summaryrefslogtreecommitdiffstats
path: root/net/url_request/url_request_file_job.cc
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-28 23:34:43 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-28 23:34:43 +0000
commit6220bb7e9f8d8201fe66b71941a3b0458d16d8b5 (patch)
tree846a041439b14418677256309afffd77dc74fe31 /net/url_request/url_request_file_job.cc
parentcf9995bcc40e8fd67551f660b7fe37cfd00b2c79 (diff)
downloadchromium_src-6220bb7e9f8d8201fe66b71941a3b0458d16d8b5.zip
chromium_src-6220bb7e9f8d8201fe66b71941a3b0458d16d8b5.tar.gz
chromium_src-6220bb7e9f8d8201fe66b71941a3b0458d16d8b5.tar.bz2
Supports single range request with file protocol
Added range request support in URLRequestFileJob to respect "Range" HTTP header. Fail with ERR_REQUESTED_RANGE_NOT_SATISFIABLE if range is bad. The following range request modes are supported: 1. Fully specified: bytes=x-y 2. With first byte position only: bytes=x- 3. With suffix length: bytes=-y Multiple ranges in a single request is not supported as we need to multipart encoding.. Review URL: http://codereview.chromium.org/92149 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14799 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request/url_request_file_job.cc')
-rw-r--r--net/url_request/url_request_file_job.cc61
1 files changed, 55 insertions, 6 deletions
diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc
index db3ff13..b3a7e4b 100644
--- a/net/url_request/url_request_file_job.cc
+++ b/net/url_request/url_request_file_job.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -29,6 +29,7 @@
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
+#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_file_dir_job.h"
@@ -90,7 +91,8 @@ URLRequestFileJob::URLRequestFileJob(URLRequest* request,
file_path_(file_path),
ALLOW_THIS_IN_INITIALIZER_LIST(
io_callback_(this, &URLRequestFileJob::DidRead)),
- is_directory_(false) {
+ is_directory_(false),
+ remaining_bytes_(0) {
}
URLRequestFileJob::~URLRequestFileJob() {
@@ -135,11 +137,17 @@ bool URLRequestFileJob::ReadRawData(net::IOBuffer* dest, int dest_size,
int *bytes_read) {
DCHECK_NE(dest_size, 0);
DCHECK(bytes_read);
+ DCHECK_GE(remaining_bytes_, 0);
+
+ if (remaining_bytes_ < dest_size)
+ dest_size = static_cast<int>(remaining_bytes_);
int rv = stream_.Read(dest->data(), dest_size, &io_callback_);
if (rv >= 0) {
// Data is immediately available.
*bytes_read = rv;
+ remaining_bytes_ -= rv;
+ DCHECK_GE(remaining_bytes_, 0);
return true;
}
@@ -175,6 +183,22 @@ void URLRequestFileJob::GetResponseInfo(net::HttpResponseInfo* info) {
}
}
+void URLRequestFileJob::SetExtraRequestHeaders(const std::string& headers) {
+ // We only care about "Range" header here.
+ std::vector<net::HttpByteRange> ranges;
+ if (net::HttpUtil::ParseRanges(headers, &ranges)) {
+ if (ranges.size() == 1) {
+ byte_range_ = ranges[0];
+ } else {
+ // We don't support multiple range requests in one single URL request,
+ // because we need to do multipart encoding here.
+ // TODO(hclam): decide whether we want to support multiple range requests.
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ }
+ }
+}
+
void URLRequestFileJob::DidResolve(
bool exists, const file_util::FileInfo& file_info) {
#if defined(OS_WIN)
@@ -200,12 +224,33 @@ void URLRequestFileJob::DidResolve(
rv = stream_.Open(file_path_, flags);
}
- if (rv == net::OK) {
- set_expected_content_size(file_info.size);
- NotifyHeadersComplete();
- } else {
+ if (rv != net::OK) {
NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, rv));
+ return;
+ }
+
+ if (!byte_range_.ComputeBounds(file_info.size)) {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ return;
+ }
+
+ remaining_bytes_ = byte_range_.last_byte_position() -
+ byte_range_.first_byte_position() + 1;
+ DCHECK_GE(remaining_bytes_, 0);
+
+ // Do the seek at the beginning of the request.
+ if (remaining_bytes_ > 0 &&
+ byte_range_.first_byte_position() != 0 &&
+ byte_range_.first_byte_position() !=
+ stream_.Seek(net::FROM_BEGIN, byte_range_.first_byte_position())) {
+ NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE));
+ return;
}
+
+ set_expected_content_size(remaining_bytes_);
+ NotifyHeadersComplete();
}
void URLRequestFileJob::DidRead(int result) {
@@ -216,6 +261,10 @@ void URLRequestFileJob::DidRead(int result) {
} else {
NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result));
}
+
+ remaining_bytes_ -= result;
+ DCHECK_GE(remaining_bytes_, 0);
+
NotifyReadComplete(result);
}