Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/time/time.h" | |
| 14 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" | 15 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" |
| 15 #include "content/browser/service_worker/service_worker_provider_host.h" | 16 #include "content/browser/service_worker/service_worker_provider_host.h" |
| 16 #include "content/common/resource_request_body.h" | 17 #include "content/common/resource_request_body.h" |
| 17 #include "content/common/service_worker/service_worker_types.h" | 18 #include "content/common/service_worker/service_worker_types.h" |
| 18 #include "content/public/browser/blob_handle.h" | 19 #include "content/public/browser/blob_handle.h" |
| 19 #include "content/public/browser/resource_request_info.h" | 20 #include "content/public/browser/resource_request_info.h" |
| 20 #include "content/public/common/page_transition_types.h" | 21 #include "content/public/common/page_transition_types.h" |
| 21 #include "net/http/http_request_headers.h" | 22 #include "net/http/http_request_headers.h" |
| 22 #include "net/http/http_response_headers.h" | 23 #include "net/http/http_response_headers.h" |
| 23 #include "net/http/http_response_info.h" | 24 #include "net/http/http_response_info.h" |
| 24 #include "net/http/http_util.h" | 25 #include "net/http/http_util.h" |
| 25 #include "webkit/browser/blob/blob_data_handle.h" | 26 #include "webkit/browser/blob/blob_data_handle.h" |
| 26 #include "webkit/browser/blob/blob_storage_context.h" | 27 #include "webkit/browser/blob/blob_storage_context.h" |
| 27 #include "webkit/browser/blob/blob_url_request_job_factory.h" | 28 #include "webkit/browser/blob/blob_url_request_job_factory.h" |
| 28 | 29 |
| 30 using base::Time; | |
| 31 using base::TimeTicks; | |
| 32 | |
| 29 namespace content { | 33 namespace content { |
| 30 | 34 |
| 31 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( | 35 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( |
| 32 net::URLRequest* request, | 36 net::URLRequest* request, |
| 33 net::NetworkDelegate* network_delegate, | 37 net::NetworkDelegate* network_delegate, |
| 34 base::WeakPtr<ServiceWorkerProviderHost> provider_host, | 38 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
| 35 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 39 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
| 36 scoped_refptr<ResourceRequestBody> body) | 40 scoped_refptr<ResourceRequestBody> body) |
| 37 : net::URLRequestJob(request, network_delegate), | 41 : net::URLRequestJob(request, network_delegate), |
| 38 provider_host_(provider_host), | 42 provider_host_(provider_host), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const { | 85 bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const { |
| 82 if (!http_info()) | 86 if (!http_info()) |
| 83 return false; | 87 return false; |
| 84 return http_info()->headers->GetMimeType(mime_type); | 88 return http_info()->headers->GetMimeType(mime_type); |
| 85 } | 89 } |
| 86 | 90 |
| 87 void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { | 91 void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { |
| 88 if (!http_info()) | 92 if (!http_info()) |
| 89 return; | 93 return; |
| 90 *info = *http_info(); | 94 *info = *http_info(); |
| 95 info->response_time = response_time_; | |
| 96 } | |
| 97 | |
| 98 void ServiceWorkerURLRequestJob::GetLoadTimingInfo( | |
| 99 net::LoadTimingInfo* load_timing_info) const { | |
| 100 *load_timing_info = load_timing_info_; | |
| 91 } | 101 } |
| 92 | 102 |
| 93 int ServiceWorkerURLRequestJob::GetResponseCode() const { | 103 int ServiceWorkerURLRequestJob::GetResponseCode() const { |
| 94 if (!http_info()) | 104 if (!http_info()) |
| 95 return -1; | 105 return -1; |
| 96 return http_info()->headers->response_code(); | 106 return http_info()->headers->response_code(); |
| 97 } | 107 } |
| 98 | 108 |
| 99 void ServiceWorkerURLRequestJob::SetExtraRequestHeaders( | 109 void ServiceWorkerURLRequestJob::SetExtraRequestHeaders( |
| 100 const net::HttpRequestHeaders& headers) { | 110 const net::HttpRequestHeaders& headers) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 } | 162 } |
| 153 | 163 |
| 154 void ServiceWorkerURLRequestJob::OnBeforeNetworkStart(net::URLRequest* request, | 164 void ServiceWorkerURLRequestJob::OnBeforeNetworkStart(net::URLRequest* request, |
| 155 bool* defer) { | 165 bool* defer) { |
| 156 NOTREACHED(); | 166 NOTREACHED(); |
| 157 } | 167 } |
| 158 | 168 |
| 159 void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { | 169 void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { |
| 160 // TODO(falken): Add Content-Length, Content-Type if they were not provided in | 170 // TODO(falken): Add Content-Length, Content-Type if they were not provided in |
| 161 // the ServiceWorkerResponse. | 171 // the ServiceWorkerResponse. |
| 172 response_time_ = base::Time::Now(); | |
| 162 CommitResponseHeader(); | 173 CommitResponseHeader(); |
| 163 } | 174 } |
| 164 | 175 |
| 165 void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, | 176 void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, |
| 166 int bytes_read) { | 177 int bytes_read) { |
| 167 SetStatus(request->status()); | 178 SetStatus(request->status()); |
| 168 if (!request->status().is_success()) { | 179 if (!request->status().is_success()) { |
| 169 NotifyDone(request->status()); | 180 NotifyDone(request->status()); |
| 170 return; | 181 return; |
| 171 } | 182 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 return; | 226 return; |
| 216 | 227 |
| 217 case FALLBACK_TO_NETWORK: | 228 case FALLBACK_TO_NETWORK: |
| 218 // Restart the request to create a new job. Our request handler will | 229 // Restart the request to create a new job. Our request handler will |
| 219 // return NULL, and the default job (which will hit network) should be | 230 // return NULL, and the default job (which will hit network) should be |
| 220 // created. | 231 // created. |
| 221 NotifyRestartRequired(); | 232 NotifyRestartRequired(); |
| 222 return; | 233 return; |
| 223 | 234 |
| 224 case FORWARD_TO_SERVICE_WORKER: | 235 case FORWARD_TO_SERVICE_WORKER: |
| 236 load_timing_info_.request_start_time = base::Time::Now(); | |
| 237 load_timing_info_.request_start = base::TimeTicks::Now(); | |
| 225 DCHECK(provider_host_ && provider_host_->active_version()); | 238 DCHECK(provider_host_ && provider_host_->active_version()); |
| 226 DCHECK(!fetch_dispatcher_); | 239 DCHECK(!fetch_dispatcher_); |
| 227 // Send a fetch event to the ServiceWorker associated to the | 240 // Send a fetch event to the ServiceWorker associated to the |
| 228 // provider_host. | 241 // provider_host. |
| 229 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( | 242 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( |
| 230 CreateFetchRequest(), | 243 CreateFetchRequest(), |
| 231 provider_host_->active_version(), | 244 provider_host_->active_version(), |
| 232 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, | 245 base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, |
| 233 weak_factory_.GetWeakPtr()), | 246 weak_factory_.GetWeakPtr()), |
| 234 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, | 247 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, |
| 235 weak_factory_.GetWeakPtr()))); | 248 weak_factory_.GetWeakPtr()))); |
| 249 load_timing_info_.serviceworker_timing.fetch_start = | |
| 250 base::TimeTicks::Now(); | |
| 236 fetch_dispatcher_->Run(); | 251 fetch_dispatcher_->Run(); |
| 237 return; | 252 return; |
| 238 } | 253 } |
| 239 | 254 |
| 240 NOTREACHED(); | 255 NOTREACHED(); |
| 241 } | 256 } |
| 242 | 257 |
| 243 scoped_ptr<ServiceWorkerFetchRequest> | 258 scoped_ptr<ServiceWorkerFetchRequest> |
| 244 ServiceWorkerURLRequestJob::CreateFetchRequest() { | 259 ServiceWorkerURLRequestJob::CreateFetchRequest() { |
| 245 std::string blob_uuid; | 260 std::string blob_uuid; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 } | 332 } |
| 318 | 333 |
| 319 request_body_blob_data_handle_ = | 334 request_body_blob_data_handle_ = |
| 320 blob_storage_context_->AddFinishedBlob(blob_data.get()); | 335 blob_storage_context_->AddFinishedBlob(blob_data.get()); |
| 321 *blob_uuid = uuid; | 336 *blob_uuid = uuid; |
| 322 *blob_size = size; | 337 *blob_size = size; |
| 323 return true; | 338 return true; |
| 324 } | 339 } |
| 325 | 340 |
| 326 void ServiceWorkerURLRequestJob::DidPrepareFetchEvent() { | 341 void ServiceWorkerURLRequestJob::DidPrepareFetchEvent() { |
| 327 // TODO(shimazu): Set the timestamp to measure the time to launch SW | 342 load_timing_info_.serviceworker_timing.launch_serviceworker = |
|
horo
2014/08/28 07:00:08
"launch_serviceworker" is not appropriate.
Service
shimazu
2014/08/29 02:16:33
Done.
| |
| 328 // This is related to this (http://crbug.com/401389) | 343 base::TimeTicks::Now(); |
| 329 } | 344 } |
| 330 | 345 |
| 331 void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( | 346 void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( |
| 332 ServiceWorkerStatusCode status, | 347 ServiceWorkerStatusCode status, |
| 333 ServiceWorkerFetchEventResult fetch_result, | 348 ServiceWorkerFetchEventResult fetch_result, |
| 334 const ServiceWorkerResponse& response) { | 349 const ServiceWorkerResponse& response) { |
| 335 fetch_dispatcher_.reset(); | 350 fetch_dispatcher_.reset(); |
| 336 | 351 |
| 337 // Check if we're not orphaned. | 352 // Check if we're not orphaned. |
| 338 if (!request()) | 353 if (!request()) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 352 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { | 367 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { |
| 353 // Change the response type and restart the request to fallback to | 368 // Change the response type and restart the request to fallback to |
| 354 // the network. | 369 // the network. |
| 355 response_type_ = FALLBACK_TO_NETWORK; | 370 response_type_ = FALLBACK_TO_NETWORK; |
| 356 NotifyRestartRequired(); | 371 NotifyRestartRequired(); |
| 357 return; | 372 return; |
| 358 } | 373 } |
| 359 | 374 |
| 360 // We should have a response now. | 375 // We should have a response now. |
| 361 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); | 376 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); |
| 377 load_timing_info_.serviceworker_timing.fetch_end = base::TimeTicks::Now(); | |
| 362 | 378 |
| 363 // Set up a request for reading the blob. | 379 // Set up a request for reading the blob. |
| 364 if (!response.blob_uuid.empty() && blob_storage_context_) { | 380 if (!response.blob_uuid.empty() && blob_storage_context_) { |
| 365 scoped_ptr<storage::BlobDataHandle> blob_data_handle = | 381 scoped_ptr<storage::BlobDataHandle> blob_data_handle = |
| 366 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); | 382 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); |
| 367 if (!blob_data_handle) { | 383 if (!blob_data_handle) { |
| 368 // The renderer gave us a bad blob UUID. | 384 // The renderer gave us a bad blob UUID. |
| 369 DeliverErrorResponse(); | 385 DeliverErrorResponse(); |
| 370 return; | 386 return; |
| 371 } | 387 } |
| 372 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( | 388 blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( |
| 373 blob_data_handle.Pass(), request()->context(), this); | 389 blob_data_handle.Pass(), request()->context(), this); |
| 374 blob_request_->Start(); | 390 blob_request_->Start(); |
| 375 } | 391 } |
| 376 | 392 |
| 377 response_url_ = response.url; | 393 response_url_ = response.url; |
| 378 CreateResponseHeader( | 394 CreateResponseHeader( |
| 379 response.status_code, response.status_text, response.headers); | 395 response.status_code, response.status_text, response.headers); |
| 396 load_timing_info_.receive_headers_end = base::TimeTicks::Now(); | |
| 380 if (!blob_request_) | 397 if (!blob_request_) |
| 381 CommitResponseHeader(); | 398 CommitResponseHeader(); |
| 382 } | 399 } |
| 383 | 400 |
| 384 void ServiceWorkerURLRequestJob::CreateResponseHeader( | 401 void ServiceWorkerURLRequestJob::CreateResponseHeader( |
| 385 int status_code, | 402 int status_code, |
| 386 const std::string& status_text, | 403 const std::string& status_text, |
| 387 const std::map<std::string, std::string>& headers) { | 404 const std::map<std::string, std::string>& headers) { |
| 388 // TODO(kinuko): If the response has an identifier to on-disk cache entry, | 405 // TODO(kinuko): If the response has an identifier to on-disk cache entry, |
| 389 // pull response header from the disk. | 406 // pull response header from the disk. |
| 390 std::string status_line( | 407 std::string status_line( |
| 391 base::StringPrintf("HTTP/1.1 %d %s", status_code, status_text.c_str())); | 408 base::StringPrintf("HTTP/1.1 %d %s", status_code, status_text.c_str())); |
| 392 status_line.push_back('\0'); | 409 status_line.push_back('\0'); |
| 393 http_response_headers_ = new net::HttpResponseHeaders(status_line); | 410 http_response_headers_ = new net::HttpResponseHeaders(status_line); |
| 394 for (std::map<std::string, std::string>::const_iterator it = headers.begin(); | 411 for (std::map<std::string, std::string>::const_iterator it = headers.begin(); |
| 395 it != headers.end(); | 412 it != headers.end(); |
| 396 ++it) { | 413 ++it) { |
| 397 std::string header; | 414 std::string header; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 412 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { | 429 void ServiceWorkerURLRequestJob::DeliverErrorResponse() { |
| 413 // TODO(falken): Print an error to the console of the ServiceWorker and of | 430 // TODO(falken): Print an error to the console of the ServiceWorker and of |
| 414 // the requesting page. | 431 // the requesting page. |
| 415 CreateResponseHeader(500, | 432 CreateResponseHeader(500, |
| 416 "Service Worker Response Error", | 433 "Service Worker Response Error", |
| 417 std::map<std::string, std::string>()); | 434 std::map<std::string, std::string>()); |
| 418 CommitResponseHeader(); | 435 CommitResponseHeader(); |
| 419 } | 436 } |
| 420 | 437 |
| 421 } // namespace content | 438 } // namespace content |
| OLD | NEW |