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 header parsing were borrowed from Firefox: | 5 // The rules for header parsing were borrowed from Firefox: |
6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo
nseHead.cpp | 6 // http://lxr.mozilla.org/seamonkey/source/netwerk/protocol/http/src/nsHttpRespo
nseHead.cpp |
7 // The rules for parsing content-types were also borrowed from Firefox: | 7 // The rules for parsing content-types were also borrowed from Firefox: |
8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 | 8 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 |
9 | 9 |
10 #include "net/http/http_response_headers.h" | 10 #include "net/http/http_response_headers.h" |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 void HttpResponseHeaders::ReplaceStatusLine(const std::string& new_status) { | 354 void HttpResponseHeaders::ReplaceStatusLine(const std::string& new_status) { |
355 CheckDoesNotHaveEmbededNulls(new_status); | 355 CheckDoesNotHaveEmbededNulls(new_status); |
356 // Copy up to the null byte. This just copies the status line. | 356 // Copy up to the null byte. This just copies the status line. |
357 std::string new_raw_headers(new_status); | 357 std::string new_raw_headers(new_status); |
358 new_raw_headers.push_back('\0'); | 358 new_raw_headers.push_back('\0'); |
359 | 359 |
360 HeaderSet empty_to_remove; | 360 HeaderSet empty_to_remove; |
361 MergeWithHeaders(new_raw_headers, empty_to_remove); | 361 MergeWithHeaders(new_raw_headers, empty_to_remove); |
362 } | 362 } |
363 | 363 |
364 void HttpResponseHeaders::UpdateWithNewRange( | 364 void HttpResponseHeaders::UpdateWithNewRange(const HttpByteRange& byte_range, |
365 const HttpByteRange& byte_range, | 365 int64_t resource_size, |
366 int64 resource_size, | 366 bool replace_status_line) { |
367 bool replace_status_line) { | |
368 DCHECK(byte_range.IsValid()); | 367 DCHECK(byte_range.IsValid()); |
369 DCHECK(byte_range.HasFirstBytePosition()); | 368 DCHECK(byte_range.HasFirstBytePosition()); |
370 DCHECK(byte_range.HasLastBytePosition()); | 369 DCHECK(byte_range.HasLastBytePosition()); |
371 | 370 |
372 const char kLengthHeader[] = "Content-Length"; | 371 const char kLengthHeader[] = "Content-Length"; |
373 const char kRangeHeader[] = "Content-Range"; | 372 const char kRangeHeader[] = "Content-Range"; |
374 | 373 |
375 RemoveHeader(kLengthHeader); | 374 RemoveHeader(kLengthHeader); |
376 RemoveHeader(kRangeHeader); | 375 RemoveHeader(kRangeHeader); |
377 | 376 |
378 int64 start = byte_range.first_byte_position(); | 377 int64_t start = byte_range.first_byte_position(); |
379 int64 end = byte_range.last_byte_position(); | 378 int64_t end = byte_range.last_byte_position(); |
380 int64 range_len = end - start + 1; | 379 int64_t range_len = end - start + 1; |
381 | 380 |
382 if (replace_status_line) | 381 if (replace_status_line) |
383 ReplaceStatusLine("HTTP/1.1 206 Partial Content"); | 382 ReplaceStatusLine("HTTP/1.1 206 Partial Content"); |
384 | 383 |
385 AddHeader(base::StringPrintf("%s: bytes %" PRId64 "-%" PRId64 "/%" PRId64, | 384 AddHeader(base::StringPrintf("%s: bytes %" PRId64 "-%" PRId64 "/%" PRId64, |
386 kRangeHeader, start, end, resource_size)); | 385 kRangeHeader, start, end, resource_size)); |
387 AddHeader(base::StringPrintf("%s: %" PRId64, kLengthHeader, range_len)); | 386 AddHeader(base::StringPrintf("%s: %" PRId64, kLengthHeader, range_len)); |
388 } | 387 } |
389 | 388 |
390 void HttpResponseHeaders::Parse(const std::string& raw_input) { | 389 void HttpResponseHeaders::Parse(const std::string& raw_input) { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 } | 651 } |
653 | 652 |
654 ++p; // from / to first digit. | 653 ++p; // from / to first digit. |
655 ++dot; // from . to second digit. | 654 ++dot; // from . to second digit. |
656 | 655 |
657 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { | 656 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { |
658 DVLOG(1) << "malformed version number"; | 657 DVLOG(1) << "malformed version number"; |
659 return HttpVersion(); | 658 return HttpVersion(); |
660 } | 659 } |
661 | 660 |
662 uint16 major = *p - '0'; | 661 uint16_t major = *p - '0'; |
663 uint16 minor = *dot - '0'; | 662 uint16_t minor = *dot - '0'; |
664 | 663 |
665 return HttpVersion(major, minor); | 664 return HttpVersion(major, minor); |
666 } | 665 } |
667 | 666 |
668 // Note: this implementation implicitly assumes that line_end points at a valid | 667 // Note: this implementation implicitly assumes that line_end points at a valid |
669 // sentinel character (such as '\0'). | 668 // sentinel character (such as '\0'). |
670 void HttpResponseHeaders::ParseStatusLine( | 669 void HttpResponseHeaders::ParseStatusLine( |
671 std::string::const_iterator line_begin, | 670 std::string::const_iterator line_begin, |
672 std::string::const_iterator line_end, | 671 std::string::const_iterator line_end, |
673 bool has_headers) { | 672 bool has_headers) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 std::string value; | 755 std::string value; |
757 | 756 |
758 size_t directive_size = directive.size(); | 757 size_t directive_size = directive.size(); |
759 | 758 |
760 void* iter = NULL; | 759 void* iter = NULL; |
761 while (EnumerateHeader(&iter, name, &value)) { | 760 while (EnumerateHeader(&iter, name, &value)) { |
762 if (value.size() > directive_size + 1 && | 761 if (value.size() > directive_size + 1 && |
763 base::StartsWith(value, directive, | 762 base::StartsWith(value, directive, |
764 base::CompareCase::INSENSITIVE_ASCII) && | 763 base::CompareCase::INSENSITIVE_ASCII) && |
765 value[directive_size] == '=') { | 764 value[directive_size] == '=') { |
766 int64 seconds; | 765 int64_t seconds; |
767 base::StringToInt64( | 766 base::StringToInt64( |
768 StringPiece(value.begin() + directive_size + 1, value.end()), | 767 StringPiece(value.begin() + directive_size + 1, value.end()), |
769 &seconds); | 768 &seconds); |
770 *result = TimeDelta::FromSeconds(seconds); | 769 *result = TimeDelta::FromSeconds(seconds); |
771 return true; | 770 return true; |
772 } | 771 } |
773 } | 772 } |
774 | 773 |
775 return false; | 774 return false; |
776 } | 775 } |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 | 1147 |
1149 bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const { | 1148 bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const { |
1150 return GetCacheControlDirective("max-age", result); | 1149 return GetCacheControlDirective("max-age", result); |
1151 } | 1150 } |
1152 | 1151 |
1153 bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const { | 1152 bool HttpResponseHeaders::GetAgeValue(TimeDelta* result) const { |
1154 std::string value; | 1153 std::string value; |
1155 if (!EnumerateHeader(NULL, "Age", &value)) | 1154 if (!EnumerateHeader(NULL, "Age", &value)) |
1156 return false; | 1155 return false; |
1157 | 1156 |
1158 int64 seconds; | 1157 int64_t seconds; |
1159 base::StringToInt64(value, &seconds); | 1158 base::StringToInt64(value, &seconds); |
1160 *result = TimeDelta::FromSeconds(seconds); | 1159 *result = TimeDelta::FromSeconds(seconds); |
1161 return true; | 1160 return true; |
1162 } | 1161 } |
1163 | 1162 |
1164 bool HttpResponseHeaders::GetDateValue(Time* result) const { | 1163 bool HttpResponseHeaders::GetDateValue(Time* result) const { |
1165 return GetTimeValuedHeader("Date", result); | 1164 return GetTimeValuedHeader("Date", result); |
1166 } | 1165 } |
1167 | 1166 |
1168 bool HttpResponseHeaders::GetLastModifiedValue(Time* result) const { | 1167 bool HttpResponseHeaders::GetLastModifiedValue(Time* result) const { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 std::string date_header; | 1242 std::string date_header; |
1244 EnumerateHeader(NULL, "Date", &date_header); | 1243 EnumerateHeader(NULL, "Date", &date_header); |
1245 return HttpUtil::HasStrongValidators(GetHttpVersion(), | 1244 return HttpUtil::HasStrongValidators(GetHttpVersion(), |
1246 etag_header, | 1245 etag_header, |
1247 last_modified_header, | 1246 last_modified_header, |
1248 date_header); | 1247 date_header); |
1249 } | 1248 } |
1250 | 1249 |
1251 // From RFC 2616: | 1250 // From RFC 2616: |
1252 // Content-Length = "Content-Length" ":" 1*DIGIT | 1251 // Content-Length = "Content-Length" ":" 1*DIGIT |
1253 int64 HttpResponseHeaders::GetContentLength() const { | 1252 int64_t HttpResponseHeaders::GetContentLength() const { |
1254 return GetInt64HeaderValue("content-length"); | 1253 return GetInt64HeaderValue("content-length"); |
1255 } | 1254 } |
1256 | 1255 |
1257 int64 HttpResponseHeaders::GetInt64HeaderValue( | 1256 int64_t HttpResponseHeaders::GetInt64HeaderValue( |
1258 const std::string& header) const { | 1257 const std::string& header) const { |
1259 void* iter = NULL; | 1258 void* iter = NULL; |
1260 std::string content_length_val; | 1259 std::string content_length_val; |
1261 if (!EnumerateHeader(&iter, header, &content_length_val)) | 1260 if (!EnumerateHeader(&iter, header, &content_length_val)) |
1262 return -1; | 1261 return -1; |
1263 | 1262 |
1264 if (content_length_val.empty()) | 1263 if (content_length_val.empty()) |
1265 return -1; | 1264 return -1; |
1266 | 1265 |
1267 if (content_length_val[0] == '+') | 1266 if (content_length_val[0] == '+') |
1268 return -1; | 1267 return -1; |
1269 | 1268 |
1270 int64 result; | 1269 int64_t result; |
1271 bool ok = base::StringToInt64(content_length_val, &result); | 1270 bool ok = base::StringToInt64(content_length_val, &result); |
1272 if (!ok || result < 0) | 1271 if (!ok || result < 0) |
1273 return -1; | 1272 return -1; |
1274 | 1273 |
1275 return result; | 1274 return result; |
1276 } | 1275 } |
1277 | 1276 |
1278 // From RFC 2616 14.16: | 1277 // From RFC 2616 14.16: |
1279 // content-range-spec = | 1278 // content-range-spec = |
1280 // bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) | 1279 // bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) |
1281 // byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" | 1280 // byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" |
1282 // instance-length = 1*DIGIT | 1281 // instance-length = 1*DIGIT |
1283 // bytes-unit = "bytes" | 1282 // bytes-unit = "bytes" |
1284 bool HttpResponseHeaders::GetContentRange(int64* first_byte_position, | 1283 bool HttpResponseHeaders::GetContentRange(int64_t* first_byte_position, |
1285 int64* last_byte_position, | 1284 int64_t* last_byte_position, |
1286 int64* instance_length) const { | 1285 int64_t* instance_length) const { |
1287 void* iter = NULL; | 1286 void* iter = NULL; |
1288 std::string content_range_spec; | 1287 std::string content_range_spec; |
1289 *first_byte_position = *last_byte_position = *instance_length = -1; | 1288 *first_byte_position = *last_byte_position = *instance_length = -1; |
1290 if (!EnumerateHeader(&iter, kContentRange, &content_range_spec)) | 1289 if (!EnumerateHeader(&iter, kContentRange, &content_range_spec)) |
1291 return false; | 1290 return false; |
1292 | 1291 |
1293 // If the header value is empty, we have an invalid header. | 1292 // If the header value is empty, we have an invalid header. |
1294 if (content_range_spec.empty()) | 1293 if (content_range_spec.empty()) |
1295 return false; | 1294 return false; |
1296 | 1295 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 return true; | 1441 return true; |
1443 } | 1442 } |
1444 | 1443 |
1445 bool HttpResponseHeaders::IsChunkEncoded() const { | 1444 bool HttpResponseHeaders::IsChunkEncoded() const { |
1446 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. | 1445 // Ignore spurious chunked responses from HTTP/1.0 servers and proxies. |
1447 return GetHttpVersion() >= HttpVersion(1, 1) && | 1446 return GetHttpVersion() >= HttpVersion(1, 1) && |
1448 HasHeaderValue("Transfer-Encoding", "chunked"); | 1447 HasHeaderValue("Transfer-Encoding", "chunked"); |
1449 } | 1448 } |
1450 | 1449 |
1451 } // namespace net | 1450 } // namespace net |
OLD | NEW |