Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // The rules for parsing content-types were borrowed from Firefox: | 5 // The rules for parsing content-types were borrowed from Firefox: |
| 6 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 | 6 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 |
| 7 | 7 |
| 8 #include "net/http/http_util.h" | 8 #include "net/http/http_util.h" |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 // string, so just go back to the top of the loop and look for | 83 // string, so just go back to the top of the loop and look for |
| 84 // |delimiter| again. | 84 // |delimiter| again. |
| 85 } while (true); | 85 } while (true); |
| 86 | 86 |
| 87 NOTREACHED(); | 87 NOTREACHED(); |
| 88 return line.length(); | 88 return line.length(); |
| 89 } | 89 } |
| 90 | 90 |
| 91 // static | 91 // static |
| 92 void HttpUtil::ParseContentType(const string& content_type_str, | 92 void HttpUtil::ParseContentType(const string& content_type_str, |
| 93 string* mime_type, string* charset, | 93 string* mime_type, |
| 94 bool *had_charset) { | 94 string* charset, |
| 95 bool *had_charset, | |
| 96 string* boundary) { | |
| 97 const string::const_iterator begin = content_type_str.begin(); | |
| 98 | |
| 95 // Trim leading and trailing whitespace from type. We include '(' in | 99 // Trim leading and trailing whitespace from type. We include '(' in |
| 96 // the trailing trim set to catch media-type comments, which are not at all | 100 // the trailing trim set to catch media-type comments, which are not at all |
| 97 // standard, but may occur in rare cases. | 101 // standard, but may occur in rare cases. |
| 98 size_t type_val = content_type_str.find_first_not_of(HTTP_LWS); | 102 size_t type_val = content_type_str.find_first_not_of(HTTP_LWS); |
| 99 type_val = std::min(type_val, content_type_str.length()); | 103 type_val = std::min(type_val, content_type_str.length()); |
| 100 size_t type_end = content_type_str.find_first_of(HTTP_LWS ";(", type_val); | 104 size_t type_end = content_type_str.find_first_of(HTTP_LWS ";(", type_val); |
| 101 if (string::npos == type_end) | 105 if (string::npos == type_end) |
| 102 type_end = content_type_str.length(); | 106 type_end = content_type_str.length(); |
| 103 | 107 |
| 104 size_t charset_val = 0; | 108 size_t charset_val = 0; |
| 105 size_t charset_end = 0; | 109 size_t charset_end = 0; |
| 106 | 110 |
| 107 // Iterate over parameters | 111 // Iterate over parameters |
| 108 bool type_has_charset = false; | 112 bool type_has_charset = false; |
| 109 size_t param_start = content_type_str.find_first_of(';', type_end); | 113 size_t param_start = content_type_str.find_first_of(';', type_end); |
| 110 if (param_start != string::npos) { | 114 if (param_start != string::npos) { |
| 111 // We have parameters. Iterate over them. | 115 // We have parameters. Iterate over them. |
| 112 size_t cur_param_start = param_start + 1; | 116 size_t cur_param_start = param_start + 1; |
| 113 do { | 117 do { |
| 114 size_t cur_param_end = | 118 size_t cur_param_end = |
| 115 FindDelimiter(content_type_str, cur_param_start, ';'); | 119 FindDelimiter(content_type_str, cur_param_start, ';'); |
| 116 | 120 |
| 117 size_t param_name_start = content_type_str.find_first_not_of( | 121 size_t param_name_start = content_type_str.find_first_not_of( |
| 118 HTTP_LWS, cur_param_start); | 122 HTTP_LWS, cur_param_start); |
| 119 param_name_start = std::min(param_name_start, cur_param_end); | 123 param_name_start = std::min(param_name_start, cur_param_end); |
| 120 | 124 |
| 121 static const char charset_str[] = "charset="; | 125 static const char charset_str[] = "charset="; |
| 122 size_t charset_end_offset = std::min( | 126 size_t charset_end_offset = std::min( |
| 123 param_name_start + sizeof(charset_str) - 1, cur_param_end); | 127 param_name_start + sizeof(charset_str) - 1, cur_param_end); |
| 124 if (LowerCaseEqualsASCII( | 128 if (LowerCaseEqualsASCII(begin + param_name_start, |
| 125 content_type_str.begin() + param_name_start, | 129 begin + charset_end_offset, |
| 126 content_type_str.begin() + charset_end_offset, charset_str)) { | 130 charset_str)) { |
| 127 charset_val = param_name_start + sizeof(charset_str) - 1; | 131 charset_val = param_name_start + sizeof(charset_str) - 1; |
| 128 charset_end = cur_param_end; | 132 charset_end = cur_param_end; |
| 129 type_has_charset = true; | 133 type_has_charset = true; |
| 130 } | 134 } |
| 131 | 135 |
| 136 static const char boundary_str[] = "boundary="; | |
|
asanka
2012/01/27 16:18:59
Isn't *LWSP-char allowed around "="?
GetHeaderPar
| |
| 137 static const size_t boundary_len = sizeof(boundary_str) - 1; | |
| 138 size_t boundary_end_offset = std::min( | |
| 139 param_name_start + boundary_len, cur_param_end); | |
| 140 if (boundary && LowerCaseEqualsASCII(begin + param_name_start, | |
| 141 begin + boundary_end_offset, | |
| 142 boundary_str)) { | |
| 143 string::const_iterator boundary_begin = | |
| 144 begin + param_name_start + boundary_len; | |
| 145 string::const_iterator boundary_end = begin + cur_param_end; | |
| 146 TrimLWS(&boundary_begin, &boundary_end); | |
| 147 boundary->assign(boundary_begin, boundary_end); | |
| 148 } | |
| 149 | |
| 132 cur_param_start = cur_param_end + 1; | 150 cur_param_start = cur_param_end + 1; |
| 133 } while (cur_param_start < content_type_str.length()); | 151 } while (cur_param_start < content_type_str.length()); |
| 134 } | 152 } |
| 135 | 153 |
| 136 if (type_has_charset) { | 154 if (type_has_charset) { |
| 137 // Trim leading and trailing whitespace from charset_val. We include | 155 // Trim leading and trailing whitespace from charset_val. We include |
| 138 // '(' in the trailing trim set to catch media-type comments, which are | 156 // '(' in the trailing trim set to catch media-type comments, which are |
| 139 // not at all standard, but may occur in rare cases. | 157 // not at all standard, but may occur in rare cases. |
| 140 charset_val = content_type_str.find_first_not_of(HTTP_LWS, charset_val); | 158 charset_val = content_type_str.find_first_not_of(HTTP_LWS, charset_val); |
| 141 charset_val = std::min(charset_val, charset_end); | 159 charset_val = std::min(charset_val, charset_end); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 155 // also, if type_val is the same as mime_type, then just update the | 173 // also, if type_val is the same as mime_type, then just update the |
| 156 // charset. however, if charset is empty and mime_type hasn't | 174 // charset. however, if charset is empty and mime_type hasn't |
| 157 // changed, then don't wipe-out an existing charset. We | 175 // changed, then don't wipe-out an existing charset. We |
| 158 // also want to reject a mime-type if it does not include a slash. | 176 // also want to reject a mime-type if it does not include a slash. |
| 159 // some servers give junk after the charset parameter, which may | 177 // some servers give junk after the charset parameter, which may |
| 160 // include a comma, so this check makes us a bit more tolerant. | 178 // include a comma, so this check makes us a bit more tolerant. |
| 161 if (content_type_str.length() != 0 && | 179 if (content_type_str.length() != 0 && |
| 162 content_type_str != "*/*" && | 180 content_type_str != "*/*" && |
| 163 content_type_str.find_first_of('/') != string::npos) { | 181 content_type_str.find_first_of('/') != string::npos) { |
| 164 // Common case here is that mime_type is empty | 182 // Common case here is that mime_type is empty |
| 165 bool eq = !mime_type->empty() && | 183 bool eq = !mime_type->empty() && LowerCaseEqualsASCII(begin + type_val, |
| 166 LowerCaseEqualsASCII(content_type_str.begin() + type_val, | 184 begin + type_end, |
| 167 content_type_str.begin() + type_end, | 185 mime_type->data()); |
| 168 mime_type->data()); | |
| 169 if (!eq) { | 186 if (!eq) { |
| 170 mime_type->assign(content_type_str.begin() + type_val, | 187 mime_type->assign(begin + type_val, begin + type_end); |
| 171 content_type_str.begin() + type_end); | |
| 172 StringToLowerASCII(mime_type); | 188 StringToLowerASCII(mime_type); |
| 173 } | 189 } |
| 174 if ((!eq && *had_charset) || type_has_charset) { | 190 if ((!eq && *had_charset) || type_has_charset) { |
| 175 *had_charset = true; | 191 *had_charset = true; |
| 176 charset->assign(content_type_str.begin() + charset_val, | 192 charset->assign(begin + charset_val, begin + charset_end); |
| 177 content_type_str.begin() + charset_end); | |
| 178 StringToLowerASCII(charset); | 193 StringToLowerASCII(charset); |
| 179 } | 194 } |
| 180 } | 195 } |
| 181 } | 196 } |
| 182 | 197 |
| 183 // static | 198 // static |
| 184 // Parse the Range header according to RFC 2616 14.35.1 | 199 // Parse the Range header according to RFC 2616 14.35.1 |
| 185 // ranges-specifier = byte-ranges-specifier | 200 // ranges-specifier = byte-ranges-specifier |
| 186 // byte-ranges-specifier = bytes-unit "=" byte-range-set | 201 // byte-ranges-specifier = bytes-unit "=" byte-range-set |
| 187 // byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec ) | 202 // byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec ) |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 834 value_is_quoted_ = true; | 849 value_is_quoted_ = true; |
| 835 // Do not store iterators into this. See declaration of unquoted_value_. | 850 // Do not store iterators into this. See declaration of unquoted_value_. |
| 836 unquoted_value_ = HttpUtil::Unquote(value_begin_, value_end_); | 851 unquoted_value_ = HttpUtil::Unquote(value_begin_, value_end_); |
| 837 } | 852 } |
| 838 } | 853 } |
| 839 | 854 |
| 840 return true; | 855 return true; |
| 841 } | 856 } |
| 842 | 857 |
| 843 } // namespace net | 858 } // namespace net |
| OLD | NEW |