| 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 |