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