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 37d22d01df41fc778f1914ea9f0fb389966b22a2..b48b8d96a6ecce970fc57d6d0931b13f8f5c0422 100644 |
--- a/content/browser/service_worker/service_worker_url_request_job.cc |
+++ b/content/browser/service_worker/service_worker_url_request_job.cc |
@@ -12,17 +12,22 @@ |
#include "net/http/http_response_headers.h" |
#include "net/http/http_response_info.h" |
#include "net/http/http_util.h" |
+#include "webkit/browser/blob/blob_data_handle.h" |
+#include "webkit/browser/blob/blob_storage_context.h" |
+#include "webkit/browser/blob/blob_url_request_job_factory.h" |
namespace content { |
ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( |
net::URLRequest* request, |
net::NetworkDelegate* network_delegate, |
- base::WeakPtr<ServiceWorkerProviderHost> provider_host) |
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
+ base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context) |
: net::URLRequestJob(request, network_delegate), |
provider_host_(provider_host), |
response_type_(NOT_DETERMINED), |
is_started_(false), |
+ blob_storage_context_(blob_storage_context), |
weak_factory_(this) { |
} |
@@ -46,6 +51,7 @@ void ServiceWorkerURLRequestJob::Start() { |
void ServiceWorkerURLRequestJob::Kill() { |
net::URLRequestJob::Kill(); |
fetch_dispatcher_.reset(); |
+ blob_request_.reset(); |
weak_factory_.InvalidateWeakPtrs(); |
} |
@@ -94,13 +100,64 @@ void ServiceWorkerURLRequestJob::SetExtraRequestHeaders( |
bool ServiceWorkerURLRequestJob::ReadRawData( |
net::IOBuffer* buf, int buf_size, int *bytes_read) { |
- // TODO(kinuko): Implement this. |
- // If the response returned from ServiceWorker had an |
- // identifier to on-disk data (e.g. blob or cache entry) we'll need to |
- // pull the body from disk. |
- NOTIMPLEMENTED(); |
- *bytes_read = 0; |
- return true; |
+ if (!blob_request_) { |
+ *bytes_read = 0; |
+ return true; |
+ } |
+ |
+ blob_request_->Read(buf, buf_size, bytes_read); |
+ net::URLRequestStatus status = blob_request_->status(); |
+ SetStatus(status); |
+ if (status.is_io_pending()) |
+ return false; |
+ return status.is_success(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnReceivedRedirect(net::URLRequest* request, |
+ const GURL& new_url, |
+ bool* defer_redirect) { |
+ NOTREACHED(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnAuthRequired( |
+ net::URLRequest* request, |
+ net::AuthChallengeInfo* auth_info) { |
+ NOTREACHED(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnCertificateRequested( |
+ net::URLRequest* request, |
+ net::SSLCertRequestInfo* cert_request_info) { |
+ NOTREACHED(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnSSLCertificateError( |
+ net::URLRequest* request, |
+ const net::SSLInfo& ssl_info, |
+ bool fatal) { |
+ NOTREACHED(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnBeforeNetworkStart(net::URLRequest* request, |
+ bool* defer) { |
+ NOTREACHED(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { |
+ // TODO(falken): Add Content-Length, Content-Type if they were not provided in |
+ // the ServiceWorkerResponse. |
+ CommitResponseHeader(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, |
+ int bytes_read) { |
+ if (!request->status().is_success()) { |
+ NotifyDone(request->status()); |
+ return; |
+ } |
+ NotifyReadComplete(bytes_read); |
+ if (bytes_read == 0) |
+ NotifyDone(request->status()); |
} |
const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { |
@@ -183,36 +240,64 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( |
return; |
} |
- // We should have response now. |
+ // We should have a response now. |
DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); |
- CreateResponseHeader(response); |
- NotifyHeadersComplete(); |
+ // Set up a request for reading the blob. |
+ if (!response.blob_uuid.empty() && blob_storage_context_) { |
+ scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle = |
+ blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); |
+ if (!blob_data_handle) { |
+ // The renderer gave us a bad blob UUID. |
+ DeliverErrorResponse(); |
+ return; |
+ } |
+ blob_request_ = webkit_blob::BlobProtocolHandler::CreateBlobRequest( |
+ blob_data_handle.Pass(), request()->context(), this); |
+ blob_request_->Start(); |
+ } |
+ |
+ CreateResponseHeader( |
+ response.status_code, response.status_text, response.headers); |
+ if (!blob_request_) |
+ CommitResponseHeader(); |
} |
void ServiceWorkerURLRequestJob::CreateResponseHeader( |
- const ServiceWorkerResponse& response) { |
+ int status_code, |
+ const std::string& status_text, |
+ const std::map<std::string, std::string>& headers) { |
// TODO(kinuko): If the response has an identifier to on-disk cache entry, |
// pull response header from the disk. |
- std::string status_line(base::StringPrintf("HTTP/1.1 %d %s", |
- response.status_code, |
- response.status_text.c_str())); |
+ std::string status_line( |
+ base::StringPrintf("HTTP/1.1 %d %s", status_code, status_text.c_str())); |
status_line.push_back('\0'); |
- scoped_refptr<net::HttpResponseHeaders> headers( |
- new net::HttpResponseHeaders(status_line)); |
- for (std::map<std::string, std::string>::const_iterator it = |
- response.headers.begin(); |
- it != response.headers.end(); ++it) { |
+ http_response_headers_ = new net::HttpResponseHeaders(status_line); |
+ for (std::map<std::string, std::string>::const_iterator it = headers.begin(); |
+ it != headers.end(); |
+ ++it) { |
std::string header; |
header.reserve(it->first.size() + 2 + it->second.size()); |
header.append(it->first); |
header.append(": "); |
header.append(it->second); |
- headers->AddHeader(header); |
+ http_response_headers_->AddHeader(header); |
} |
+} |
+void ServiceWorkerURLRequestJob::CommitResponseHeader() { |
http_response_info_.reset(new net::HttpResponseInfo()); |
- http_response_info_->headers = headers; |
+ http_response_info_->headers.swap(http_response_headers_); |
+ NotifyHeadersComplete(); |
+} |
+ |
+void ServiceWorkerURLRequestJob::DeliverErrorResponse() { |
+ // TODO(falken): Print an error to the console of the ServiceWorker and of |
+ // the requesting page. |
+ CreateResponseHeader(500, |
+ "Service Worker Response Error", |
+ std::map<std::string, std::string>()); |
+ CommitResponseHeader(); |
} |
} // namespace content |