| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "content/browser/fileapi/chrome_blob_storage_context.h" |
| 9 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" | 10 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" |
| 10 #include "content/browser/service_worker/service_worker_provider_host.h" | 11 #include "content/browser/service_worker/service_worker_provider_host.h" |
| 11 #include "net/http/http_request_headers.h" | 12 #include "net/http/http_request_headers.h" |
| 12 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
| 13 #include "net/http/http_response_info.h" | 14 #include "net/http/http_response_info.h" |
| 14 #include "net/http/http_util.h" | 15 #include "net/http/http_util.h" |
| 16 #include "webkit/browser/blob/blob_data_handle.h" |
| 17 #include "webkit/browser/blob/blob_storage_context.h" |
| 18 #include "webkit/browser/blob/blob_url_request_job_factory.h" |
| 15 | 19 |
| 16 namespace content { | 20 namespace content { |
| 17 | 21 |
| 18 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( | 22 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( |
| 19 net::URLRequest* request, | 23 net::URLRequest* request, |
| 20 net::NetworkDelegate* network_delegate, | 24 net::NetworkDelegate* network_delegate, |
| 21 base::WeakPtr<ServiceWorkerProviderHost> provider_host) | 25 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
| 26 scoped_refptr<ChromeBlobStorageContext> blob_storage_context) |
| 22 : net::URLRequestJob(request, network_delegate), | 27 : net::URLRequestJob(request, network_delegate), |
| 23 provider_host_(provider_host), | 28 provider_host_(provider_host), |
| 24 response_type_(NOT_DETERMINED), | 29 response_type_(NOT_DETERMINED), |
| 25 is_started_(false), | 30 is_started_(false), |
| 31 blob_storage_context_(blob_storage_context), |
| 26 weak_factory_(this) { | 32 weak_factory_(this) { |
| 27 } | 33 } |
| 28 | 34 |
| 29 void ServiceWorkerURLRequestJob::FallbackToNetwork() { | 35 void ServiceWorkerURLRequestJob::FallbackToNetwork() { |
| 30 DCHECK_EQ(NOT_DETERMINED, response_type_); | 36 DCHECK_EQ(NOT_DETERMINED, response_type_); |
| 31 response_type_ = FALLBACK_TO_NETWORK; | 37 response_type_ = FALLBACK_TO_NETWORK; |
| 32 MaybeStartRequest(); | 38 MaybeStartRequest(); |
| 33 } | 39 } |
| 34 | 40 |
| 35 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { | 41 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 return; | 93 return; |
| 88 } | 94 } |
| 89 | 95 |
| 90 // We don't support multiple range requests in one single URL request. | 96 // We don't support multiple range requests in one single URL request. |
| 91 if (ranges.size() == 1U) | 97 if (ranges.size() == 1U) |
| 92 byte_range_ = ranges[0]; | 98 byte_range_ = ranges[0]; |
| 93 } | 99 } |
| 94 | 100 |
| 95 bool ServiceWorkerURLRequestJob::ReadRawData( | 101 bool ServiceWorkerURLRequestJob::ReadRawData( |
| 96 net::IOBuffer* buf, int buf_size, int *bytes_read) { | 102 net::IOBuffer* buf, int buf_size, int *bytes_read) { |
| 97 // TODO(kinuko): Implement this. | 103 if (!blob_request_) { |
| 98 // If the response returned from ServiceWorker had an | 104 *bytes_read = 0; |
| 99 // identifier to on-disk data (e.g. blob or cache entry) we'll need to | 105 return true; |
| 100 // pull the body from disk. | 106 } |
| 101 NOTIMPLEMENTED(); | 107 |
| 102 *bytes_read = 0; | 108 blob_request_->Read(buf, buf_size, bytes_read); |
| 103 return true; | 109 net::URLRequestStatus status = blob_request_->status(); |
| 110 SetStatus(status); |
| 111 if (status.is_io_pending()) |
| 112 return false; |
| 113 return status.is_success(); |
| 114 } |
| 115 |
| 116 void ServiceWorkerURLRequestJob::OnReceivedRedirect(net::URLRequest* request, |
| 117 const GURL& new_url, |
| 118 bool* defer_redirect) { |
| 119 NOTREACHED(); |
| 120 } |
| 121 |
| 122 void ServiceWorkerURLRequestJob::OnAuthRequired( |
| 123 net::URLRequest* request, |
| 124 net::AuthChallengeInfo* auth_info) { |
| 125 NOTREACHED(); |
| 126 } |
| 127 |
| 128 void ServiceWorkerURLRequestJob::OnCertificateRequested( |
| 129 net::URLRequest* request, |
| 130 net::SSLCertRequestInfo* cert_request_info) { |
| 131 NOTREACHED(); |
| 132 } |
| 133 |
| 134 void ServiceWorkerURLRequestJob::OnSSLCertificateError( |
| 135 net::URLRequest* request, |
| 136 const net::SSLInfo& ssl_info, |
| 137 bool fatal) { |
| 138 NOTREACHED(); |
| 139 } |
| 140 |
| 141 void ServiceWorkerURLRequestJob::OnBeforeNetworkStart(net::URLRequest* request, |
| 142 bool* defer) { |
| 143 NOTREACHED(); |
| 144 } |
| 145 |
| 146 void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { |
| 147 NotifyHeadersComplete(); |
| 148 } |
| 149 |
| 150 void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, |
| 151 int bytes_read) { |
| 152 if (!request->status().is_success()) { |
| 153 NotifyDone(request->status()); |
| 154 return; |
| 155 } |
| 156 NotifyReadComplete(bytes_read); |
| 157 if (bytes_read == 0) |
| 158 NotifyDone(request->status()); |
| 104 } | 159 } |
| 105 | 160 |
| 106 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { | 161 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { |
| 107 if (!http_response_info_) | 162 if (!http_response_info_) |
| 108 return NULL; | 163 return NULL; |
| 109 if (range_response_info_) | 164 if (range_response_info_) |
| 110 return range_response_info_.get(); | 165 return range_response_info_.get(); |
| 111 return http_response_info_.get(); | 166 return http_response_info_.get(); |
| 112 } | 167 } |
| 113 | 168 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 131 return; | 186 return; |
| 132 | 187 |
| 133 case FALLBACK_TO_NETWORK: | 188 case FALLBACK_TO_NETWORK: |
| 134 // Restart the request to create a new job. Our request handler will | 189 // Restart the request to create a new job. Our request handler will |
| 135 // return NULL, and the default job (which will hit network) should be | 190 // return NULL, and the default job (which will hit network) should be |
| 136 // created. | 191 // created. |
| 137 NotifyRestartRequired(); | 192 NotifyRestartRequired(); |
| 138 return; | 193 return; |
| 139 | 194 |
| 140 case FORWARD_TO_SERVICE_WORKER: | 195 case FORWARD_TO_SERVICE_WORKER: |
| 141 DCHECK(provider_host_ && provider_host_->active_version()); | 196 DCHECK(provider_host_); |
| 197 DCHECK(provider_host_->active_version()); |
| 142 DCHECK(!fetch_dispatcher_); | 198 DCHECK(!fetch_dispatcher_); |
| 143 | 199 |
| 144 // Send a fetch event to the ServiceWorker associated to the | 200 // Send a fetch event to the ServiceWorker associated to the |
| 145 // provider_host. | 201 // provider_host. |
| 146 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( | 202 fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( |
| 147 request(), provider_host_->active_version(), | 203 request(), provider_host_->active_version(), |
| 148 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, | 204 base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, |
| 149 weak_factory_.GetWeakPtr()))); | 205 weak_factory_.GetWeakPtr()))); |
| 150 fetch_dispatcher_->Run(); | 206 fetch_dispatcher_->Run(); |
| 151 return; | 207 return; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 176 } | 232 } |
| 177 | 233 |
| 178 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { | 234 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { |
| 179 // Change the response type and restart the request to fallback to | 235 // Change the response type and restart the request to fallback to |
| 180 // the network. | 236 // the network. |
| 181 response_type_ = FALLBACK_TO_NETWORK; | 237 response_type_ = FALLBACK_TO_NETWORK; |
| 182 NotifyRestartRequired(); | 238 NotifyRestartRequired(); |
| 183 return; | 239 return; |
| 184 } | 240 } |
| 185 | 241 |
| 242 // Set up a request for reading the blob. |
| 243 if (response_type_ == FORWARD_TO_SERVICE_WORKER && |
| 244 !response.blob_uuid.empty()) { |
| 245 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle = |
| 246 blob_storage_context_->context()->GetBlobDataFromUUID( |
| 247 response.blob_uuid); |
| 248 blob_request_ = webkit_blob::BlobProtocolHandler::CreateBlobRequest( |
| 249 blob_data_handle.Pass(), request()->context(), this); |
| 250 blob_request_->Start(); |
| 251 } |
| 252 |
| 186 // We should have response now. | 253 // We should have response now. |
| 187 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); | 254 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); |
| 188 | 255 |
| 189 CreateResponseHeader(response); | 256 CreateResponseHeader(response); |
| 190 NotifyHeadersComplete(); | 257 if (!blob_request_) |
| 258 NotifyHeadersComplete(); |
| 191 } | 259 } |
| 192 | 260 |
| 193 void ServiceWorkerURLRequestJob::CreateResponseHeader( | 261 void ServiceWorkerURLRequestJob::CreateResponseHeader( |
| 194 const ServiceWorkerResponse& response) { | 262 const ServiceWorkerResponse& response) { |
| 195 // TODO(kinuko): If the response has an identifier to on-disk cache entry, | 263 // TODO(kinuko): If the response has an identifier to on-disk cache entry, |
| 196 // pull response header from the disk. | 264 // pull response header from the disk. |
| 197 std::string status_line(base::StringPrintf("HTTP/1.1 %d %s", | 265 std::string status_line(base::StringPrintf("HTTP/1.1 %d %s", |
| 198 response.status_code, | 266 response.status_code, |
| 199 response.status_text.c_str())); | 267 response.status_text.c_str())); |
| 200 status_line.push_back('\0'); | 268 status_line.push_back('\0'); |
| 201 scoped_refptr<net::HttpResponseHeaders> headers( | 269 scoped_refptr<net::HttpResponseHeaders> headers( |
| 202 new net::HttpResponseHeaders(status_line)); | 270 new net::HttpResponseHeaders(status_line)); |
| 203 for (std::map<std::string, std::string>::const_iterator it = | 271 for (std::map<std::string, std::string>::const_iterator it = |
| 204 response.headers.begin(); | 272 response.headers.begin(); |
| 205 it != response.headers.end(); ++it) { | 273 it != response.headers.end(); ++it) { |
| 206 std::string header; | 274 std::string header; |
| 207 header.reserve(it->first.size() + 2 + it->second.size()); | 275 header.reserve(it->first.size() + 2 + it->second.size()); |
| 208 header.append(it->first); | 276 header.append(it->first); |
| 209 header.append(": "); | 277 header.append(": "); |
| 210 header.append(it->second); | 278 header.append(it->second); |
| 211 headers->AddHeader(header); | 279 headers->AddHeader(header); |
| 212 } | 280 } |
| 213 | 281 |
| 214 http_response_info_.reset(new net::HttpResponseInfo()); | 282 http_response_info_.reset(new net::HttpResponseInfo()); |
| 215 http_response_info_->headers = headers; | 283 http_response_info_->headers = headers; |
| 216 } | 284 } |
| 217 | 285 |
| 218 } // namespace content | 286 } // namespace content |
| OLD | NEW |