summaryrefslogtreecommitdiffstats
path: root/net/http/http_response_headers.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/http/http_response_headers.cc')
-rw-r--r--net/http/http_response_headers.cc84
1 files changed, 83 insertions, 1 deletions
diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc
index bc7ac62..59bd854 100644
--- a/net/http/http_response_headers.cc
+++ b/net/http/http_response_headers.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -969,4 +969,86 @@ int64 HttpResponseHeaders::GetContentLength() const {
return result;
}
+// From RFC 2616 14.16:
+// content-range-spec =
+// bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" )
+// byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*"
+// instance-length = 1*DIGIT
+// bytes-unit = "bytes"
+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))
+ return false;
+
+ if (content_range_val.empty())
+ return false;
+
+ size_t space_position = content_range_val.find(' ');
+ if (space_position == std::string::npos)
+ return false;
+
+ if (!LowerCaseEqualsASCII(content_range_val.begin(),
+ content_range_val.begin() + space_position,
+ "bytes")) {
+ return false;
+ }
+
+ size_t slash_position = content_range_val.find('/', space_position + 1);
+ if (slash_position == std::string::npos)
+ return false;
+
+ // 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);
+ // If byte-range-resp-spec == "*".
+ if (LowerCaseEqualsASCII(byte_range_resp_spec, "*")) {
+ *first_byte_position = -1;
+ *last_byte_position = -1;
+ } else {
+ size_t minus_position = byte_range_resp_spec.find('-');
+ if (minus_position != std::string::npos) {
+ // Obtain first-byte-pos.
+ bool ok = StringToInt64(
+ std::string(byte_range_resp_spec.begin(),
+ byte_range_resp_spec.begin() + minus_position),
+ first_byte_position);
+ // Obtain last-byte-pos.
+ ok &= StringToInt64(
+ std::string(byte_range_resp_spec.begin() + minus_position + 1,
+ byte_range_resp_spec.end()),
+ last_byte_position);
+ if (!ok ||
+ *first_byte_position < 0 ||
+ *last_byte_position < 0 ||
+ *first_byte_position > *last_byte_position)
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ // Parse the instance-length part.
+ // If instance-length == "*".
+ if (LowerCaseEqualsASCII(content_range_val.begin() + slash_position + 1,
+ content_range_val.end(),
+ "*")) {
+ *instance_length = -1;
+ } else if (!StringToInt64(
+ std::string(content_range_val.begin() + slash_position + 1,
+ content_range_val.end()),
+ instance_length)) {
+ return false;
+ } else if (*instance_length < 0 ||
+ *instance_length <
+ *last_byte_position - *first_byte_position + 1) {
+ return false;
+ }
+
+ return true;
+}
+
} // namespace net