Chromium Code Reviews| 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..551457a2ce3580061fde26bf3c635f59b354836a 100644 |
| --- a/net/http/http_response_headers.cc |
| +++ b/net/http/http_response_headers.cc |
| @@ -620,6 +620,36 @@ HttpResponseHeaders::HttpResponseHeaders() : response_code_(-1) { |
| HttpResponseHeaders::~HttpResponseHeaders() { |
| } |
| +// Shared function for major and minor section of HTTP Version string |
|
eroman
2014/09/23 21:12:28
This wording needs work.
arun87.kumar
2014/09/24 12:04:05
Done.
|
| +// to handle leading zeros and multiple digit usecases |
| +// if string is valid, converts it to number, |
| +// fills it to int variable passed as input param and returns true |
| +// else returns false |
| +bool HttpResponseHeaders::ParseVersionInternal( |
| + std::string::const_iterator begin, |
| + std::string::const_iterator end, |
| + uint32* value) { |
| + std::string::const_iterator start, p; |
| + start = p = begin; |
| + bool is_leading_zero = true; // handle leading zeroes |
|
eroman
2014/09/23 21:12:28
Is there really a need to check for leading zeros?
arun87.kumar
2014/09/24 12:04:05
Done.
|
| + |
| + while (p < end) { |
| + if (!(*p >= '0' && *p <= '9')) { |
| + DVLOG(1) << "invalid value"; |
| + return false; |
| + } |
| + if (is_leading_zero) { |
| + if (*p != '0') |
| + is_leading_zero = false; |
| + else |
| + start++; // ignore leading zeroes |
| + } |
| + p++; |
| + } |
| + base::StringToUint(StringPiece(start, p), value); |
|
eroman
2014/09/23 21:12:28
This is still not checking for overflow.
arun87.kumar
2014/09/24 12:04:05
Added overflow check
|
| + return true; |
| +} |
| + |
| // Note: this implementation implicitly assumes that line_end points at a valid |
| // sentinel character (such as '\0'). |
| // static |
| @@ -629,8 +659,6 @@ HttpVersion HttpResponseHeaders::ParseVersion( |
| 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"; |
| @@ -645,23 +673,38 @@ HttpVersion HttpResponseHeaders::ParseVersion( |
| } |
| std::string::const_iterator dot = std::find(p, line_end, '.'); |
| - if (dot == line_end) { |
| + //second check is to verify if there is nothing after dot |
| + if (dot == line_end || dot+1 == line_end) { |
| + DVLOG(1) << "malformed version"; |
| + return HttpVersion(); |
| + } |
| + |
| + // find end of minor. |
| + std::string::const_iterator end_of_minor = dot+1; |
| + |
| + //skip numbers |
| + while(*end_of_minor >= '0' && *end_of_minor <= '9') |
| + end_of_minor++; |
| + |
| + //If there is no number after dot |
| + if(dot+1 == end_of_minor) { |
| DVLOG(1) << "malformed version"; |
| return HttpVersion(); |
| } |
| ++p; // from / to first digit. |
| - ++dot; // from . to second digit. |
| - if (!(*p >= '0' && *p <= '9' && *dot >= '0' && *dot <= '9')) { |
| - DVLOG(1) << "malformed version number"; |
| + uint32 major = 0; |
| + uint32 minor = 0; |
| + |
| + 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,18 +716,25 @@ 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() << "." |
| << http_version_.minor_value(); |