| 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 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 } | 620 } |
| 621 | 621 |
| 622 HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) { | 622 HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) { |
| 623 } | 623 } |
| 624 | 624 |
| 625 HttpResponseHeaders::~HttpResponseHeaders() { | 625 HttpResponseHeaders::~HttpResponseHeaders() { |
| 626 } | 626 } |
| 627 | 627 |
| 628 // Note: this implementation implicitly assumes that line_end points at a valid | 628 // Note: this implementation implicitly assumes that line_end points at a valid |
| 629 // sentinel character (such as '\0'). | 629 // sentinel character (such as '\0'). |
| 630 // static | |
| 631 HttpVersion HttpResponseHeaders::ParseVersion( | |
| 632 std::string::const_iterator line_begin, | |
| 633 std::string::const_iterator line_end) { | |
| 634 std::string::const_iterator p = line_begin; | |
| 635 | |
| 636 // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT | |
| 637 // TODO: (1*DIGIT apparently means one or more digits, but we only handle 1). | |
| 638 // TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1. | |
| 639 | |
| 640 if ((line_end - p < 4) || !LowerCaseEqualsASCII(p, p + 4, "http")) { | |
| 641 DVLOG(1) << "missing status line"; | |
| 642 return HttpVersion(); | |
| 643 } | |
| 644 | |
| 645 p += 4; | |
| 646 | |
| 647 if (p >= line_end || *p != '/') { | |
| 648 DVLOG(1) << "missing version"; | |
| 649 return HttpVersion(); | |
| 650 } | |
| 651 | |
| 652 std::string::const_iterator dot = std::find(p, line_end, '.'); | |
| 653 if (dot == line_end) { | |
| 654 DVLOG(1) << "malformed version"; | |
| 655 return HttpVersion(); | |
| 656 } | |
| 657 | |
| 658 ++p; // from / to first digit. | |
| 659 ++dot; // from . to second digit. | |
| 660 | |
| 661 if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { | |
| 662 DVLOG(1) << "malformed version number"; | |
| 663 return HttpVersion(); | |
| 664 } | |
| 665 | |
| 666 uint16 major = *p - '0'; | |
| 667 uint16 minor = *dot - '0'; | |
| 668 | |
| 669 return HttpVersion(major, minor); | |
| 670 } | |
| 671 | |
| 672 // Note: this implementation implicitly assumes that line_end points at a valid | |
| 673 // sentinel character (such as '\0'). | |
| 674 void HttpResponseHeaders::ParseStatusLine( | 630 void HttpResponseHeaders::ParseStatusLine( |
| 675 std::string::const_iterator line_begin, | 631 std::string::const_iterator line_begin, |
| 676 std::string::const_iterator line_end, | 632 std::string::const_iterator line_end, |
| 677 bool has_headers) { | 633 bool has_headers) { |
| 678 // Extract the version number | 634 // Extract the version number |
| 679 parsed_http_version_ = ParseVersion(line_begin, line_end); | 635 std::string::const_iterator first_space = |
| 636 std::find(line_begin, line_end, ' '); |
| 637 std::string version(line_begin, first_space); |
| 638 bool success = HttpUtil::ParseVersion(version, &parsed_http_version_); |
| 680 | 639 |
| 681 // Clamp the version number to one of: {0.9, 1.0, 1.1} | 640 // Clamp the version number to one of: {0.9, 1.0, 1.1} |
| 682 if (parsed_http_version_ == HttpVersion(0, 9) && !has_headers) { | 641 if (success && parsed_http_version_ == HttpVersion(0, 9) && !has_headers) { |
| 683 http_version_ = HttpVersion(0, 9); | 642 http_version_ = HttpVersion(0, 9); |
| 684 raw_headers_ = "HTTP/0.9"; | 643 raw_headers_ = "HTTP/0.9"; |
| 685 } else if (parsed_http_version_ >= HttpVersion(1, 1)) { | 644 } else if (success && parsed_http_version_ >= HttpVersion(1, 1)) { |
| 686 http_version_ = HttpVersion(1, 1); | 645 http_version_ = HttpVersion(1, 1); |
| 687 raw_headers_ = "HTTP/1.1"; | 646 raw_headers_ = "HTTP/1.1"; |
| 688 } else { | 647 } else { |
| 689 // Treat everything else like HTTP 1.0 | 648 // Treat everything else like HTTP 1.0 |
| 690 http_version_ = HttpVersion(1, 0); | 649 http_version_ = HttpVersion(1, 0); |
| 691 raw_headers_ = "HTTP/1.0"; | 650 raw_headers_ = "HTTP/1.0"; |
| 692 } | 651 } |
| 693 if (parsed_http_version_ != http_version_) { | 652 if (parsed_http_version_ != http_version_) { |
| 694 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." | 653 DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "." |
| 695 << http_version_.minor_value(); | 654 << http_version_.minor_value(); |
| 696 } | 655 } |
| 697 | 656 |
| 698 // TODO(eroman): this doesn't make sense if ParseVersion failed. | 657 // TODO(eroman): this doesn't make sense if ParseVersion failed. |
| 699 std::string::const_iterator p = std::find(line_begin, line_end, ' '); | 658 std::string::const_iterator p = first_space; |
| 700 | 659 |
| 701 if (p == line_end) { | 660 if (p == line_end) { |
| 702 DVLOG(1) << "missing response status; assuming 200 OK"; | 661 DVLOG(1) << "missing response status; assuming 200 OK"; |
| 703 raw_headers_.append(" 200 OK"); | 662 raw_headers_.append(" 200 OK"); |
| 704 response_code_ = 200; | 663 response_code_ = 200; |
| 705 return; | 664 return; |
| 706 } | 665 } |
| 707 | 666 |
| 708 // Skip whitespace. | 667 // Skip whitespace. |
| 709 while (*p == ' ') | 668 while (*p == ' ') |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 // should not generate representation metadata other than Cache-Control, | 1456 // should not generate representation metadata other than Cache-Control, |
| 1498 // Content-Location, Date, ETag, Expires, and Vary. | 1457 // Content-Location, Date, ETag, Expires, and Vary. |
| 1499 return ProxyService::MISSING_VIA_HEADER; | 1458 return ProxyService::MISSING_VIA_HEADER; |
| 1500 } | 1459 } |
| 1501 // There is no bypass event. | 1460 // There is no bypass event. |
| 1502 return ProxyService::BYPASS_EVENT_TYPE_MAX; | 1461 return ProxyService::BYPASS_EVENT_TYPE_MAX; |
| 1503 } | 1462 } |
| 1504 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) | 1463 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) |
| 1505 | 1464 |
| 1506 } // namespace net | 1465 } // namespace net |
| OLD | NEW |