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() << "." |