Chromium Code Reviews| Index: chrome/browser/chromeos/fileapi/external_file_url_request_job.cc |
| diff --git a/chrome/browser/chromeos/fileapi/external_file_url_request_job.cc b/chrome/browser/chromeos/fileapi/external_file_url_request_job.cc |
| index 213211377f192621a57a32919c58159adc29bffe..8eb852de466de69b8d09e5f8ba052c586519b364 100644 |
| --- a/chrome/browser/chromeos/fileapi/external_file_url_request_job.cc |
| +++ b/chrome/browser/chromeos/fileapi/external_file_url_request_job.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/memory/ref_counted.h" |
| +#include "base/thread_task_runner_handle.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/chromeos/file_manager/fileapi_util.h" |
| #include "chrome/browser/chromeos/fileapi/external_file_url_util.h" |
| @@ -19,7 +20,6 @@ |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/storage_partition.h" |
| #include "content/public/common/url_constants.h" |
| -#include "net/base/net_errors.h" |
| #include "net/http/http_byte_range.h" |
| #include "net/http/http_request_headers.h" |
| #include "net/http/http_response_info.h" |
| @@ -163,32 +163,47 @@ ExternalFileURLRequestJob::ExternalFileURLRequestJob( |
| net::NetworkDelegate* network_delegate) |
| : net::URLRequestJob(request, network_delegate), |
| profile_id_(profile_id), |
| + range_parse_result_(net::OK), |
| remaining_bytes_(0), |
| - weak_ptr_factory_(this) { |
| -} |
| + weak_ptr_factory_(this) {} |
| void ExternalFileURLRequestJob::SetExtraRequestHeaders( |
| const net::HttpRequestHeaders& headers) { |
| std::string range_header; |
| if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) { |
| - // Note: We only support single range requests. |
| + // Currently this job only cares about the Range header, and only supports |
| + // single range requests. Note that validation is deferred to Start, |
| + // because NotifyStartError is not legal to call since the job has not |
| + // started. |
| std::vector<net::HttpByteRange> ranges; |
| if (net::HttpUtil::ParseRangeHeader(range_header, &ranges) && |
| ranges.size() == 1) { |
| byte_range_ = ranges[0]; |
| } else { |
| - // Failed to parse Range: header, so notify the error. |
| - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| - net::ERR_REQUEST_RANGE_NOT_SATISFIABLE)); |
| + range_parse_result_ = net::ERR_REQUEST_RANGE_NOT_SATISFIABLE; |
| } |
| } |
| } |
| void ExternalFileURLRequestJob::Start() { |
| + // Post a task to invoke DoStart asynchronously to avoid re-entering the |
|
mtomasz
2015/11/02 05:43:21
Why is this necessary, while it wasn't before? The
xunjieli
2015/11/02 15:40:11
Done. NotifyStartError is not legal to call synchr
mmenke
2015/11/02 15:44:59
On a side note, I think we may want to allow this
|
| + // delegate. |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(&ExternalFileURLRequestJob::DoStart, |
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +void ExternalFileURLRequestJob::DoStart() { |
| DVLOG(1) << "Starting request"; |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(!stream_reader_); |
| + if (range_parse_result_ != net::OK) { |
| + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
| + range_parse_result_)); |
| + return; |
| + } |
| + |
| // We only support GET request. |
| if (request()->method() != "GET") { |
| LOG(WARNING) << "Failed to start request: " << request()->method() |
| @@ -326,38 +341,23 @@ bool ExternalFileURLRequestJob::IsRedirectResponse(GURL* location, |
| return true; |
| } |
| -bool ExternalFileURLRequestJob::ReadRawData(net::IOBuffer* buf, |
| - int buf_size, |
| - int* bytes_read) { |
| +int ExternalFileURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(stream_reader_); |
| - if (remaining_bytes_ == 0) { |
| - *bytes_read = 0; |
| - return true; |
| - } |
| + if (remaining_bytes_ == 0) |
| + return 0; |
| const int result = stream_reader_->Read( |
| - buf, |
| - std::min<int64>(buf_size, remaining_bytes_), |
| + buf, std::min<int64>(buf_size, remaining_bytes_), |
| base::Bind(&ExternalFileURLRequestJob::OnReadCompleted, |
| weak_ptr_factory_.GetWeakPtr())); |
| - if (result == net::ERR_IO_PENDING) { |
| - // The data is not yet available. |
| - SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); |
| - return false; |
| - } |
| - if (result < 0) { |
| - // An error occurs. |
| - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result)); |
| - return false; |
| - } |
| + if (result < 0) |
| + return result; |
| - // Reading has been finished immediately. |
| - *bytes_read = result; |
| remaining_bytes_ -= result; |
| - return true; |
| + return result; |
| } |
| ExternalFileURLRequestJob::~ExternalFileURLRequestJob() { |
| @@ -366,15 +366,10 @@ ExternalFileURLRequestJob::~ExternalFileURLRequestJob() { |
| void ExternalFileURLRequestJob::OnReadCompleted(int read_result) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (read_result < 0) { |
| - DCHECK_NE(read_result, net::ERR_IO_PENDING); |
| - NotifyDone( |
| - net::URLRequestStatus(net::URLRequestStatus::FAILED, read_result)); |
| - } |
| + if (read_result > 0) |
| + remaining_bytes_ -= read_result; |
| - remaining_bytes_ -= read_result; |
| - SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status. |
| - NotifyReadComplete(read_result); |
| + ReadRawDataComplete(read_result); |
| } |
| } // namespace chromeos |