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(); |