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/service_worker/service_worker_fetch_dispatcher.h" | 9 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" |
10 #include "content/browser/service_worker/service_worker_provider_host.h" | 10 #include "content/browser/service_worker/service_worker_provider_host.h" |
11 #include "net/http/http_request_headers.h" | 11 #include "net/http/http_request_headers.h" |
12 #include "net/http/http_response_headers.h" | 12 #include "net/http/http_response_headers.h" |
13 #include "net/http/http_response_info.h" | 13 #include "net/http/http_response_info.h" |
14 #include "net/http/http_util.h" | 14 #include "net/http/http_util.h" |
15 #include "webkit/browser/blob/blob_data_handle.h" | |
16 #include "webkit/browser/blob/blob_storage_context.h" | |
17 #include "webkit/browser/blob/blob_url_request_job_factory.h" | |
15 | 18 |
16 namespace content { | 19 namespace content { |
17 | 20 |
18 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( | 21 ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( |
19 net::URLRequest* request, | 22 net::URLRequest* request, |
20 net::NetworkDelegate* network_delegate, | 23 net::NetworkDelegate* network_delegate, |
21 base::WeakPtr<ServiceWorkerProviderHost> provider_host) | 24 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
25 base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context) | |
22 : net::URLRequestJob(request, network_delegate), | 26 : net::URLRequestJob(request, network_delegate), |
23 provider_host_(provider_host), | 27 provider_host_(provider_host), |
24 response_type_(NOT_DETERMINED), | 28 response_type_(NOT_DETERMINED), |
25 is_started_(false), | 29 is_started_(false), |
30 blob_storage_context_(blob_storage_context), | |
26 weak_factory_(this) { | 31 weak_factory_(this) { |
27 } | 32 } |
28 | 33 |
29 void ServiceWorkerURLRequestJob::FallbackToNetwork() { | 34 void ServiceWorkerURLRequestJob::FallbackToNetwork() { |
30 DCHECK_EQ(NOT_DETERMINED, response_type_); | 35 DCHECK_EQ(NOT_DETERMINED, response_type_); |
31 response_type_ = FALLBACK_TO_NETWORK; | 36 response_type_ = FALLBACK_TO_NETWORK; |
32 MaybeStartRequest(); | 37 MaybeStartRequest(); |
33 } | 38 } |
34 | 39 |
35 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { | 40 void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { |
36 DCHECK_EQ(NOT_DETERMINED, response_type_); | 41 DCHECK_EQ(NOT_DETERMINED, response_type_); |
37 response_type_ = FORWARD_TO_SERVICE_WORKER; | 42 response_type_ = FORWARD_TO_SERVICE_WORKER; |
38 MaybeStartRequest(); | 43 MaybeStartRequest(); |
39 } | 44 } |
40 | 45 |
41 void ServiceWorkerURLRequestJob::Start() { | 46 void ServiceWorkerURLRequestJob::Start() { |
42 is_started_ = true; | 47 is_started_ = true; |
43 MaybeStartRequest(); | 48 MaybeStartRequest(); |
44 } | 49 } |
45 | 50 |
46 void ServiceWorkerURLRequestJob::Kill() { | 51 void ServiceWorkerURLRequestJob::Kill() { |
47 net::URLRequestJob::Kill(); | 52 net::URLRequestJob::Kill(); |
48 fetch_dispatcher_.reset(); | 53 fetch_dispatcher_.reset(); |
54 blob_request_.reset(); | |
49 weak_factory_.InvalidateWeakPtrs(); | 55 weak_factory_.InvalidateWeakPtrs(); |
50 } | 56 } |
51 | 57 |
52 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { | 58 net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { |
53 // TODO(kinuko): refine this for better debug. | 59 // TODO(kinuko): refine this for better debug. |
54 return net::URLRequestJob::GetLoadState(); | 60 return net::URLRequestJob::GetLoadState(); |
55 } | 61 } |
56 | 62 |
57 bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) { | 63 bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) { |
58 if (!http_info()) | 64 if (!http_info()) |
(...skipping 28 matching lines...) Expand all 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 // TODO(falken): Add Content-Length, Content-Type if they were not provided in | |
148 // the ServiceWorkerResponse. | |
149 CommitResponseHeader(); | |
150 } | |
151 | |
152 void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, | |
153 int bytes_read) { | |
154 if (!request->status().is_success()) { | |
155 NotifyDone(request->status()); | |
156 return; | |
157 } | |
158 NotifyReadComplete(bytes_read); | |
159 if (bytes_read == 0) | |
160 NotifyDone(request->status()); | |
104 } | 161 } |
105 | 162 |
106 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { | 163 const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { |
107 if (!http_response_info_) | 164 if (!http_response_info_) |
108 return NULL; | 165 return NULL; |
109 if (range_response_info_) | 166 if (range_response_info_) |
110 return range_response_info_.get(); | 167 return range_response_info_.get(); |
111 return http_response_info_.get(); | 168 return http_response_info_.get(); |
112 } | 169 } |
113 | 170 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 } | 233 } |
177 | 234 |
178 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { | 235 if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { |
179 // Change the response type and restart the request to fallback to | 236 // Change the response type and restart the request to fallback to |
180 // the network. | 237 // the network. |
181 response_type_ = FALLBACK_TO_NETWORK; | 238 response_type_ = FALLBACK_TO_NETWORK; |
182 NotifyRestartRequired(); | 239 NotifyRestartRequired(); |
183 return; | 240 return; |
184 } | 241 } |
185 | 242 |
186 // We should have response now. | 243 // We should have a response now. |
187 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); | 244 DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); |
188 | 245 |
246 // Set up a request for reading the blob. | |
247 if (!response.blob_uuid.empty() && blob_storage_context_) { | |
248 scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle = | |
michaeln
2014/05/27 21:26:16
if blob_data_handle is NULL here, i think we shoul
falken
2014/05/28 12:32:00
Now I return 500 "Service Worker Response Error" w
| |
249 blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); | |
250 blob_request_ = webkit_blob::BlobProtocolHandler::CreateBlobRequest( | |
251 blob_data_handle.Pass(), request()->context(), this); | |
252 blob_request_->Start(); | |
253 } | |
254 | |
189 CreateResponseHeader(response); | 255 CreateResponseHeader(response); |
190 NotifyHeadersComplete(); | 256 if (!blob_request_) |
257 CommitResponseHeader(); | |
191 } | 258 } |
192 | 259 |
193 void ServiceWorkerURLRequestJob::CreateResponseHeader( | 260 void ServiceWorkerURLRequestJob::CreateResponseHeader( |
194 const ServiceWorkerResponse& response) { | 261 const ServiceWorkerResponse& response) { |
195 // TODO(kinuko): If the response has an identifier to on-disk cache entry, | 262 // TODO(kinuko): If the response has an identifier to on-disk cache entry, |
196 // pull response header from the disk. | 263 // pull response header from the disk. |
197 std::string status_line(base::StringPrintf("HTTP/1.1 %d %s", | 264 std::string status_line(base::StringPrintf("HTTP/1.1 %d %s", |
198 response.status_code, | 265 response.status_code, |
199 response.status_text.c_str())); | 266 response.status_text.c_str())); |
200 status_line.push_back('\0'); | 267 status_line.push_back('\0'); |
201 scoped_refptr<net::HttpResponseHeaders> headers( | 268 http_response_headers_ = new net::HttpResponseHeaders(status_line); |
202 new net::HttpResponseHeaders(status_line)); | |
203 for (std::map<std::string, std::string>::const_iterator it = | 269 for (std::map<std::string, std::string>::const_iterator it = |
204 response.headers.begin(); | 270 response.headers.begin(); |
205 it != response.headers.end(); ++it) { | 271 it != response.headers.end(); ++it) { |
206 std::string header; | 272 std::string header; |
207 header.reserve(it->first.size() + 2 + it->second.size()); | 273 header.reserve(it->first.size() + 2 + it->second.size()); |
208 header.append(it->first); | 274 header.append(it->first); |
209 header.append(": "); | 275 header.append(": "); |
210 header.append(it->second); | 276 header.append(it->second); |
211 headers->AddHeader(header); | 277 http_response_headers_->AddHeader(header); |
212 } | 278 } |
279 } | |
213 | 280 |
281 void ServiceWorkerURLRequestJob::CommitResponseHeader() { | |
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.swap(http_response_headers_); |
284 NotifyHeadersComplete(); | |
216 } | 285 } |
217 | 286 |
218 } // namespace content | 287 } // namespace content |
OLD | NEW |