Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/service_worker/service_worker_controllee_url_loader_fa ctory.h" | |
| 6 | |
| 7 #include "content/common/service_worker/service_worker_utils.h" | |
| 8 #include "content/public/browser/browser_thread.h" | |
| 9 #include "mojo/public/cpp/system/data_pipe.h" | |
| 10 #include "net/base/io_buffer.h" | |
| 11 #include "storage/browser/blob/blob_data_handle.h" | |
| 12 #include "storage/browser/blob/blob_storage_context.h" | |
| 13 | |
| 14 namespace content { | |
| 15 | |
| 16 void ServiceWorkerControlleeURLLoaderFactory::CreateLoaderAndStart( | |
| 17 mojom::URLLoaderAssociatedRequest request, | |
| 18 int32_t routing_id, | |
| 19 int32_t request_id, | |
| 20 uint32_t options, | |
| 21 const ResourceRequest& url_request, | |
| 22 mojom::URLLoaderClientPtr client) { | |
| 23 request_ = std::move(request); | |
| 24 url_request_ = std::move(url_request); | |
| 25 client_ = std::move(client); | |
| 26 } | |
| 27 | |
| 28 ServiceWorkerControlleeURLLoaderFactory:: | |
| 29 ~ServiceWorkerControlleeURLLoaderFactory() {} | |
| 30 | |
| 31 void ServiceWorkerControlleeURLLoaderFactory::SyncLoad( | |
| 32 int32_t routing_id, | |
| 33 int32_t request_id, | |
| 34 const ResourceRequest& request, | |
| 35 SyncLoadCallback callback) { | |
| 36 NOTREACHED(); | |
| 37 } | |
| 38 | |
| 39 void ServiceWorkerControlleeURLLoaderFactory::FallbackToNetwork() { | |
| 40 DCHECK_EQ(ResponseType::kNotDetermined, response_type_); | |
| 41 response_type_ = ResponseType::kFallbackToNetwork; | |
| 42 StartRequest(); | |
| 43 } | |
| 44 | |
| 45 bool ServiceWorkerControlleeURLLoaderFactory::ShouldFallbackToNetwork() { | |
| 46 return response_type_ == ResponseType::kFallbackToNetwork; | |
| 47 } | |
| 48 | |
| 49 ui::PageTransition | |
| 50 ServiceWorkerControlleeURLLoaderFactory::GetPageTransition() { | |
| 51 NOTIMPLEMENTED() << __FUNCTION__; | |
| 52 return ui::PAGE_TRANSITION_LINK; | |
| 53 } | |
| 54 | |
| 55 size_t ServiceWorkerControlleeURLLoaderFactory::GetURLChainSize() { | |
| 56 NOTIMPLEMENTED() << __FUNCTION__; | |
| 57 return 0; | |
| 58 } | |
| 59 | |
| 60 void ServiceWorkerControlleeURLLoaderFactory::ForwardToServiceWorker() { | |
| 61 DCHECK_EQ(ResponseType::kNotDetermined, response_type_); | |
| 62 response_type_ = ResponseType::kForwardToServiceWorker; | |
| 63 StartRequest(); | |
| 64 } | |
| 65 | |
| 66 void ServiceWorkerControlleeURLLoaderFactory::FallbackToNetworkOrRenderer() { | |
| 67 NOTIMPLEMENTED() << __FUNCTION__; | |
| 68 } | |
| 69 | |
| 70 void ServiceWorkerControlleeURLLoaderFactory::FailToNetworkOrRenderer() { | |
| 71 NOTIMPLEMENTED() << __FUNCTION__; | |
| 72 } | |
| 73 | |
| 74 void ServiceWorkerControlleeURLLoaderFactory::FailDueToLostController() { | |
| 75 NOTIMPLEMENTED() << __FUNCTION__; | |
| 76 } | |
| 77 | |
| 78 bool ServiceWorkerControlleeURLLoaderFactory::WasCanceled() const { | |
| 79 NOTIMPLEMENTED() << __FUNCTION__; | |
| 80 return false; | |
| 81 } | |
| 82 | |
| 83 std::unique_ptr<ServiceWorkerFetchRequest> | |
| 84 ServiceWorkerControlleeURLLoaderFactory::CreateFetchRequest() { | |
| 85 std::string blob_uuid; | |
| 86 uint64_t blob_size = 0; | |
| 87 #if 0 // TODO(scottmg): | |
| 88 if (HasRequestBody()) | |
| 89 CreateRequestBodyBlob(&blob_uuid, &blob_size); | |
| 90 #endif | |
| 91 std::unique_ptr<ServiceWorkerFetchRequest> request( | |
| 92 new ServiceWorkerFetchRequest()); | |
| 93 request->mode = request_mode_; | |
| 94 request->is_main_resource_load = | |
| 95 ServiceWorkerUtils::IsMainResourceType(resource_type_); | |
| 96 request->request_context_type = request_context_type_; | |
| 97 request->frame_type = frame_type_; | |
| 98 request->url = url_request_.url; | |
| 99 request->method = url_request_.method; | |
| 100 #if 0 // TODO(scottmg): | |
| 101 const net::HttpRequestHeaders& headers = request_->extra_request_headers(); | |
| 102 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) { | |
| 103 if (ServiceWorkerContext::IsExcludedHeaderNameForFetchEvent(it.name())) | |
| 104 continue; | |
| 105 request->headers[it.name()] = it.value(); | |
| 106 } | |
| 107 #endif | |
| 108 request->blob_uuid = blob_uuid; | |
| 109 request->blob_size = blob_size; | |
| 110 request->credentials_mode = credentials_mode_; | |
| 111 request->redirect_mode = redirect_mode_; | |
| 112 request->client_id = client_id_; | |
| 113 #if 0 // TODO(scottmg): | |
| 114 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); | |
| 115 if (info) { | |
| 116 request->is_reload = ui::PageTransitionCoreTypeIs( | |
| 117 info->GetPageTransition(), ui::PAGE_TRANSITION_RELOAD); | |
| 118 request->referrer = | |
| 119 Referrer(GURL(request_->referrer()), info->GetReferrerPolicy()); | |
| 120 } else { | |
| 121 CHECK( | |
| 122 request_->referrer_policy() == | |
| 123 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE); | |
| 124 request->referrer = | |
| 125 Referrer(GURL(request_->referrer()), blink::kWebReferrerPolicyDefault); | |
| 126 } | |
| 127 #endif | |
| 128 request->fetch_type = fetch_type_; | |
| 129 return request; | |
| 130 } | |
| 131 | |
| 132 void ServiceWorkerControlleeURLLoaderFactory::StartRequest() { | |
| 133 if (response_type_ != ResponseType::kForwardToServiceWorker) { | |
| 134 NOTIMPLEMENTED() << " Unexpected response type!"; | |
| 135 return; | |
| 136 } | |
| 137 DCHECK(!fetch_dispatcher_); | |
| 138 ServiceWorkerMetrics::URLRequestJobResult result = | |
| 139 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE; | |
| 140 ServiceWorkerVersion* active_worker = | |
| 141 delegate_->GetServiceWorkerVersion(&result); | |
| 142 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( | |
| 143 CreateFetchRequest(), active_worker, resource_type_, timeout_, | |
| 144 net::NetLogWithSource() /* TODO(scottmg): net log */, | |
| 145 base::Bind(&ServiceWorkerControlleeURLLoaderFactory::DidPrepareFetchEvent, | |
| 146 weak_factory_.GetWeakPtr(), active_worker), | |
| 147 base::Bind( | |
| 148 &ServiceWorkerControlleeURLLoaderFactory::DidDispatchFetchEvent, | |
| 149 weak_factory_.GetWeakPtr()))); | |
| 150 fetch_dispatcher_->Run(); | |
| 151 } | |
| 152 | |
| 153 void ServiceWorkerControlleeURLLoaderFactory::DidPrepareFetchEvent( | |
| 154 scoped_refptr<ServiceWorkerVersion> version) {} | |
| 155 | |
| 156 void ServiceWorkerControlleeURLLoaderFactory::DidDispatchFetchEvent( | |
| 157 ServiceWorkerStatusCode status, | |
| 158 ServiceWorkerFetchEventResult fetch_result, | |
| 159 const ServiceWorkerResponse& response, | |
| 160 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream, | |
| 161 const scoped_refptr<ServiceWorkerVersion>& version) { | |
| 162 ResourceResponseHead head; | |
| 163 // TODO(scottmg): More stuff copied over. | |
| 164 head.headers = new net::HttpResponseHeaders(""); | |
| 165 for (const auto& kv : response.headers) | |
| 166 head.headers->AddHeader(kv.first + ": " + kv.second); | |
| 167 head.url_list_via_service_worker = response.url_list; | |
| 168 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this. | |
| 169 head.was_fetched_via_service_worker = true; | |
| 170 head.cors_exposed_header_names = response.cors_exposed_header_names; | |
| 171 client_->OnReceiveResponse(head, base::nullopt /* TODO(scottmg): ssl info */, | |
| 172 mojom::DownloadedTempFilePtr()); | |
| 173 | |
| 174 // TODO(scottmg): We'd prefer this! But for now we we have to use the blob as | |
| 175 // SWFetchDispatcher only offers blobs for normal fetches. | |
| 176 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5yy Ljfld0KvKchVfA84Y/edit?usp=drive_web | |
| 177 DCHECK(body_as_stream.is_null()); | |
|
falken
2017/05/08 08:20:33
I'm not sure I understand the "SWFetchDispatcher o
scottmg
2017/05/08 20:12:31
Oh, ok, thanks. This was just my ignorance. I only
falken
2017/05/09 08:20:15
Yea if I understand what Blob Servicification mean
| |
| 178 | |
| 179 // TODO(scottmg): This is temporary hacky code to load the blob right here and | |
| 180 // turn it into a data pipe to respond with. | |
| 181 if (!response.blob_uuid.empty() && blob_storage_context_) { | |
| 182 std::unique_ptr<storage::BlobDataHandle> blob_data_handle = | |
| 183 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); | |
| 184 blob_reader_ = blob_data_handle->CreateReader( | |
| 185 nullptr /* file system context */, | |
| 186 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()); | |
| 187 CHECK(storage::BlobReader::Status::DONE == | |
| 188 blob_reader_->CalculateSize(net::CompletionCallback())); | |
| 189 blob_reader_->SetReadRange(0, blob_reader_->total_size()); | |
| 190 scoped_refptr<net::IOBuffer> buffer( | |
| 191 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size()))); | |
| 192 | |
| 193 int bytes_read; | |
| 194 auto status = blob_reader_->Read( | |
| 195 buffer.get(), blob_reader_->total_size(), &bytes_read, | |
| 196 base::Bind(&ServiceWorkerControlleeURLLoaderFactory::AfterRead, | |
| 197 weak_factory_.GetWeakPtr(), buffer)); | |
| 198 LOG(ERROR) << (int)status; | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 void ServiceWorkerControlleeURLLoaderFactory::AfterRead( | |
| 203 scoped_refptr<net::IOBuffer> buffer, | |
| 204 int bytes) { | |
| 205 uint32_t bytes_written = static_cast<uint32_t>(bytes); | |
| 206 MojoResult result = | |
| 207 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(), | |
| 208 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE); | |
| 209 LOG(ERROR) << (int)result; | |
| 210 client_->OnStartLoadingResponseBody(std::move(data_pipe_.consumer_handle)); | |
| 211 } | |
| 212 | |
| 213 } // namespace content | |
| OLD | NEW |