| Index: net/http/http_response_headers.cc
|
| diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc
|
| index 3a9f7e04fe0c4bad6a232ae52270e55427532d03..94c6f7eccd6e7bf05b28a1809ceba892735bb90d 100644
|
| --- a/net/http/http_response_headers.cc
|
| +++ b/net/http/http_response_headers.cc
|
| @@ -620,6 +620,37 @@ HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) {
|
| HttpResponseHeaders::~HttpResponseHeaders() {
|
| }
|
|
|
| +// Function to parse HTTP Version in accordance to
|
| +// RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
|
| +// if input string is valid, returns corresponding number in value
|
| +// else returns false
|
| +bool HttpResponseHeaders::ParseVersionInternal(
|
| + std::string::const_iterator begin,
|
| + std::string::const_iterator end,
|
| + uint32* value) {
|
| + std::string error_msg;
|
| + if(!base::StringToUint(StringPiece(begin, end), value)) {
|
| + if(*value == 0) {
|
| + if(begin == end) {
|
| + error_msg = "Empty String!!!";
|
| + } else if(!(*begin >= '0' && *begin <= '9')) {
|
| + error_msg = "Invalid char at beginning!!!";
|
| + } else {
|
| + error_msg = "Underflow!!!";
|
| + }
|
| + } else if(*value == 0xFFFFFFFF) {
|
| + error_msg = "Overflow!!!";
|
| + } else if(!(*(end-1) >= '0' && *(end-1) <= '9')) {
|
| + error_msg = "Invalid char at end!!!";
|
| + } else {
|
| + error_msg = "Invalid value!!!";
|
| + }
|
| + DVLOG(1) << error_msg;
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| // Note: this implementation implicitly assumes that line_end points at a valid
|
| // sentinel character (such as '\0').
|
| // static
|
| @@ -628,10 +659,6 @@ HttpVersion HttpResponseHeaders::ParseVersion(
|
| std::string::const_iterator line_end) {
|
| std::string::const_iterator p = line_begin;
|
|
|
| - // RFC2616 sec 3.1: HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
|
| - // TODO: (1*DIGIT apparently means one or more digits, but we only handle 1).
|
| - // TODO: handle leading zeros, which is allowed by the rfc1616 sec 3.1.
|
| -
|
| if ((line_end - p < 4) || !LowerCaseEqualsASCII(p, p + 4, "http")) {
|
| DVLOG(1) << "missing status line";
|
| return HttpVersion();
|
| @@ -645,23 +672,24 @@ HttpVersion HttpResponseHeaders::ParseVersion(
|
| }
|
|
|
| std::string::const_iterator dot = std::find(p, line_end, '.');
|
| - if (dot == line_end) {
|
| - DVLOG(1) << "malformed version";
|
| - return HttpVersion();
|
| - }
|
| -
|
| + std::string::const_iterator end_of_minor = dot+1;
|
| +
|
| + // find end of minor.
|
| + while(*end_of_minor != ' ')
|
| + end_of_minor++;
|
| +
|
| ++p; // from / to first digit.
|
| - ++dot; // from . to second digit.
|
| + uint32 major = 0;
|
| + uint32 minor = 0;
|
|
|
| - if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) {
|
| - DVLOG(1) << "malformed version number";
|
| + if (ParseVersionInternal(p, dot, &major) &&
|
| + ParseVersionInternal(dot + 1, end_of_minor, &minor)) {
|
| + DVLOG(1) << "ParseVersion success!!!";
|
| + return HttpVersion(major, minor);
|
| + } else {
|
| + DVLOG(1) << "ParseVersion fail!!!";
|
| return HttpVersion();
|
| }
|
| -
|
| - uint16 major = *p - '0';
|
| - uint16 minor = *dot - '0';
|
| -
|
| - return HttpVersion(major, minor);
|
| }
|
|
|
| // Note: this implementation implicitly assumes that line_end points at a valid
|
| @@ -673,17 +701,23 @@ void HttpResponseHeaders::ParseStatusLine(
|
| // Extract the version number
|
| parsed_http_version_ = ParseVersion(line_begin, line_end);
|
|
|
| - // Clamp the version number to one of: {0.9, 1.0, 1.1}
|
| - if (parsed_http_version_ == HttpVersion(0, 9) && !has_headers) {
|
| - http_version_ = HttpVersion(0, 9);
|
| - raw_headers_ = "HTTP/0.9";
|
| - } else if (parsed_http_version_ >= HttpVersion(1, 1)) {
|
| - http_version_ = HttpVersion(1, 1);
|
| - raw_headers_ = "HTTP/1.1";
|
| - } else {
|
| - // Treat everything else like HTTP 1.0
|
| + //Allow mulitple digits in major and minor values of HTTP Version.
|
| + //If parseVersion failed, keep version as 1.0 as per old logic
|
| + //If version is 0.9 and has headers, keep version as 1.0 as per old logic
|
| + //If version is 0.9 and has no headers, keep version as 0.9 as per old logic
|
| + //Else in all other cases, http_version will be same as parsed_http_version
|
| + if (parsed_http_version_ == HttpVersion()) {
|
| + http_version_ = HttpVersion(1, 0);
|
| + raw_headers_ = "HTTP/1.0";
|
| + } else if (parsed_http_version_ == HttpVersion(0, 9) && has_headers) {
|
| http_version_ = HttpVersion(1, 0);
|
| raw_headers_ = "HTTP/1.0";
|
| + } else {
|
| + http_version_ = parsed_http_version_;
|
| + raw_headers_ = "HTTP/";
|
| + raw_headers_.append(base::UintToString(http_version_.major_value()));
|
| + raw_headers_.append(".");
|
| + raw_headers_.append(base::UintToString(http_version_.minor_value()));
|
| }
|
| if (parsed_http_version_ != http_version_) {
|
| DVLOG(1) << "assuming HTTP/" << http_version_.major_value() << "."
|
|
|