| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 } | 158 } |
| 159 if ((!eq && *had_charset) || type_has_charset) { | 159 if ((!eq && *had_charset) || type_has_charset) { |
| 160 *had_charset = true; | 160 *had_charset = true; |
| 161 *charset = base::ToLowerASCII( | 161 *charset = base::ToLowerASCII( |
| 162 base::StringPiece(begin + charset_val, begin + charset_end)); | 162 base::StringPiece(begin + charset_val, begin + charset_end)); |
| 163 } | 163 } |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 // static | 167 // static |
| 168 // Parse the Range header according to RFC 2616 14.35.1 | |
| 169 // ranges-specifier = byte-ranges-specifier | |
| 170 // byte-ranges-specifier = bytes-unit "=" byte-range-set | |
| 171 // byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec ) | |
| 172 // byte-range-spec = first-byte-pos "-" [last-byte-pos] | |
| 173 // first-byte-pos = 1*DIGIT | |
| 174 // last-byte-pos = 1*DIGIT | |
| 175 bool HttpUtil::ParseRanges(const std::string& headers, | |
| 176 std::vector<HttpByteRange>* ranges) { | |
| 177 std::string ranges_specifier; | |
| 178 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); | |
| 179 | |
| 180 while (it.GetNext()) { | |
| 181 // Look for "Range" header. | |
| 182 if (!base::LowerCaseEqualsASCII(it.name(), "range")) | |
| 183 continue; | |
| 184 ranges_specifier = it.values(); | |
| 185 // We just care about the first "Range" header, so break here. | |
| 186 break; | |
| 187 } | |
| 188 | |
| 189 if (ranges_specifier.empty()) | |
| 190 return false; | |
| 191 | |
| 192 return ParseRangeHeader(ranges_specifier, ranges); | |
| 193 } | |
| 194 | |
| 195 // static | |
| 196 bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier, | 168 bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier, |
| 197 std::vector<HttpByteRange>* ranges) { | 169 std::vector<HttpByteRange>* ranges) { |
| 198 size_t equal_char_offset = ranges_specifier.find('='); | 170 size_t equal_char_offset = ranges_specifier.find('='); |
| 199 if (equal_char_offset == std::string::npos) | 171 if (equal_char_offset == std::string::npos) |
| 200 return false; | 172 return false; |
| 201 | 173 |
| 202 // Try to extract bytes-unit part. | 174 // Try to extract bytes-unit part. |
| 203 std::string::const_iterator bytes_unit_begin = ranges_specifier.begin(); | 175 std::string::const_iterator bytes_unit_begin = ranges_specifier.begin(); |
| 204 std::string::const_iterator bytes_unit_end = bytes_unit_begin + | 176 std::string::const_iterator bytes_unit_end = bytes_unit_begin + |
| 205 equal_char_offset; | 177 equal_char_offset; |
| 206 std::string::const_iterator byte_range_set_begin = bytes_unit_end + 1; | 178 std::string::const_iterator byte_range_set_begin = bytes_unit_end + 1; |
| 207 std::string::const_iterator byte_range_set_end = ranges_specifier.end(); | 179 std::string::const_iterator byte_range_set_end = ranges_specifier.end(); |
| 208 | 180 |
| 209 TrimLWS(&bytes_unit_begin, &bytes_unit_end); | 181 TrimLWS(&bytes_unit_begin, &bytes_unit_end); |
| 210 // "bytes" unit identifier is not found. | 182 // "bytes" unit identifier is not found. |
| 211 if (!base::LowerCaseEqualsASCII( | 183 if (!base::LowerCaseEqualsASCII( |
| 212 base::StringPiece(bytes_unit_begin, bytes_unit_end), "bytes")) | 184 base::StringPiece(bytes_unit_begin, bytes_unit_end), "bytes")) { |
| 213 return false; | 185 return false; |
| 186 } |
| 214 | 187 |
| 215 ValuesIterator byte_range_set_iterator(byte_range_set_begin, | 188 ValuesIterator byte_range_set_iterator(byte_range_set_begin, |
| 216 byte_range_set_end, ','); | 189 byte_range_set_end, ','); |
| 217 while (byte_range_set_iterator.GetNext()) { | 190 while (byte_range_set_iterator.GetNext()) { |
| 218 size_t minus_char_offset = byte_range_set_iterator.value().find('-'); | 191 size_t minus_char_offset = byte_range_set_iterator.value().find('-'); |
| 219 // If '-' character is not found, reports failure. | 192 // If '-' character is not found, reports failure. |
| 220 if (minus_char_offset == std::string::npos) | 193 if (minus_char_offset == std::string::npos) |
| 221 return false; | 194 return false; |
| 222 | 195 |
| 223 std::string::const_iterator first_byte_pos_begin = | 196 std::string::const_iterator first_byte_pos_begin = |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 bool HttpUtil::IsValidHeaderValue(const base::StringPiece& value) { | 409 bool HttpUtil::IsValidHeaderValue(const base::StringPiece& value) { |
| 437 // Just a sanity check: disallow NUL, CR and LF. | 410 // Just a sanity check: disallow NUL, CR and LF. |
| 438 for (char c : value) { | 411 for (char c : value) { |
| 439 if (c == '\0' || c == '\r' || c == '\n') | 412 if (c == '\0' || c == '\r' || c == '\n') |
| 440 return false; | 413 return false; |
| 441 } | 414 } |
| 442 return true; | 415 return true; |
| 443 } | 416 } |
| 444 | 417 |
| 445 // static | 418 // static |
| 446 std::string HttpUtil::StripHeaders(const std::string& headers, | |
| 447 const char* const headers_to_remove[], | |
| 448 size_t headers_to_remove_len) { | |
| 449 std::string stripped_headers; | |
| 450 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); | |
| 451 | |
| 452 while (it.GetNext()) { | |
| 453 bool should_remove = false; | |
| 454 for (size_t i = 0; i < headers_to_remove_len; ++i) { | |
| 455 if (base::LowerCaseEqualsASCII( | |
| 456 base::StringPiece(it.name_begin(), it.name_end()), | |
| 457 headers_to_remove[i])) { | |
| 458 should_remove = true; | |
| 459 break; | |
| 460 } | |
| 461 } | |
| 462 if (!should_remove) { | |
| 463 // Assume that name and values are on the same line. | |
| 464 stripped_headers.append(it.name_begin(), it.values_end()); | |
| 465 stripped_headers.append("\r\n"); | |
| 466 } | |
| 467 } | |
| 468 return stripped_headers; | |
| 469 } | |
| 470 | |
| 471 // static | |
| 472 bool HttpUtil::IsNonCoalescingHeader(std::string::const_iterator name_begin, | 419 bool HttpUtil::IsNonCoalescingHeader(std::string::const_iterator name_begin, |
| 473 std::string::const_iterator name_end) { | 420 std::string::const_iterator name_end) { |
| 474 // NOTE: "set-cookie2" headers do not support expires attributes, so we don't | 421 // NOTE: "set-cookie2" headers do not support expires attributes, so we don't |
| 475 // have to list them here. | 422 // have to list them here. |
| 476 const char* const kNonCoalescingHeaders[] = { | 423 const char* const kNonCoalescingHeaders[] = { |
| 477 "date", | 424 "date", |
| 478 "expires", | 425 "expires", |
| 479 "last-modified", | 426 "last-modified", |
| 480 "location", // See bug 1050541 for details | 427 "location", // See bug 1050541 for details |
| 481 "retry-after", | 428 "retry-after", |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 return true; | 1094 return true; |
| 1148 } | 1095 } |
| 1149 | 1096 |
| 1150 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { | 1097 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { |
| 1151 if (strict_quotes_) | 1098 if (strict_quotes_) |
| 1152 return c == '"'; | 1099 return c == '"'; |
| 1153 return HttpUtil::IsQuote(c); | 1100 return HttpUtil::IsQuote(c); |
| 1154 } | 1101 } |
| 1155 | 1102 |
| 1156 } // namespace net | 1103 } // namespace net |
| OLD | NEW |