Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: content/browser/service_worker/service_worker_controllee_url_loader_factory.cc

Issue 2843043002: network service: Create URLLoader for service worker navigation case
Patch Set: fix rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 LOG(ERROR) << "URL: " << url_request.url;
24 request_ = std::move(request);
25 url_request_ = std::move(url_request);
26 client_ = std::move(client);
27 // TODO(scottmg): This factory currently only handles one request due to the
28 // way it's hooked up for navigation and with ServiceWorkerStorage. It should
29 // probably delegate all its work to a URLLoaderImpl that's created here, but
30 // that's not done yet to keep things a bit simpler for now.
kinuko 2017/05/09 14:45:25 Maybe the main work should be done by URLLoader im
scottmg 2017/05/09 22:14:10 Yeah, agreed. It just adds even more boilerplate,
31 }
32
33 ServiceWorkerControlleeURLLoaderFactory::
34 ~ServiceWorkerControlleeURLLoaderFactory() {}
35
36 void ServiceWorkerControlleeURLLoaderFactory::SyncLoad(
37 int32_t routing_id,
38 int32_t request_id,
39 const ResourceRequest& request,
40 SyncLoadCallback callback) {
41 NOTREACHED();
42 }
43
44 void ServiceWorkerControlleeURLLoaderFactory::FallbackToNetwork() {
45 DCHECK_EQ(ResponseType::kNotDetermined, response_type_);
46 response_type_ = ResponseType::kFallbackToNetwork;
47 StartRequest();
48 }
49
50 bool ServiceWorkerControlleeURLLoaderFactory::ShouldFallbackToNetwork() {
51 return response_type_ == ResponseType::kFallbackToNetwork;
52 }
53
54 ui::PageTransition
55 ServiceWorkerControlleeURLLoaderFactory::GetPageTransition() {
56 NOTIMPLEMENTED() << __FUNCTION__;
57 return ui::PAGE_TRANSITION_LINK;
58 }
59
60 size_t ServiceWorkerControlleeURLLoaderFactory::GetURLChainSize() {
61 NOTIMPLEMENTED() << __FUNCTION__;
62 return 0;
63 }
64
65 void ServiceWorkerControlleeURLLoaderFactory::ForwardToServiceWorker() {
66 DCHECK_EQ(ResponseType::kNotDetermined, response_type_);
67 response_type_ = ResponseType::kForwardToServiceWorker;
68 StartRequest();
69 }
70
71 void ServiceWorkerControlleeURLLoaderFactory::FallbackToNetworkOrRenderer() {
72 NOTIMPLEMENTED() << __FUNCTION__;
73 }
74
75 void ServiceWorkerControlleeURLLoaderFactory::FailToNetworkOrRenderer() {
76 NOTIMPLEMENTED() << __FUNCTION__;
77 }
78
79 void ServiceWorkerControlleeURLLoaderFactory::FailDueToLostController() {
80 NOTIMPLEMENTED() << __FUNCTION__;
81 }
82
83 bool ServiceWorkerControlleeURLLoaderFactory::WasCanceled() const {
84 NOTIMPLEMENTED() << __FUNCTION__;
85 return false;
86 }
87
88 std::unique_ptr<ServiceWorkerFetchRequest>
89 ServiceWorkerControlleeURLLoaderFactory::CreateFetchRequest() {
90 std::string blob_uuid;
91 uint64_t blob_size = 0;
92 #if 0 // TODO(scottmg):
93 if (HasRequestBody())
94 CreateRequestBodyBlob(&blob_uuid, &blob_size);
95 #endif
96 std::unique_ptr<ServiceWorkerFetchRequest> request(
97 new ServiceWorkerFetchRequest());
98 request->mode = request_mode_;
99 request->is_main_resource_load =
100 ServiceWorkerUtils::IsMainResourceType(resource_type_);
101 request->request_context_type = request_context_type_;
102 request->frame_type = frame_type_;
103 request->url = url_request_.url;
104 request->method = url_request_.method;
105 #if 0 // TODO(scottmg):
106 const net::HttpRequestHeaders& headers = request_->extra_request_headers();
107 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) {
108 if (ServiceWorkerContext::IsExcludedHeaderNameForFetchEvent(it.name()))
109 continue;
110 request->headers[it.name()] = it.value();
111 }
112 #endif
113 request->blob_uuid = blob_uuid;
114 request->blob_size = blob_size;
115 request->credentials_mode = credentials_mode_;
116 request->redirect_mode = redirect_mode_;
117 request->client_id = client_id_;
118 #if 0 // TODO(scottmg):
119 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
120 if (info) {
121 request->is_reload = ui::PageTransitionCoreTypeIs(
122 info->GetPageTransition(), ui::PAGE_TRANSITION_RELOAD);
123 request->referrer =
124 Referrer(GURL(request_->referrer()), info->GetReferrerPolicy());
125 } else {
126 CHECK(
127 request_->referrer_policy() ==
128 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE);
129 request->referrer =
130 Referrer(GURL(request_->referrer()), blink::kWebReferrerPolicyDefault);
131 }
132 #endif
133 request->fetch_type = fetch_type_;
134 return request;
135 }
136
137 void ServiceWorkerControlleeURLLoaderFactory::StartRequest() {
138 if (response_type_ == ResponseType::kFallbackToNetwork) {
139 // Need to restart the request, and send it through the network.
140 BrowserThread::PostTask(
141 BrowserThread::UI, FROM_HERE,
142 base::Bind(network_fallback_callback_,
143 base::Passed(std::move(
144 base::MakeUnique<ResourceRequest>(url_request_)))));
145 return;
146 }
147 if (response_type_ != ResponseType::kForwardToServiceWorker) {
148 NOTIMPLEMENTED() << " Unexpected response type!";
149 return;
150 }
151 DCHECK(!fetch_dispatcher_);
152 ServiceWorkerMetrics::URLRequestJobResult result =
153 ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
154 ServiceWorkerVersion* active_worker =
155 delegate_->GetServiceWorkerVersion(&result);
156 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
157 CreateFetchRequest(), active_worker, resource_type_, timeout_,
158 net::NetLogWithSource() /* TODO(scottmg): net log */,
159 base::Bind(&ServiceWorkerControlleeURLLoaderFactory::DidPrepareFetchEvent,
160 weak_factory_.GetWeakPtr(), active_worker),
161 base::Bind(
162 &ServiceWorkerControlleeURLLoaderFactory::DidDispatchFetchEvent,
163 weak_factory_.GetWeakPtr())));
164 fetch_dispatcher_->Run();
165 }
166
167 void ServiceWorkerControlleeURLLoaderFactory::DidPrepareFetchEvent(
168 scoped_refptr<ServiceWorkerVersion> version) {}
169
170 void ServiceWorkerControlleeURLLoaderFactory::DidDispatchFetchEvent(
171 ServiceWorkerStatusCode status,
172 ServiceWorkerFetchEventResult fetch_result,
173 const ServiceWorkerResponse& response,
174 blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
175 const scoped_refptr<ServiceWorkerVersion>& version) {
176 ResourceResponseHead head;
177 // TODO(scottmg): More stuff copied over.
178 head.headers = new net::HttpResponseHeaders("");
179 for (const auto& kv : response.headers)
180 head.headers->AddHeader(kv.first + ": " + kv.second);
181 head.url_list_via_service_worker = response.url_list;
182 head.mime_type = "text/html"; // TODO(scottmg): No idea where to get this.
183 head.was_fetched_via_service_worker = true;
184 head.cors_exposed_header_names = response.cors_exposed_header_names;
185 client_->OnReceiveResponse(head, base::nullopt /* TODO(scottmg): ssl info */,
186 mojom::DownloadedTempFilePtr());
187
188 // Ideally, we would always get a data pipe fom SWFetchDispatcher and use this
189 // case. See:
190 // https://docs.google.com/a/google.com/document/d/1_ROmusFvd8ATwIZa29-P6Ls5yy Ljfld0KvKchVfA84Y/edit?usp=drive_web
191 if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
192 client_->OnStartLoadingResponseBody(std::move(body_as_stream->stream));
193 } else {
194 // TODO(scottmg): This is temporary hacky to load the blob right here and
195 // turn it into a data pipe to respond with, until we are always able to
196 // take the above path.
197 if (!response.blob_uuid.empty() && blob_storage_context_) {
198 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
199 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
200 blob_reader_ = blob_data_handle->CreateReader(
201 nullptr /* file system context */,
202 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
203 CHECK(storage::BlobReader::Status::DONE ==
204 blob_reader_->CalculateSize(net::CompletionCallback()));
205 blob_reader_->SetReadRange(0, blob_reader_->total_size());
206 scoped_refptr<net::IOBuffer> buffer(
207 new net::IOBuffer(static_cast<size_t>(blob_reader_->total_size())));
208
209 int bytes_read;
210 blob_reader_->Read(
211 buffer.get(), blob_reader_->total_size(), &bytes_read,
212 base::Bind(&ServiceWorkerControlleeURLLoaderFactory::AfterRead,
213 weak_factory_.GetWeakPtr(), buffer));
214 }
215 }
216 }
217
218 void ServiceWorkerControlleeURLLoaderFactory::AfterRead(
219 scoped_refptr<net::IOBuffer> buffer,
220 int bytes) {
221 uint32_t bytes_written = static_cast<uint32_t>(bytes);
222 mojo::WriteDataRaw(data_pipe_.producer_handle.get(), buffer->data(),
223 &bytes_written, MOJO_WRITE_DATA_FLAG_NONE);
224 client_->OnStartLoadingResponseBody(std::move(data_pipe_.consumer_handle));
225 }
226
227 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698