1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be 321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file. 421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/glue/media/buffered_resource_loader.h" 621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/format_macros.h" 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/string_util.h" 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_errors.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebKitClient.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" 1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/glue/multipart_response_delegate.h" 1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/glue/webkit_glue.h" 1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebFrame; 1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebString; 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebURLError; 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebURLLoader; 2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebURLRequest; 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebURLResponse; 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing webkit_glue::MultipartResponseDelegate; 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace webkit_glue { 2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kHttpOK = 200; 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kHttpPartialContent = 206; 2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Define the number of bytes in a megabyte. 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const size_t kMegabyte = 1024 * 1024; 3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Backward capacity of the buffer, by default 2MB. 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const size_t kBackwardCapcity = 2 * kMegabyte; 3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Forward capacity of the buffer, by default 10MB. 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const size_t kForwardCapacity = 10 * kMegabyte; 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// The threshold of bytes that we should wait until the data arrives in the 4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// future instead of restarting a new connection. This number is defined in the 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// number of bytes, we should determine this value from typical connection speed 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// and amount of time for a suitable wait. Now I just make a guess for this 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// number to be 2MB. 4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(hclam): determine a better value for this. 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kForwardWaitThreshold = 2 * kMegabyte; 4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenBufferedResourceLoader::BufferedResourceLoader( 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const GURL& url, 4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int64 first_byte_position, 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int64 last_byte_position) 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen deferred_(false), 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen defer_strategy_(kReadThenDefer), 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen completed_(false), 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen range_requested_(false), 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen range_supported_(false), 5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_(url), 5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_byte_position_(first_byte_position), 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen last_byte_position_(last_byte_position), 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen single_origin_(true), 6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen start_callback_(NULL), 6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen offset_(0), 6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen content_length_(kPositionNotSpecified), 6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen instance_size_(kPositionNotSpecified), 6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_callback_(NULL), 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_position_(0), 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_size_(0), 6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_buffer_(NULL), 6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_offset_(0), 7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen last_offset_(0), 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen keep_test_loader_(false) { 7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenBufferedResourceLoader::~BufferedResourceLoader() { 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!completed_ && url_loader_.get()) 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_->cancel(); 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::Start(net::CompletionCallback* start_callback, 8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NetworkEventCallback* event_callback, 8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebFrame* frame) { 8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Make sure we have not started. 8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!start_callback_.get()); 8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!event_callback_.get()); 8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(start_callback); 8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(event_callback); 8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CHECK(frame); 8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen start_callback_.reset(start_callback); 9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen event_callback_.reset(event_callback); 9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_byte_position_ != kPositionNotSpecified) { 9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(hclam): server may not support range request so |offset_| may not 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // equal to |first_byte_position_|. 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen offset_ = first_byte_position_; 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Increment the reference count right before we start the request. This 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // reference will be release when this request has ended. 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AddRef(); 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Prepare the request. 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLRequest request(url_); 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen request.setTargetType(WebURLRequest::TargetIsMedia); 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (IsRangeRequest()) { 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen range_requested_ = true; 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request.setHTTPHeaderField(WebString::fromUTF8("Range"), 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WebString::fromUTF8(GenerateHeaders( 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen first_byte_position_, 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen last_byte_position_))); 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen frame->setReferrerForRequest(request, WebKit::WebURL()); 11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // This flag is for unittests as we don't want to reset |url_loader| 11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!keep_test_loader_) 11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_.reset(frame->createAssociatedURLLoader()); 11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Start the resource loading. 12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_->loadAsynchronously(request, this); 12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::Stop() { 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Reset callbacks. 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen start_callback_.reset(); 12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen event_callback_.reset(); 12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_callback_.reset(); 12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Use the internal buffer to signal that we have been stopped. 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(hclam): Not so pretty to do this. 13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!buffer_.get()) 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Destroy internal buffer. 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen buffer_.reset(); 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (url_loader_.get()) { 13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (deferred_) 13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_->setDefersLoading(false); 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen deferred_ = false; 14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!completed_) { 14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_->cancel(); 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen completed_ = true; 14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::Read(int64 position, 15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int read_size, 15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen uint8* buffer, 15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::CompletionCallback* read_callback) { 15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!read_callback_.get()); 15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(buffer_.get()); 15521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(read_callback); 15621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(buffer); 15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Save the parameter of reading. 15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_callback_.reset(read_callback); 16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_position_ = position; 16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_size_ = read_size; 16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_buffer_ = buffer; 16321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If read position is beyond the instance size, we cannot read there. 16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (instance_size_ != kPositionNotSpecified && 16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen instance_size_ <= read_position_) { 16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneRead(0); 16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Make sure |offset_| and |read_position_| does not differ by a large 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // amount. 17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (read_position_ > offset_ + kint32max || 17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_position_ < offset_ + kint32min) { 17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneRead(net::ERR_CACHE_MISS); 17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Prepare the parameters. 18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_offset_ = static_cast<int>(read_position_ - offset_); 18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen last_offset_ = first_offset_ + read_size_; 18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If we can serve the request now, do the actual read. 18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (CanFulfillRead()) { 18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ReadInternal(); 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateDeferBehavior(); 18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If you're deferred and you can't fulfill the read because you don't have 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // enough data, you will never fulfill the read. 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Update defer behavior to re-enable deferring if need be. 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateDeferBehavior(); 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 19521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If we expected the read request to be fulfilled later, returns 19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // immediately and let more data to flow in. 19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (WillFulfillRead()) 19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Make a callback to report failure. 20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneRead(net::ERR_CACHE_MISS); 20221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 20321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 20421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint64 BufferedResourceLoader::GetBufferedPosition() { 20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (buffer_.get()) 20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; 20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return kPositionNotSpecified; 20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint64 BufferedResourceLoader::content_length() { 21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return content_length_; 21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint64 BufferedResourceLoader::instance_size() { 21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return instance_size_; 21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BufferedResourceLoader::range_supported() { 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return range_supported_; 22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool BufferedResourceLoader::network_activity() { 22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return !completed_ && !deferred_; 22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst GURL& BufferedResourceLoader::url() { 22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return url_; 22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::SetURLLoaderForTest(WebURLLoader* mock_loader) { 23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_.reset(mock_loader); 23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen keep_test_loader_ = true; 23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen///////////////////////////////////////////////////////////////////////////// 23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// WebKit::WebURLLoaderClient implementation. 23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::willSendRequest( 23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLRequest& newRequest, 24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const WebURLResponse& redirectResponse) { 24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // The load may have been stopped and |start_callback| is destroyed. 24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // In this case we shouldn't do anything. 24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!start_callback_.get()) { 24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Set the url in the request to an invalid value (empty url). 24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen newRequest.setURL(WebKit::WebURL()); 24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only allow |single_origin_| if we haven't seen a different origin yet. 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (single_origin_) 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin(); 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 25421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!IsProtocolSupportedForMedia(newRequest.url())) { 25521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Set the url in the request to an invalid value (empty url). 25621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen newRequest.setURL(WebKit::WebURL()); 25721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneStart(net::ERR_ADDRESS_INVALID); 25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 26121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_ = newRequest.url(); 26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 26321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 26421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didSendData( 26521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 26621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen unsigned long long bytes_sent, 26721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen unsigned long long total_bytes_to_be_sent) { 26821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTIMPLEMENTED(); 26921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 27021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 27121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didReceiveResponse( 27221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 27321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const WebURLResponse& response) { 27421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 27521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // The loader may have been stopped and |start_callback| is destroyed. 27621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // In this case we shouldn't do anything. 27721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!start_callback_.get()) 27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 27921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool partial_response = false; 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 28221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // We make a strong assumption that when we reach here we have either 28321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // received a response from HTTP/HTTPS protocol or the request was 28421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // successful (in particular range request). So we only verify the partial 28521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // response for HTTP and HTTPS protocol. 28621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { 28721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int error = net::OK; 28821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check to see whether the server supports byte ranges. 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string accept_ranges = 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen response.httpHeaderField("Accept-Ranges").utf8(); 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen range_supported_ = (accept_ranges.find("bytes") != std::string::npos); 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen partial_response = (response.httpStatusCode() == kHttpPartialContent); 29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (range_requested_) { 29721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If we have verified the partial response and it is correct, we will 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // return net::OK. It's also possible for a server to support range 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // requests without advertising Accept-Ranges: bytes. 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (partial_response && VerifyPartialResponse(response)) 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen range_supported_ = true; 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else 30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen error = net::ERR_INVALID_RESPONSE; 30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (response.httpStatusCode() != kHttpOK) { 30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // We didn't request a range but server didn't reply with "200 OK". 30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen error = net::ERR_FAILED; 30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (error != net::OK) { 31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneStart(error); 31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Stop(); 31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else { 31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // For any protocol other than HTTP and HTTPS, assume range request is 31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // always fulfilled. 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen partial_response = range_requested_; 31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Expected content length can be |kPositionNotSpecified|, in that case 32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // |content_length_| is not specified and this is a streaming response. 32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen content_length_ = response.expectedContentLength(); 32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If we have not requested a range, then the size of the instance is equal 32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // to the content length. 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!partial_response) 32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen instance_size_ = content_length_; 32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Calls with a successful response. 33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneStart(net::OK); 33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didReceiveData( 33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const char* data, 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int data_length, 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int encoded_data_length) { 33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!completed_); 33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK_GT(data_length, 0); 34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If this loader has been stopped, |buffer_| would be destroyed. 34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // In this case we shouldn't do anything. 34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!buffer_.get()) 34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Writes more data to |buffer_|. 34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); 34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If there is an active read request, try to fulfill the request. 350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (HasPendingRead() && CanFulfillRead()) 35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ReadInternal(); 35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // At last see if the buffer is full and we need to defer the downloading. 354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateDeferBehavior(); 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Consume excess bytes from our in-memory buffer if necessary. 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (buffer_->forward_bytes() > buffer_->forward_capacity()) { 358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); 359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool success = buffer_->Seek(excess); 360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(success); 361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen offset_ += first_offset_ + excess; 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Notify that we have received some data. 36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NotifyNetworkEvent(); 36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didDownloadData( 36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebKit::WebURLLoader* loader, 37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int dataLength) { 37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTIMPLEMENTED(); 37221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 37421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didReceiveCachedMetadata( 37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const char* data, 37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int data_length) { 37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTIMPLEMENTED(); 37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didFinishLoading( 38221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen double finishTime) { 38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!completed_); 38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen completed_ = true; 38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If we didn't know the |instance_size_| we do now. 388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (instance_size_ == kPositionNotSpecified) { 389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen instance_size_ = offset_ + buffer_->forward_bytes(); 390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If there is a start callback, calls it. 39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (start_callback_.get()) { 39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneStart(net::OK); 39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If there is a pending read but the request has ended, returns with what 39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // we have. 39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (HasPendingRead()) { 40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Make sure we have a valid buffer before we satisfy a read request. 40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(buffer_.get()); 40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Try to fulfill with what is in the buffer. 40421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (CanFulfillRead()) 40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ReadInternal(); 40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen else 40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneRead(net::ERR_CACHE_MISS); 40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // There must not be any outstanding read request. 41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!HasPendingRead()); 41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Notify that network response is completed. 41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NotifyNetworkEvent(); 41521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_.reset(); 41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Release(); 41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::didFail( 42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen WebURLLoader* loader, 42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const WebURLError& error) { 42321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!completed_); 42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen completed_ = true; 42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 42621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If there is a start callback, calls it. 42721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (start_callback_.get()) { 42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneStart(error.reason); 42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If there is a pending read but the request failed, return with the 43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // reason for the error. 43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (HasPendingRead()) { 43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneRead(error.reason); 43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 43621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Notify that network response is completed. 43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NotifyNetworkEvent(); 43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen url_loader_.reset(); 44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Release(); 44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 44472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool BufferedResourceLoader::HasSingleOrigin() const { 44572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return single_origin_; 44672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 44772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen///////////////////////////////////////////////////////////////////////////// 44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Helper methods. 450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BufferedResourceLoader::UpdateDeferBehavior() { 451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!url_loader_.get() || !buffer_.get()) 45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return; 45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if ((deferred_ && ShouldDisableDefer()) || 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (!deferred_ && ShouldEnableDefer())) { 456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool eventOccurred = ToggleDeferring(); 457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (eventOccurred) 458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotifyNetworkEvent(); 459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { 463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen defer_strategy_ = strategy; 464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateDeferBehavior(); 465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BufferedResourceLoader::ShouldEnableDefer() { 468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If we're already deferring, then enabling makes no sense. 469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (deferred_) 470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switch(defer_strategy_) { 473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Never defer at all, so never enable defer. 474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case kNeverDefer: 475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Defer if nothing is being requested. 478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case kReadThenDefer: 479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return !read_callback_.get(); 480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Defer if we've reached the max capacity of the threshold. 482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case kThresholdDefer: 483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return buffer_->forward_bytes() >= buffer_->forward_capacity(); 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Otherwise don't enable defer. 486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 48821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BufferedResourceLoader::ShouldDisableDefer() { 490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If we're not deferring, then disabling makes no sense. 491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!deferred_) 492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 49321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switch(defer_strategy_) { 495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Always disable deferring. 496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case kNeverDefer: 497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We have an outstanding read request, and we have not buffered enough 500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // yet to fulfill the request; disable defer to get more data. 501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case kReadThenDefer: { 502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t amount_buffered = buffer_->forward_bytes(); 503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t amount_to_read = static_cast<size_t>(read_size_); 504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return read_callback_.get() && amount_buffered < amount_to_read; 505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 50621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We have less than half the capacity of our threshold, so 508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // disable defer to get more data. 509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case kThresholdDefer: { 510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t amount_buffered = buffer_->forward_bytes(); 511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t half_capacity = buffer_->forward_capacity() / 2; 512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return amount_buffered < half_capacity; 513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 51421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Otherwise keep deferring. 517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BufferedResourceLoader::ToggleDeferring() { 521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen deferred_ = !deferred_; 522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (url_loader_.get()) { 523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url_loader_->setDefersLoading(deferred_); 524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 52721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 52821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 52921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool BufferedResourceLoader::CanFulfillRead() { 53021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If we are reading too far in the backward direction. 53121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_offset_ < 0 && 53221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) 53321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 53421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 53521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If the start offset is too far ahead. 53621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) 53721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 53821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 53921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // At the point, we verified that first byte requested is within the buffer. 54021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If the request has completed, then just returns with what we have now. 54121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (completed_) 54221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 54321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // If the resource request is still active, make sure the whole requested 54521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // range is covered. 54621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (last_offset_ > static_cast<int>(buffer_->forward_bytes())) 54721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 54821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 54921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 55021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 55121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 55221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool BufferedResourceLoader::WillFulfillRead() { 55321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Reading too far in the backward direction. 55421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_offset_ < 0 && 55521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) 55621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 55721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 55821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Try to read too far ahead. 55921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (last_offset_ > kForwardWaitThreshold) 56021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 56121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // The resource request has completed, there's no way we can fulfill the 56321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // read request. 56421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (completed_) 56521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 56621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 56721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 56821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 56921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 57021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::ReadInternal() { 57121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Seek to the first byte requested. 57221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen bool ret = buffer_->Seek(first_offset_); 57321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(ret); 57421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 57521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Then do the read. 57621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int read = static_cast<int>(buffer_->Read(read_buffer_, read_size_)); 57721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen offset_ += first_offset_ + read; 57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 57921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // And report with what we have read. 58021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DoneRead(read); 58121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 58221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 58321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool BufferedResourceLoader::VerifyPartialResponse( 58421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const WebURLResponse& response) { 58521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int first_byte_position, last_byte_position, instance_size; 58621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 58721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!MultipartResponseDelegate::ReadContentRanges(response, 58821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &first_byte_position, 58921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &last_byte_position, 59021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen &instance_size)) { 59121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 59221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 59321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 59421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (instance_size != kPositionNotSpecified) { 59521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen instance_size_ = instance_size; 59621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 59721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 59821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_byte_position_ != kPositionNotSpecified && 59921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_byte_position_ != first_byte_position) { 60021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 60121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 60221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 60321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(hclam): I should also check |last_byte_position|, but since 60421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // we will never make such a request that it is ok to leave it unimplemented. 60521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 60621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 60721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 60821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstd::string BufferedResourceLoader::GenerateHeaders( 60921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int64 first_byte_position, 61021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int64 last_byte_position) { 61121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Construct the value for the range header. 61221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string header; 61321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_byte_position > kPositionNotSpecified && 61421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen last_byte_position > kPositionNotSpecified) { 61521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (first_byte_position <= last_byte_position) { 61621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen header = base::StringPrintf("bytes=%" PRId64 "-%" PRId64, 61721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_byte_position, 61821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen last_byte_position); 61921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 62021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (first_byte_position > kPositionNotSpecified) { 62121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen header = base::StringPrintf("bytes=%" PRId64 "-", 62221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_byte_position); 62321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } else if (last_byte_position > kPositionNotSpecified) { 62421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NOTIMPLEMENTED() << "Suffix range not implemented"; 62521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 62621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return header; 62721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 62821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 62921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::DoneRead(int error) { 63021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_callback_->RunWithParams(Tuple1<int>(error)); 63121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_callback_.reset(); 63221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_position_ = 0; 63321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_size_ = 0; 63421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen read_buffer_ = NULL; 63521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen first_offset_ = 0; 63621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen last_offset_ = 0; 63721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 63821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 63921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::DoneStart(int error) { 64021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen start_callback_->RunWithParams(Tuple1<int>(error)); 64121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen start_callback_.reset(); 64221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 64321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 64421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid BufferedResourceLoader::NotifyNetworkEvent() { 64521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (event_callback_.get()) 64621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen event_callback_->Run(); 64721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 64821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool BufferedResourceLoader::IsRangeRequest() const { 650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return first_byte_position_ != kPositionNotSpecified; 651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 65321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} // namespace webkit_glue 654