Index: content/browser/service_worker/service_worker_url_request_job.cc |
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc |
index 143e354e8b14345bb27ea9a028e9888ada8892d6..15c85a10a295db830dc2abf315b7d2e90c4e8e8f 100644 |
--- a/content/browser/service_worker/service_worker_url_request_job.cc |
+++ b/content/browser/service_worker/service_worker_url_request_job.cc |
@@ -203,44 +203,50 @@ void ServiceWorkerURLRequestJob::SetExtraRequestHeaders( |
byte_range_ = ranges[0]; |
} |
-int ServiceWorkerURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) { |
+bool ServiceWorkerURLRequestJob::ReadRawData(net::IOBuffer* buf, |
+ int buf_size, |
+ int* bytes_read) { |
DCHECK(buf); |
DCHECK_GE(buf_size, 0); |
+ DCHECK(bytes_read); |
DCHECK(waiting_stream_url_.is_empty()); |
- |
- int bytes_read = 0; |
- |
if (stream_.get()) { |
- switch (stream_->ReadRawData(buf, buf_size, &bytes_read)) { |
+ switch (stream_->ReadRawData(buf, buf_size, bytes_read)) { |
case Stream::STREAM_HAS_DATA: |
- DCHECK_GT(bytes_read, 0); |
- return bytes_read; |
+ DCHECK_GT(*bytes_read, 0); |
+ return true; |
case Stream::STREAM_COMPLETE: |
- DCHECK_EQ(0, bytes_read); |
+ DCHECK(!*bytes_read); |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE); |
- return 0; |
+ return true; |
case Stream::STREAM_EMPTY: |
stream_pending_buffer_ = buf; |
stream_pending_buffer_size_ = buf_size; |
- return net::ERR_IO_PENDING; |
+ SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); |
+ return false; |
case Stream::STREAM_ABORTED: |
// Handle this as connection reset. |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED); |
- return net::ERR_CONNECTION_RESET; |
+ NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
+ net::ERR_CONNECTION_RESET)); |
+ return false; |
} |
NOTREACHED(); |
- return net::ERR_FAILED; |
+ return false; |
} |
- if (!blob_request_) |
- return 0; |
- blob_request_->Read(buf, buf_size, &bytes_read); |
+ if (!blob_request_) { |
+ *bytes_read = 0; |
+ return true; |
+ } |
+ blob_request_->Read(buf, buf_size, bytes_read); |
net::URLRequestStatus status = blob_request_->status(); |
- if (status.status() != net::URLRequestStatus::SUCCESS) |
- return status.error(); |
- if (bytes_read == 0) |
+ SetStatus(status); |
+ if (status.is_io_pending()) |
+ return false; |
+ if (status.is_success() && *bytes_read == 0) |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE); |
- return bytes_read; |
+ return status.is_success(); |
} |
// TODO(falken): Refactor Blob and Stream specific handling to separate classes. |
@@ -286,18 +292,29 @@ void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { |
void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, |
int bytes_read) { |
+ SetStatus(request->status()); |
if (!request->status().is_success()) { |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_BLOB_READ); |
- } else if (bytes_read == 0) { |
+ NotifyDone(request->status()); |
+ return; |
+ } |
+ |
+ if (bytes_read == 0) { |
+ // Protect because NotifyReadComplete() can destroy |this|. |
+ scoped_refptr<ServiceWorkerURLRequestJob> protect(this); |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_BLOB_RESPONSE); |
+ NotifyReadComplete(bytes_read); |
+ NotifyDone(request->status()); |
+ return; |
} |
- net::URLRequestStatus status = request->status(); |
- ReadRawDataComplete(status.is_success() ? bytes_read : status.error()); |
+ NotifyReadComplete(bytes_read); |
} |
// Overrides for Stream reading ----------------------------------------------- |
void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) { |
+ // Clear the IO_PENDING status. |
+ SetStatus(net::URLRequestStatus()); |
// Do nothing if stream_pending_buffer_ is empty, i.e. there's no ReadRawData |
// operation waiting for IO completion. |
if (!stream_pending_buffer_.get()) |
@@ -306,15 +323,15 @@ void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) { |
// stream_pending_buffer_ is set to the IOBuffer instance provided to |
// ReadRawData() by URLRequestJob. |
- int result = 0; |
+ int bytes_read = 0; |
switch (stream_->ReadRawData(stream_pending_buffer_.get(), |
- stream_pending_buffer_size_, &result)) { |
+ stream_pending_buffer_size_, &bytes_read)) { |
case Stream::STREAM_HAS_DATA: |
- DCHECK_GT(result, 0); |
+ DCHECK_GT(bytes_read, 0); |
break; |
case Stream::STREAM_COMPLETE: |
// Calling NotifyReadComplete with 0 signals completion. |
- DCHECK(!result); |
+ DCHECK(!bytes_read); |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_STREAM_RESPONSE); |
break; |
case Stream::STREAM_EMPTY: |
@@ -322,8 +339,9 @@ void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) { |
break; |
case Stream::STREAM_ABORTED: |
// Handle this as connection reset. |
- result = net::ERR_CONNECTION_RESET; |
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_STREAM_ABORTED); |
+ NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, |
+ net::ERR_CONNECTION_RESET)); |
break; |
} |
@@ -331,7 +349,7 @@ void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) { |
// safe for the observer to read. |
stream_pending_buffer_ = nullptr; |
stream_pending_buffer_size_ = 0; |
- ReadRawDataComplete(result); |
+ NotifyReadComplete(bytes_read); |
} |
void ServiceWorkerURLRequestJob::OnStreamRegistered(Stream* stream) { |
@@ -627,7 +645,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( |
// error. |
if (response.status_code == 0) { |
RecordStatusZeroResponseError(response.error); |
- NotifyStartError( |
+ NotifyDone( |
net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); |
return; |
} |