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

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

Issue 759203002: [ServiceWorker] Make Stream support in ServiceWorkerURLRequestJob (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_url_request_job.h" 5 #include "content/browser/service_worker/service_worker_url_request_job.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/guid.h" 12 #include "base/guid.h"
13 #include "base/profiler/scoped_tracker.h" 13 #include "base/profiler/scoped_tracker.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "content/browser/resource_context_impl.h"
16 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" 17 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
17 #include "content/browser/service_worker/service_worker_provider_host.h" 18 #include "content/browser/service_worker/service_worker_provider_host.h"
19 #include "content/browser/streams/stream.h"
20 #include "content/browser/streams/stream_context.h"
21 #include "content/browser/streams/stream_registry.h"
18 #include "content/common/resource_request_body.h" 22 #include "content/common/resource_request_body.h"
19 #include "content/common/service_worker/service_worker_types.h" 23 #include "content/common/service_worker/service_worker_types.h"
20 #include "content/public/browser/blob_handle.h" 24 #include "content/public/browser/blob_handle.h"
21 #include "content/public/browser/resource_request_info.h" 25 #include "content/public/browser/resource_request_info.h"
22 #include "content/public/browser/service_worker_context.h" 26 #include "content/public/browser/service_worker_context.h"
23 #include "net/base/net_errors.h" 27 #include "net/base/net_errors.h"
24 #include "net/http/http_request_headers.h" 28 #include "net/http/http_request_headers.h"
25 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
26 #include "net/http/http_response_info.h" 30 #include "net/http/http_response_info.h"
27 #include "net/http/http_util.h" 31 #include "net/http/http_util.h"
28 #include "storage/browser/blob/blob_data_handle.h" 32 #include "storage/browser/blob/blob_data_handle.h"
29 #include "storage/browser/blob/blob_storage_context.h" 33 #include "storage/browser/blob/blob_storage_context.h"
30 #include "storage/browser/blob/blob_url_request_job_factory.h" 34 #include "storage/browser/blob/blob_url_request_job_factory.h"
31 #include "ui/base/page_transition_types.h" 35 #include "ui/base/page_transition_types.h"
32 36
33 namespace content { 37 namespace content {
34 38
35 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( 39 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
36 net::URLRequest* request, 40 net::URLRequest* request,
37 net::NetworkDelegate* network_delegate, 41 net::NetworkDelegate* network_delegate,
38 base::WeakPtr<ServiceWorkerProviderHost> provider_host, 42 base::WeakPtr<ServiceWorkerProviderHost> provider_host,
39 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, 43 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
44 const ResourceContext* resource_context,
40 FetchRequestMode request_mode, 45 FetchRequestMode request_mode,
41 FetchCredentialsMode credentials_mode, 46 FetchCredentialsMode credentials_mode,
42 RequestContextType request_context_type, 47 RequestContextType request_context_type,
43 RequestContextFrameType frame_type, 48 RequestContextFrameType frame_type,
44 scoped_refptr<ResourceRequestBody> body) 49 scoped_refptr<ResourceRequestBody> body)
45 : net::URLRequestJob(request, network_delegate), 50 : net::URLRequestJob(request, network_delegate),
46 provider_host_(provider_host), 51 provider_host_(provider_host),
47 response_type_(NOT_DETERMINED), 52 response_type_(NOT_DETERMINED),
48 is_started_(false), 53 is_started_(false),
49 service_worker_response_type_(blink::WebServiceWorkerResponseTypeDefault), 54 service_worker_response_type_(blink::WebServiceWorkerResponseTypeDefault),
50 blob_storage_context_(blob_storage_context), 55 blob_storage_context_(blob_storage_context),
56 resource_context_(resource_context),
57 stream_pending_buffer_size_(0),
58 stream_total_bytes_read_(0),
59 stream_max_range_(0),
51 request_mode_(request_mode), 60 request_mode_(request_mode),
52 credentials_mode_(credentials_mode), 61 credentials_mode_(credentials_mode),
53 request_context_type_(request_context_type), 62 request_context_type_(request_context_type),
54 frame_type_(frame_type), 63 frame_type_(frame_type),
55 fall_back_required_(false), 64 fall_back_required_(false),
56 body_(body), 65 body_(body),
57 weak_factory_(this) { 66 weak_factory_(this) {
58 } 67 }
59 68
60 void ServiceWorkerURLRequestJob::FallbackToNetwork() { 69 void ServiceWorkerURLRequestJob::FallbackToNetwork() {
61 DCHECK_EQ(NOT_DETERMINED, response_type_); 70 DCHECK_EQ(NOT_DETERMINED, response_type_);
62 response_type_ = FALLBACK_TO_NETWORK; 71 response_type_ = FALLBACK_TO_NETWORK;
63 MaybeStartRequest(); 72 MaybeStartRequest();
64 } 73 }
65 74
66 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { 75 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() {
67 DCHECK_EQ(NOT_DETERMINED, response_type_); 76 DCHECK_EQ(NOT_DETERMINED, response_type_);
68 response_type_ = FORWARD_TO_SERVICE_WORKER; 77 response_type_ = FORWARD_TO_SERVICE_WORKER;
69 MaybeStartRequest(); 78 MaybeStartRequest();
70 } 79 }
71 80
72 void ServiceWorkerURLRequestJob::Start() { 81 void ServiceWorkerURLRequestJob::Start() {
73 is_started_ = true; 82 is_started_ = true;
74 MaybeStartRequest(); 83 MaybeStartRequest();
75 } 84 }
76 85
77 void ServiceWorkerURLRequestJob::Kill() { 86 void ServiceWorkerURLRequestJob::Kill() {
78 net::URLRequestJob::Kill(); 87 net::URLRequestJob::Kill();
88 if (stream_.get()) {
89 stream_->RemoveReadObserver(this);
90 stream_->Abort();
91 stream_ = nullptr;
92 }
93 if (!waiting_stream_url_.is_empty()) {
94 StreamRegistry* stream_registry =
95 GetStreamContextForResourceContext(resource_context_)->registry();
96 stream_registry->RemoveRegisterObserver(waiting_stream_url_);
97 stream_registry->NotifyReaderAbortedBeforeRegistration(waiting_stream_url_);
98 }
79 fetch_dispatcher_.reset(); 99 fetch_dispatcher_.reset();
80 blob_request_.reset(); 100 blob_request_.reset();
81 weak_factory_.InvalidateWeakPtrs(); 101 weak_factory_.InvalidateWeakPtrs();
82 } 102 }
83 103
84 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { 104 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const {
85 // TODO(kinuko): refine this for better debug. 105 // TODO(kinuko): refine this for better debug.
86 return net::URLRequestJob::GetLoadState(); 106 return net::URLRequestJob::GetLoadState();
87 } 107 }
88 108
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { 144 !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
125 return; 145 return;
126 } 146 }
127 147
128 // We don't support multiple range requests in one single URL request. 148 // We don't support multiple range requests in one single URL request.
129 if (ranges.size() == 1U) 149 if (ranges.size() == 1U)
130 byte_range_ = ranges[0]; 150 byte_range_ = ranges[0];
131 } 151 }
132 152
133 bool ServiceWorkerURLRequestJob::ReadRawData( 153 bool ServiceWorkerURLRequestJob::ReadRawData(
134 net::IOBuffer* buf, int buf_size, int *bytes_read) { 154 net::IOBuffer* buf, int buf_size, int *bytes_read) {
nhiroki 2014/11/27 05:03:25 DCHECK_GE(buf_size, 0)?
horo 2014/11/27 06:52:49 Done.
155 if (stream_.get()) {
156 DCHECK(buf);
157 DCHECK(bytes_read);
nhiroki 2014/11/27 05:03:25 Can you move these checks into the beginning of th
horo 2014/11/27 06:52:49 Done.
158 int to_read = buf_size;
159 if (stream_max_range_ && to_read) {
160 if (to_read + stream_total_bytes_read_ > stream_max_range_)
161 to_read = stream_max_range_ - stream_total_bytes_read_;
162
163 if (to_read <= 0) {
nhiroki 2014/11/27 05:03:25 "to_read < 0" seems a bug because... 1) |buf_size
horo 2014/11/27 06:52:49 We don't need stream_total_bytes_read_ nor stream_
164 *bytes_read = 0;
165 return true;
166 }
167 }
168
169 switch (stream_->ReadRawData(buf, to_read, bytes_read)) {
170 case Stream::STREAM_HAS_DATA:
nhiroki 2014/11/27 05:03:25 "DCHECK_GT(bytes_read, 0)" like line 276?
horo 2014/11/27 06:52:49 Done.
171 case Stream::STREAM_COMPLETE:
172 stream_total_bytes_read_ += *bytes_read;
173 return true;
174 case Stream::STREAM_EMPTY:
175 stream_pending_buffer_ = buf;
176 stream_pending_buffer_size_ = to_read;
177 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
178 return false;
179 case Stream::STREAM_ABORTED:
180 // Handle this as connection reset.
181 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
182 net::ERR_CONNECTION_RESET));
183 return false;
184 }
185 NOTREACHED();
186 return false;
187 }
135 if (!blob_request_) { 188 if (!blob_request_) {
136 *bytes_read = 0; 189 *bytes_read = 0;
137 return true; 190 return true;
138 } 191 }
139 192
140 blob_request_->Read(buf, buf_size, bytes_read); 193 blob_request_->Read(buf, buf_size, bytes_read);
141 net::URLRequestStatus status = blob_request_->status(); 194 net::URLRequestStatus status = blob_request_->status();
142 SetStatus(status); 195 SetStatus(status);
143 if (status.is_io_pending()) 196 if (status.is_io_pending())
144 return false; 197 return false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 SetStatus(request->status()); 251 SetStatus(request->status());
199 if (!request->status().is_success()) { 252 if (!request->status().is_success()) {
200 NotifyDone(request->status()); 253 NotifyDone(request->status());
201 return; 254 return;
202 } 255 }
203 NotifyReadComplete(bytes_read); 256 NotifyReadComplete(bytes_read);
204 if (bytes_read == 0) 257 if (bytes_read == 0)
205 NotifyDone(request->status()); 258 NotifyDone(request->status());
206 } 259 }
207 260
261 void ServiceWorkerURLRequestJob::OnDataAvailable(Stream* stream) {
262 // Clear the IO_PENDING status.
263 SetStatus(net::URLRequestStatus());
264 // Do nothing if pending_buffer_ is empty, i.e. there's no ReadRawData()
265 // operation waiting for IO completion.
266 if (!stream_pending_buffer_.get())
267 return;
268
269 // pending_buffer_ is set to the IOBuffer instance provided to ReadRawData()
270 // by URLRequestJob.
271
272 int bytes_read;
273 switch (stream_->ReadRawData(
274 stream_pending_buffer_.get(), stream_pending_buffer_size_, &bytes_read)) {
275 case Stream::STREAM_HAS_DATA:
276 DCHECK_GT(bytes_read, 0);
277 break;
278 case Stream::STREAM_COMPLETE:
279 // Ensure this. Calling NotifyReadComplete call with 0 signals
280 // completion.
281 bytes_read = 0;
nhiroki 2014/11/27 05:03:25 This looks odd... at line 298 |stream_total_bytes_
horo 2014/11/27 06:52:50 I think checking bytes_read == 0 is enough.
282 break;
283 case Stream::STREAM_EMPTY:
284 NOTREACHED();
285 break;
286 case Stream::STREAM_ABORTED:
287 // Handle this as connection reset.
288 NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED,
289 net::ERR_CONNECTION_RESET));
290 break;
291 }
292
293 // Clear the buffers before notifying the read is complete, so that it is
294 // safe for the observer to read.
295 stream_pending_buffer_ = NULL;
nhiroki 2014/11/27 05:03:25 nullptr?
horo 2014/11/27 06:52:49 Done.
296 stream_pending_buffer_size_ = 0;
297
298 stream_total_bytes_read_ += bytes_read;
299 NotifyReadComplete(bytes_read);
300 }
301
302 void ServiceWorkerURLRequestJob::OnStreamRegistered(Stream* stream) {
303 StreamContext* stream_context =
304 GetStreamContextForResourceContext(resource_context_);
305 stream_context->registry()->RemoveRegisterObserver(waiting_stream_url_);
306 waiting_stream_url_ = GURL();
307 stream_ = stream;
308 stream_->SetReadObserver(this);
309 CommitResponseHeader();
310 }
311
208 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { 312 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
209 if (!http_response_info_) 313 if (!http_response_info_)
210 return NULL; 314 return NULL;
211 if (range_response_info_) 315 if (range_response_info_)
212 return range_response_info_.get(); 316 return range_response_info_.get();
213 return http_response_info_.get(); 317 return http_response_info_.get();
214 } 318 }
215 319
216 void ServiceWorkerURLRequestJob::GetExtraResponseInfo( 320 void ServiceWorkerURLRequestJob::GetExtraResponseInfo(
217 bool* was_fetched_via_service_worker, 321 bool* was_fetched_via_service_worker,
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 // Treat a response whose status is 0 as a Network Error. 535 // Treat a response whose status is 0 as a Network Error.
432 if (response.status_code == 0) { 536 if (response.status_code == 0) {
433 NotifyDone( 537 NotifyDone(
434 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); 538 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED));
435 return; 539 return;
436 } 540 }
437 541
438 fetch_end_time_ = base::TimeTicks::Now(); 542 fetch_end_time_ = base::TimeTicks::Now();
439 load_timing_info_.send_end = fetch_end_time_; 543 load_timing_info_.send_end = fetch_end_time_;
440 544
545 // Set up a request for reading the stream.
546 if (response.stream_url.is_valid()) {
547 DCHECK(response.blob_uuid.empty());
548 response_url_ = response.url;
549 service_worker_response_type_ = response.response_type;
550 CreateResponseHeader(
551 response.status_code, response.status_text, response.headers);
552 load_timing_info_.receive_headers_end = base::TimeTicks::Now();
553 StreamContext* stream_context =
554 GetStreamContextForResourceContext(resource_context_);
555 stream_ =
556 stream_context->registry()->GetStream(response.stream_url);
557 if (!stream_.get()) {
558 waiting_stream_url_ = response.stream_url;
559 // Wait for StreamHostMsg_StartBuilding message from the ServieWorker.
560 stream_context->registry()->SetRegisterObserver(waiting_stream_url_,
561 this);
562 return;
563 }
564 stream_->SetReadObserver(this);
565 CommitResponseHeader();
566 return;
567 }
441 // Set up a request for reading the blob. 568 // Set up a request for reading the blob.
442 if (!response.blob_uuid.empty() && blob_storage_context_) { 569 if (!response.blob_uuid.empty() && blob_storage_context_) {
443 scoped_ptr<storage::BlobDataHandle> blob_data_handle = 570 scoped_ptr<storage::BlobDataHandle> blob_data_handle =
444 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); 571 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid);
445 if (!blob_data_handle) { 572 if (!blob_data_handle) {
446 // The renderer gave us a bad blob UUID. 573 // The renderer gave us a bad blob UUID.
447 DeliverErrorResponse(); 574 DeliverErrorResponse();
448 return; 575 return;
449 } 576 }
450 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( 577 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 618
492 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { 619 void ServiceWorkerURLRequestJob::DeliverErrorResponse() {
493 // TODO(falken): Print an error to the console of the ServiceWorker and of 620 // TODO(falken): Print an error to the console of the ServiceWorker and of
494 // the requesting page. 621 // the requesting page.
495 CreateResponseHeader( 622 CreateResponseHeader(
496 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); 623 500, "Service Worker Response Error", ServiceWorkerHeaderMap());
497 CommitResponseHeader(); 624 CommitResponseHeader();
498 } 625 }
499 626
500 } // namespace content 627 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698