Index: content/browser/appcache/appcache_job.cc |
diff --git a/content/browser/appcache/appcache_job.cc b/content/browser/appcache/appcache_job.cc |
index 5bd29cc8c421ed7a2dc8d97d2833ccfca6f0373b..12e6cc077d21622173bce67bb8810f2f937f6fca 100644 |
--- a/content/browser/appcache/appcache_job.cc |
+++ b/content/browser/appcache/appcache_job.cc |
@@ -6,10 +6,13 @@ |
#include "base/command_line.h" |
#include "content/browser/appcache/appcache_request.h" |
+#include "content/browser/appcache/appcache_response.h" |
#include "content/browser/appcache/appcache_url_loader_job.h" |
#include "content/browser/appcache/appcache_url_request_job.h" |
- |
#include "content/public/common/content_switches.h" |
+#include "net/http/http_request_headers.h" |
+#include "net/http/http_response_headers.h" |
+#include "net/http/http_util.h" |
namespace content { |
@@ -74,4 +77,44 @@ AppCacheJob::AppCacheJob() |
delivery_type_(AWAITING_DELIVERY_ORDERS), |
weak_factory_(this) {} |
+void AppCacheJob::InitializeRangeRequestInfo( |
+ const net::HttpRequestHeaders& headers) { |
+ std::string value; |
+ std::vector<net::HttpByteRange> ranges; |
+ if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &value) || |
+ !net::HttpUtil::ParseRangeHeader(value, &ranges)) { |
+ return; |
+ } |
+ |
+ // If multiple ranges are requested, we play dumb and |
+ // return the entire response with 200 OK. |
+ if (ranges.size() == 1U) |
+ range_requested_ = ranges[0]; |
+} |
+ |
+void AppCacheJob::SetupRangeResponse(AppCacheResponseReader* reader) { |
+ DCHECK(is_range_request() && reader && IsDeliveringAppCacheResponse()); |
+ int resource_size = static_cast<int>(info_->response_data_size()); |
+ if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { |
+ range_requested_ = net::HttpByteRange(); |
+ return; |
+ } |
+ |
+ DCHECK(range_requested_.IsValid()); |
+ int offset = static_cast<int>(range_requested_.first_byte_position()); |
+ int length = static_cast<int>(range_requested_.last_byte_position() - |
+ range_requested_.first_byte_position() + 1); |
+ |
+ // Tell the reader about the range to read. |
+ reader->SetReadRange(offset, length); |
+ |
+ // Make a copy of the full response headers and fix them up |
+ // for the range we'll be returning. |
+ range_response_info_.reset( |
+ new net::HttpResponseInfo(*info_->http_response_info())); |
+ net::HttpResponseHeaders* headers = range_response_info_->headers.get(); |
+ headers->UpdateWithNewRange(range_requested_, resource_size, |
+ true /* replace status line */); |
+} |
+ |
} // namespace content |