OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 2 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 3 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 4 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
5 * Copyright (C) 2009 Google Inc. All rights reserved. | 5 * Copyright (C) 2009 Google Inc. All rights reserved. |
6 * | 6 * |
7 * Redistribution and use in source and binary forms, with or without | 7 * Redistribution and use in source and binary forms, with or without |
8 * modification, are permitted provided that the following conditions | 8 * modification, are permitted provided that the following conditions |
9 * are met: | 9 * are met: |
10 * | 10 * |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 | 66 |
67 while (pos != len && *token) { | 67 while (pos != len && *token) { |
68 if (toASCIILower(str[pos]) != *token++) | 68 if (toASCIILower(str[pos]) != *token++) |
69 return false; | 69 return false; |
70 ++pos; | 70 ++pos; |
71 } | 71 } |
72 | 72 |
73 return true; | 73 return true; |
74 } | 74 } |
75 | 75 |
| 76 // See RFC 2616, Section 2.2. |
| 77 bool isRFC2616Token(const String& characters) |
| 78 { |
| 79 if (characters.isEmpty()) |
| 80 return false; |
| 81 for (unsigned i = 0; i < characters.length(); ++i) { |
| 82 UChar c = characters[i]; |
| 83 if (c >= 0x80 || c <= 0x1F || c == 0x7F |
| 84 || c == '(' || c == ')' || c == '<' || c == '>' || c == '@' |
| 85 || c == ',' || c == ';' || c == ':' || c == '\\' || c == '"' |
| 86 || c == '/' || c == '[' || c == ']' || c == '?' || c == '=' |
| 87 || c == '{' || c == '}' || c == ' ' || c == '\t') |
| 88 return false; |
| 89 } |
| 90 return true; |
| 91 } |
| 92 |
76 ContentDispositionType contentDispositionType(const String& contentDisposition) | 93 ContentDispositionType contentDispositionType(const String& contentDisposition) |
77 { | 94 { |
78 if (contentDisposition.isEmpty()) | 95 if (contentDisposition.isEmpty()) |
79 return ContentDispositionNone; | 96 return ContentDispositionNone; |
80 | 97 |
81 // Some broken sites just send | 98 Vector<String> parameters; |
82 // Content-Disposition: ; filename="file" | 99 contentDisposition.split(';', parameters); |
83 // screen those out here. | |
84 if (contentDisposition.startsWith(";")) | |
85 return ContentDispositionNone; | |
86 | 100 |
87 if (contentDisposition.startsWith("inline", false)) | 101 String dispositionType = parameters[0]; |
| 102 dispositionType.stripWhiteSpace(); |
| 103 |
| 104 if (equalIgnoringCase(dispositionType, "inline")) |
88 return ContentDispositionInline; | 105 return ContentDispositionInline; |
89 | 106 |
90 // Some broken sites just send | 107 // Some broken sites just send bogus headers like |
91 // Content-Disposition: filename="file" | 108 // |
| 109 // Content-Disposition: ; filename="file" |
| 110 // Content-Disposition: filename="file" |
| 111 // Content-Disposition: name="file" |
| 112 // |
92 // without a disposition token... screen those out. | 113 // without a disposition token... screen those out. |
93 if (contentDisposition.startsWith("filename", false)) | 114 if (!isRFC2616Token(dispositionType)) |
94 return ContentDispositionNone; | |
95 | |
96 // Also in use is Content-Disposition: name="file" | |
97 if (contentDisposition.startsWith("name", false)) | |
98 return ContentDispositionNone; | 115 return ContentDispositionNone; |
99 | 116 |
100 // We have a content-disposition of "attachment" or unknown. | 117 // We have a content-disposition of "attachment" or unknown. |
101 // RFC 2183, section 2.8 says that an unknown disposition | 118 // RFC 2183, section 2.8 says that an unknown disposition |
102 // value should be treated as "attachment" | 119 // value should be treated as "attachment" |
103 return ContentDispositionAttachment; | 120 return ContentDispositionAttachment; |
104 } | 121 } |
105 | 122 |
106 bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del
ay, String& url) | 123 bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del
ay, String& url) |
107 { | 124 { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhite
Space(); | 177 url = refresh.substring(urlStartPos, urlEndPos - urlStartPos).stripWhite
Space(); |
161 return true; | 178 return true; |
162 } | 179 } |
163 } | 180 } |
164 | 181 |
165 double parseDate(const String& value) | 182 double parseDate(const String& value) |
166 { | 183 { |
167 return parseDateFromNullTerminatedCharacters(value.utf8().data()); | 184 return parseDateFromNullTerminatedCharacters(value.utf8().data()); |
168 } | 185 } |
169 | 186 |
| 187 // FIXME: This function doesn't comply with RFC 6266. |
| 188 // For example, this function doesn't handle the interaction between " and ; |
| 189 // that arises from quoted-string, nor does this function properly unquote |
| 190 // attribute values. Further this function appears to process parameter names |
| 191 // in a case-sensitive manner. (There are likely other bugs as well.) |
170 String filenameFromHTTPContentDisposition(const String& value) | 192 String filenameFromHTTPContentDisposition(const String& value) |
171 { | 193 { |
172 Vector<String> keyValuePairs; | 194 Vector<String> keyValuePairs; |
173 value.split(';', keyValuePairs); | 195 value.split(';', keyValuePairs); |
174 | 196 |
175 unsigned length = keyValuePairs.size(); | 197 unsigned length = keyValuePairs.size(); |
176 for (unsigned i = 0; i < length; i++) { | 198 for (unsigned i = 0; i < length; i++) { |
177 size_t valueStartPos = keyValuePairs[i].find('='); | 199 size_t valueStartPos = keyValuePairs[i].find('='); |
178 if (valueStartPos == notFound) | 200 if (valueStartPos == notFound) |
179 continue; | 201 continue; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 389 |
368 if (firstBytePos < 0 || !(lastBytePos == -1 || lastBytePos >= firstBytePos)) | 390 if (firstBytePos < 0 || !(lastBytePos == -1 || lastBytePos >= firstBytePos)) |
369 return false; | 391 return false; |
370 | 392 |
371 rangeOffset = firstBytePos; | 393 rangeOffset = firstBytePos; |
372 rangeEnd = lastBytePos; | 394 rangeEnd = lastBytePos; |
373 return true; | 395 return true; |
374 } | 396 } |
375 | 397 |
376 } | 398 } |
OLD | NEW |