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 94298caa7a90961ae4e14eea9e53df32e9bd44d6..6a795d630de276a655d8a46490ff576385bed64f 100644 |
--- a/content/browser/service_worker/service_worker_url_request_job.cc |
+++ b/content/browser/service_worker/service_worker_url_request_job.cc |
@@ -9,9 +9,15 @@ |
#include <vector> |
#include "base/bind.h" |
+#include "base/guid.h" |
#include "base/strings/stringprintf.h" |
#include "content/browser/service_worker/service_worker_fetch_dispatcher.h" |
#include "content/browser/service_worker/service_worker_provider_host.h" |
+#include "content/common/resource_request_body.h" |
+#include "content/common/service_worker/service_worker_types.h" |
+#include "content/public/browser/blob_handle.h" |
+#include "content/public/browser/resource_request_info.h" |
+#include "content/public/common/page_transition_types.h" |
#include "net/http/http_request_headers.h" |
#include "net/http/http_response_headers.h" |
#include "net/http/http_response_info.h" |
@@ -26,12 +32,14 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( |
net::URLRequest* request, |
net::NetworkDelegate* network_delegate, |
base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
- base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context) |
+ base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context, |
+ scoped_refptr<ResourceRequestBody> body) |
: net::URLRequestJob(request, network_delegate), |
provider_host_(provider_host), |
response_type_(NOT_DETERMINED), |
is_started_(false), |
blob_storage_context_(blob_storage_context), |
+ body_(body), |
weak_factory_(this) { |
} |
@@ -216,11 +224,11 @@ void ServiceWorkerURLRequestJob::StartRequest() { |
case FORWARD_TO_SERVICE_WORKER: |
DCHECK(provider_host_ && provider_host_->active_version()); |
DCHECK(!fetch_dispatcher_); |
- |
// Send a fetch event to the ServiceWorker associated to the |
// provider_host. |
fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( |
- request(), provider_host_->active_version(), |
+ CreateFetchRequest(), |
+ provider_host_->active_version(), |
base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, |
weak_factory_.GetWeakPtr()))); |
fetch_dispatcher_->Run(); |
@@ -230,6 +238,90 @@ void ServiceWorkerURLRequestJob::StartRequest() { |
NOTREACHED(); |
} |
+scoped_ptr<ServiceWorkerFetchRequest> |
+ServiceWorkerURLRequestJob::CreateFetchRequest() { |
+ std::string blob_uuid; |
+ uint64 blob_size = 0; |
+ CreateRequestBodyBlob(&blob_uuid, &blob_size); |
+ scoped_ptr<ServiceWorkerFetchRequest> request( |
+ new ServiceWorkerFetchRequest()); |
+ |
+ request->url = request_->url(); |
+ request->method = request_->method(); |
+ const net::HttpRequestHeaders& headers = request_->extra_request_headers(); |
+ for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) |
+ request->headers[it.name()] = it.value(); |
+ request->blob_uuid = blob_uuid; |
+ request->blob_size = blob_size; |
+ request->referrer = GURL(request_->referrer()); |
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); |
+ if (info) { |
+ request->is_reload = PageTransitionCoreTypeIs(info->GetPageTransition(), |
+ PAGE_TRANSITION_RELOAD); |
+ } |
+ return request.Pass(); |
+} |
+ |
+bool ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid, |
+ uint64* blob_size) { |
+ if (!body_ || !blob_storage_context_) |
+ return false; |
+ const std::string uuid(base::GenerateGUID()); |
+ uint64 size = 0; |
+ std::vector<const ResourceRequestBody::Element*> resolved_elements; |
+ for (size_t i = 0; i < body_->elements()->size(); ++i) { |
+ const ResourceRequestBody::Element& element = (*body_->elements())[i]; |
+ if (element.type() != ResourceRequestBody::Element::TYPE_BLOB) { |
+ resolved_elements.push_back(&element); |
+ continue; |
+ } |
+ scoped_ptr<webkit_blob::BlobDataHandle> handle = |
+ blob_storage_context_->GetBlobDataFromUUID(element.blob_uuid()); |
+ if (handle->data()->items().empty()) |
+ continue; |
+ for (size_t i = 0; i < handle->data()->items().size(); ++i) { |
+ const webkit_blob::BlobData::Item& item = handle->data()->items().at(i); |
+ DCHECK_NE(webkit_blob::BlobData::Item::TYPE_BLOB, item.type()); |
+ resolved_elements.push_back(&item); |
+ } |
+ } |
+ scoped_refptr<webkit_blob::BlobData> blob_data = |
+ new webkit_blob::BlobData(uuid); |
+ for (size_t i = 0; i < resolved_elements.size(); ++i) { |
+ const ResourceRequestBody::Element& element = *resolved_elements[i]; |
+ size += element.length(); |
+ switch (element.type()) { |
+ case ResourceRequestBody::Element::TYPE_BYTES: |
+ blob_data->AppendData(element.bytes(), element.length()); |
+ break; |
+ case ResourceRequestBody::Element::TYPE_FILE: |
+ blob_data->AppendFile(element.path(), |
+ element.offset(), |
+ element.length(), |
+ element.expected_modification_time()); |
+ break; |
+ case ResourceRequestBody::Element::TYPE_BLOB: |
+ // Blob elements should be resolved beforehand. |
+ NOTREACHED(); |
+ break; |
+ case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM: |
+ blob_data->AppendFileSystemFile(element.filesystem_url(), |
+ element.offset(), |
+ element.length(), |
+ element.expected_modification_time()); |
+ break; |
+ default: |
+ NOTIMPLEMENTED(); |
+ } |
+ } |
+ |
+ request_body_blob_data_handle_ = |
+ blob_storage_context_->AddFinishedBlob(blob_data.get()); |
+ *blob_uuid = uuid; |
+ *blob_size = size; |
+ return true; |
+} |
+ |
void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( |
ServiceWorkerStatusCode status, |
ServiceWorkerFetchEventResult fetch_result, |