summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-26 21:34:08 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-26 21:34:08 +0000
commit803c73a9ad3151139f85732dfad0a3b1bf9887c4 (patch)
tree51e4b08443681de6b389c2b90240bc254c7fdaf9
parente0b80b3250092090db5d049c991c07a251d858f4 (diff)
downloadchromium_src-803c73a9ad3151139f85732dfad0a3b1bf9887c4.zip
chromium_src-803c73a9ad3151139f85732dfad0a3b1bf9887c4.tar.gz
chromium_src-803c73a9ad3151139f85732dfad0a3b1bf9887c4.tar.bz2
HttpResponseHeaders::GetContentRange() to handle implied LWS
There was a bug in HttpResponseHeaders::GetContentRange() that it didn't respect implied LWS rule, i.e. there can be arbitrary number of spaces in the header value between tokens. TEST=HttpResponseHeaders.GetContentRange Review URL: http://codereview.chromium.org/113675 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16921 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/http/http_response_headers.cc60
-rw-r--r--net/http/http_response_headers_unittest.cc38
2 files changed, 78 insertions, 20 deletions
diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc
index fb647ac..7f75466 100644
--- a/net/http/http_response_headers.cc
+++ b/net/http/http_response_headers.cc
@@ -980,31 +980,39 @@ bool HttpResponseHeaders::GetContentRange(int64* first_byte_position,
int64* last_byte_position,
int64* instance_length) const {
void* iter = NULL;
- std::string content_range_val;
- if (!EnumerateHeader(&iter, "content-range", &content_range_val))
+ std::string content_range_spec;
+ if (!EnumerateHeader(&iter, "content-range", &content_range_spec))
return false;
- if (content_range_val.empty())
+ // If the header value is empty, we have an invalid header.
+ if (content_range_spec.empty())
return false;
- size_t space_position = content_range_val.find(' ');
+ size_t space_position = content_range_spec.find(' ');
if (space_position == std::string::npos)
return false;
- if (!LowerCaseEqualsASCII(content_range_val.begin(),
- content_range_val.begin() + space_position,
+ // Invalid header if it doesn't contain "bytes-unit".
+ if (!LowerCaseEqualsASCII(content_range_spec.begin(),
+ content_range_spec.begin() + space_position,
"bytes")) {
return false;
}
- size_t slash_position = content_range_val.find('/', space_position + 1);
+ size_t slash_position = content_range_spec.find('/', space_position + 1);
if (slash_position == std::string::npos)
return false;
+ // Obtain the part behind the space and before slash.
+ std::string::const_iterator byte_range_resp_spec_begin =
+ content_range_spec.begin() + space_position + 1;
+ std::string::const_iterator byte_range_resp_spec_end =
+ content_range_spec.begin() + slash_position;
+ HttpUtil::TrimLWS(&byte_range_resp_spec_begin, &byte_range_resp_spec_end);
+
// Parse the byte-range-resp-spec part.
- std::string byte_range_resp_spec(
- content_range_val.begin() + space_position + 1,
- content_range_val.begin() + slash_position);
+ std::string byte_range_resp_spec(byte_range_resp_spec_begin,
+ byte_range_resp_spec_end);
// If byte-range-resp-spec == "*".
if (LowerCaseEqualsASCII(byte_range_resp_spec, "*")) {
*first_byte_position = -1;
@@ -1013,14 +1021,25 @@ bool HttpResponseHeaders::GetContentRange(int64* first_byte_position,
size_t minus_position = byte_range_resp_spec.find('-');
if (minus_position != std::string::npos) {
// Obtain first-byte-pos.
+ std::string::const_iterator first_byte_pos_begin =
+ byte_range_resp_spec.begin();
+ std::string::const_iterator first_byte_pos_end =
+ byte_range_resp_spec.begin() + minus_position;
+ HttpUtil::TrimLWS(&first_byte_pos_begin, &first_byte_pos_end);
+
bool ok = StringToInt64(
- std::string(byte_range_resp_spec.begin(),
- byte_range_resp_spec.begin() + minus_position),
+ std::string(first_byte_pos_begin, first_byte_pos_end),
first_byte_position);
+
// Obtain last-byte-pos.
+ std::string::const_iterator last_byte_pos_begin =
+ byte_range_resp_spec.begin() + minus_position + 1;
+ std::string::const_iterator last_byte_pos_end =
+ byte_range_resp_spec.end();
+ HttpUtil::TrimLWS(&last_byte_pos_begin, &last_byte_pos_end);
+
ok &= StringToInt64(
- std::string(byte_range_resp_spec.begin() + minus_position + 1,
- byte_range_resp_spec.end()),
+ std::string(last_byte_pos_begin, last_byte_pos_end),
last_byte_position);
if (!ok ||
*first_byte_position < 0 ||
@@ -1034,13 +1053,16 @@ bool HttpResponseHeaders::GetContentRange(int64* first_byte_position,
// Parse the instance-length part.
// If instance-length == "*".
- if (LowerCaseEqualsASCII(content_range_val.begin() + slash_position + 1,
- content_range_val.end(),
- "*")) {
+ std::string::const_iterator instance_length_begin =
+ content_range_spec.begin() + slash_position + 1;
+ std::string::const_iterator instance_length_end =
+ content_range_spec.end();
+ HttpUtil::TrimLWS(&instance_length_begin, &instance_length_end);
+
+ if (LowerCaseEqualsASCII(instance_length_begin, instance_length_end, "*")) {
*instance_length = -1;
} else if (!StringToInt64(
- std::string(content_range_val.begin() + slash_position + 1,
- content_range_val.end()),
+ std::string(instance_length_begin, instance_length_end),
instance_length)) {
return false;
} else if (*instance_length < 0 ||
diff --git a/net/http/http_response_headers_unittest.cc b/net/http/http_response_headers_unittest.cc
index 24ca9869..c78c597 100644
--- a/net/http/http_response_headers_unittest.cc
+++ b/net/http/http_response_headers_unittest.cc
@@ -1109,6 +1109,13 @@ TEST(HttpResponseHeaders, GetContentRange) {
51
},
{ "HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes\t0-50/51",
+ false,
+ -1,
+ -1,
+ -1
+ },
+ { "HTTP/1.1 206 Partial Content\n"
"Content-Range: bytes 0-50/51",
true,
0,
@@ -1116,7 +1123,22 @@ TEST(HttpResponseHeaders, GetContentRange) {
51
},
{ "HTTP/1.1 206 Partial Content\n"
- "Content-Range: bytes 0 - 50 / 51",
+ "Content-Range: bytes 0 - 50 \t / \t51",
+ true,
+ 0,
+ 50,
+ 51
+ },
+ { "HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0\t-\t50\t/\t51\t",
+ true,
+ 0,
+ 50,
+ 51
+ },
+
+ { "HTTP/1.1 206 Partial Content\n"
+ "Content-Range: \t bytes \t 0 - 50 / 5 1",
false,
-1,
-1,
@@ -1136,6 +1158,13 @@ TEST(HttpResponseHeaders, GetContentRange) {
-1,
-1
},
+ { "HTTP/1.1 416 Requested range not satisfiable\n"
+ "Content-Range: bytes * / * ",
+ true,
+ -1,
+ -1,
+ -1
+ },
{ "HTTP/1.1 206 Partial Content\n"
"Content-Range: bytes 0-50/*",
true,
@@ -1144,6 +1173,13 @@ TEST(HttpResponseHeaders, GetContentRange) {
-1
},
{ "HTTP/1.1 206 Partial Content\n"
+ "Content-Range: bytes 0-50 / * ",
+ true,
+ 0,
+ 50,
+ -1
+ },
+ { "HTTP/1.1 206 Partial Content\n"
"Content-Range: bytes 0-10000000000/10000000001",
true,
0,