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

Side by Side Diff: content/browser/appcache/appcache_url_loader_job.cc

Issue 2956373002: Add support for subresource request loads in AppCache for the network service. (Closed)
Patch Set: Address review comments Created 3 years, 5 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
« no previous file with comments | « content/browser/appcache/appcache_url_loader_job.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2017 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/appcache/appcache_url_loader_job.h" 5 #include "content/browser/appcache/appcache_url_loader_job.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "content/browser/appcache/appcache_histograms.h" 8 #include "content/browser/appcache/appcache_histograms.h"
9 #include "content/browser/appcache/appcache_subresource_url_factory.h"
10 #include "content/browser/url_loader_factory_getter.h"
9 #include "content/common/net_adapters.h" 11 #include "content/common/net_adapters.h"
10 #include "content/public/common/resource_type.h" 12 #include "content/public/common/resource_type.h"
11 #include "net/http/http_status_code.h" 13 #include "net/http/http_status_code.h"
12 14
13 namespace content { 15 namespace content {
14 16
17 SubresourceLoadInfo::SubresourceLoadInfo()
18 : routing_id(-1), request_id(-1), options(0) {}
19
20 SubresourceLoadInfo::~SubresourceLoadInfo() {}
21
15 AppCacheURLLoaderJob::~AppCacheURLLoaderJob() { 22 AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {
16 if (storage_.get()) 23 if (storage_.get())
17 storage_->CancelDelegateCallbacks(this); 24 storage_->CancelDelegateCallbacks(this);
18 } 25 }
19 26
20 void AppCacheURLLoaderJob::Kill() {} 27 void AppCacheURLLoaderJob::Kill() {}
21 28
22 bool AppCacheURLLoaderJob::IsStarted() const { 29 bool AppCacheURLLoaderJob::IsStarted() const {
23 return delivery_type_ != AWAITING_DELIVERY_ORDERS; 30 return delivery_type_ != AWAITING_DELIVERY_ORDERS;
24 } 31 }
25 32
26 void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url, 33 void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
27 int64_t cache_id, 34 int64_t cache_id,
28 const AppCacheEntry& entry, 35 const AppCacheEntry& entry,
29 bool is_fallback) { 36 bool is_fallback) {
30 if (!storage_.get()) { 37 if (!storage_.get()) {
31 DeliverErrorResponse(); 38 DeliverErrorResponse();
32 return; 39 return;
33 } 40 }
34 41
35 delivery_type_ = APPCACHED_DELIVERY; 42 delivery_type_ = APPCACHED_DELIVERY;
36 43
44 load_timing_info_.request_start_time = base::Time::Now();
45 load_timing_info_.request_start = base::TimeTicks::Now();
46
37 AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() - 47 AppCacheHistograms::AddAppCacheJobStartDelaySample(base::TimeTicks::Now() -
38 start_time_tick_); 48 start_time_tick_);
39 49
40 manifest_url_ = manifest_url; 50 manifest_url_ = manifest_url;
41 cache_id_ = cache_id; 51 cache_id_ = cache_id;
42 entry_ = entry; 52 entry_ = entry;
43 is_fallback_ = is_fallback; 53 is_fallback_ = is_fallback;
44 54
45 // Handle range requests. 55 // Handle range requests.
46 net::HttpRequestHeaders headers; 56 net::HttpRequestHeaders headers;
47 headers.AddHeadersFromString(request_.headers); 57 headers.AddHeadersFromString(request_.headers);
48 InitializeRangeRequestInfo(headers); 58 InitializeRangeRequestInfo(headers);
49 59
50 // TODO(ananta) 60 // TODO(ananta)
51 // Implement the AppCacheServiceImpl::Observer interface or add weak pointer 61 // Implement the AppCacheServiceImpl::Observer interface or add weak pointer
52 // support to it. 62 // support to it.
53 storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this); 63 storage_->LoadResponseInfo(manifest_url_, entry_.response_id(), this);
54 } 64 }
55 65
56 void AppCacheURLLoaderJob::DeliverNetworkResponse() { 66 void AppCacheURLLoaderJob::DeliverNetworkResponse() {
57 delivery_type_ = NETWORK_DELIVERY; 67 delivery_type_ = NETWORK_DELIVERY;
58 68
59 AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() - 69 AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
60 start_time_tick_); 70 start_time_tick_);
61 71
62 DCHECK(!loader_callback_.is_null()); 72 if (IsResourceTypeFrame(request_.resource_type)) {
63 // In network service land, if we are processing a navigation request, we 73 DCHECK(!main_resource_loader_callback_.is_null());
64 // need to inform the loader callback that we are not going to handle this 74 // In network service land, if we are processing a navigation request, we
65 // request. The loader callback is valid only for navigation requests. 75 // need to inform the loader callback that we are not going to handle this
66 std::move(loader_callback_).Run(StartLoaderCallback()); 76 // request. The loader callback is valid only for navigation requests.
77 std::move(main_resource_loader_callback_).Run(StartLoaderCallback());
78 } else {
79 default_url_loader_factory_getter_->GetNetworkFactory()
80 ->get()
81 ->CreateLoaderAndStart(
82 mojo::MakeRequest(&network_loader_request_),
83 subresource_load_info_->routing_id,
84 subresource_load_info_->request_id, subresource_load_info_->options,
85 subresource_load_info_->request, std::move(client_info_),
86 subresource_load_info_->traffic_annotation);
87 }
67 } 88 }
68 89
69 void AppCacheURLLoaderJob::DeliverErrorResponse() { 90 void AppCacheURLLoaderJob::DeliverErrorResponse() {
70 delivery_type_ = ERROR_DELIVERY; 91 delivery_type_ = ERROR_DELIVERY;
71 92
72 // We expect the URLLoaderClient pointer to be valid at this point. 93 // We expect the URLLoaderClient pointer to be valid at this point.
73 DCHECK(client_info_); 94 DCHECK(client_info_);
74 95
75 // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems 96 // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems
76 // to map to HTTP_INTERNAL_SERVER_ERROR. 97 // to map to HTTP_INTERNAL_SERVER_ERROR.
(...skipping 15 matching lines...) Expand all
92 113
93 const GURL& AppCacheURLLoaderJob::GetURL() const { 114 const GURL& AppCacheURLLoaderJob::GetURL() const {
94 return request_.url; 115 return request_.url;
95 } 116 }
96 117
97 AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() { 118 AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
98 return this; 119 return this;
99 } 120 }
100 121
101 void AppCacheURLLoaderJob::FollowRedirect() { 122 void AppCacheURLLoaderJob::FollowRedirect() {
102 DCHECK(false); 123 if (network_loader_request_)
124 network_loader_request_->FollowRedirect();
103 } 125 }
104 126
105 void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority, 127 void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
106 int32_t intra_priority_value) { 128 int32_t intra_priority_value) {
107 NOTREACHED() << "We don't support SetPriority()"; 129 if (network_loader_request_)
130 network_loader_request_->SetPriority(priority, intra_priority_value);
131 }
132
133 void AppCacheURLLoaderJob::SetSubresourceLoadInfo(
134 std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
135 URLLoaderFactoryGetter* default_url_loader) {
136 subresource_load_info_ = std::move(subresource_load_info);
137
138 associated_binding_.reset(new mojo::AssociatedBinding<mojom::URLLoader>(
139 this, std::move(subresource_load_info_->url_loader_request)));
140 associated_binding_->set_connection_error_handler(base::Bind(
141 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
142
143 client_info_ = std::move(subresource_load_info_->client);
144 default_url_loader_factory_getter_ = default_url_loader;
108 } 145 }
109 146
110 void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request, 147 void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request,
111 mojom::URLLoaderClientPtr client) { 148 mojom::URLLoaderClientPtr client) {
112 DCHECK(!binding_.is_bound()); 149 DCHECK(!binding_.is_bound());
113 binding_.Bind(std::move(request)); 150 binding_.Bind(std::move(request));
114 151
115 binding_.set_connection_error_handler(base::Bind( 152 binding_.set_connection_error_handler(base::Bind(
116 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this))); 153 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
117 154
(...skipping 26 matching lines...) Expand all
144 } 181 }
145 182
146 if (response_info) { 183 if (response_info) {
147 info_ = response_info; 184 info_ = response_info;
148 reader_.reset( 185 reader_.reset(
149 storage_->CreateResponseReader(manifest_url_, entry_.response_id())); 186 storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
150 187
151 if (is_range_request()) 188 if (is_range_request())
152 SetupRangeResponse(); 189 SetupRangeResponse();
153 190
154 DCHECK(!loader_callback_.is_null()); 191 if (IsResourceTypeFrame(request_.resource_type)) {
155 std::move(loader_callback_) 192 DCHECK(!main_resource_loader_callback_.is_null());
156 .Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this))); 193 std::move(main_resource_loader_callback_)
194 .Run(base::Bind(&AppCacheURLLoaderJob::Start, StaticAsWeakPtr(this)));
195 }
157 196
158 response_body_stream_ = std::move(data_pipe_.producer_handle); 197 response_body_stream_ = std::move(data_pipe_.producer_handle);
159 198
160 // TODO(ananta) 199 // TODO(ananta)
161 // Move the asynchronous reading and mojo pipe handling code to a helper 200 // Move the asynchronous reading and mojo pipe handling code to a helper
162 // class. That would also need a change to BlobURLLoader. 201 // class. That would also need a change to BlobURLLoader.
163 202
164 // Wait for the data pipe to be ready to accept data. 203 // Wait for the data pipe to be ready to accept data.
165 writable_handle_watcher_.Watch( 204 writable_handle_watcher_.Watch(
166 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, 205 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
(...skipping 11 matching lines...) Expand all
178 false, IsResourceTypeFrame(request_.resource_type), 217 false, IsResourceTypeFrame(request_.resource_type),
179 manifest_url_.GetOrigin()); 218 manifest_url_.GetOrigin());
180 219
181 cache_entry_not_found_ = true; 220 cache_entry_not_found_ = true;
182 } 221 }
183 } 222 }
184 223
185 void AppCacheURLLoaderJob::OnReadComplete(int result) { 224 void AppCacheURLLoaderJob::OnReadComplete(int result) {
186 DLOG(WARNING) << "AppCache read completed with result: " << result; 225 DLOG(WARNING) << "AppCache read completed with result: " << result;
187 226
227 if (result <= 0) {
228 writable_handle_watcher_.Cancel();
229 pending_write_->Complete(0);
230 pending_write_ = nullptr;
231 }
232
188 bool is_main_resource = IsResourceTypeFrame(request_.resource_type); 233 bool is_main_resource = IsResourceTypeFrame(request_.resource_type);
189 234
190 if (result == 0) { 235 if (result == 0) {
191 NotifyCompleted(result); 236 NotifyCompleted(result);
192 AppCacheHistograms::CountResponseRetrieval(true, is_main_resource, 237 AppCacheHistograms::CountResponseRetrieval(true, is_main_resource,
193 manifest_url_.GetOrigin()); 238 manifest_url_.GetOrigin());
194 return; 239 return;
195 } else if (result < 0) { 240 } else if (result < 0) {
196 // TODO(ananta) 241 // TODO(ananta)
197 // Populate the relevant fields of the ResourceRequestCompletionStatus 242 // Populate the relevant fields of the ResourceRequestCompletionStatus
(...skipping 11 matching lines...) Expand all
209 } 254 }
210 255
211 void AppCacheURLLoaderJob::OnConnectionError() { 256 void AppCacheURLLoaderJob::OnConnectionError() {
212 if (storage_.get()) 257 if (storage_.get())
213 storage_->CancelDelegateCallbacks(this); 258 storage_->CancelDelegateCallbacks(this);
214 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); 259 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
215 } 260 }
216 261
217 void AppCacheURLLoaderJob::SendResponseInfo() { 262 void AppCacheURLLoaderJob::SendResponseInfo() {
218 DCHECK(client_info_); 263 DCHECK(client_info_);
219
220 // If this is null it means the response information was sent to the client. 264 // If this is null it means the response information was sent to the client.
221 if (!data_pipe_.consumer_handle.is_valid()) 265 if (!data_pipe_.consumer_handle.is_valid())
222 return; 266 return;
223 267
224 const net::HttpResponseInfo* http_info = is_range_request() 268 const net::HttpResponseInfo* http_info = is_range_request()
225 ? range_response_info_.get() 269 ? range_response_info_.get()
226 : info_->http_response_info(); 270 : info_->http_response_info();
227 271
228 ResourceResponseHead response_head; 272 ResourceResponseHead response_head;
229 response_head.headers = http_info->headers; 273 response_head.headers = http_info->headers;
274 response_head.appcache_id = cache_id_;
275 response_head.appcache_manifest_url = manifest_url_;
230 276
231 // TODO(ananta)
232 // Copy more fields.
233 http_info->headers->GetMimeType(&response_head.mime_type); 277 http_info->headers->GetMimeType(&response_head.mime_type);
234 http_info->headers->GetCharset(&response_head.charset); 278 http_info->headers->GetCharset(&response_head.charset);
235 279
280 // TODO(ananta)
281 // Verify if the times sent here are correct.
236 response_head.request_time = http_info->request_time; 282 response_head.request_time = http_info->request_time;
237 response_head.response_time = http_info->response_time; 283 response_head.response_time = http_info->response_time;
238 response_head.content_length = 284 response_head.content_length =
239 is_range_request() ? range_response_info_->headers->GetContentLength() 285 is_range_request() ? range_response_info_->headers->GetContentLength()
240 : info_->response_data_size(); 286 : info_->response_data_size();
241 287
288 response_head.connection_info = http_info->connection_info;
289 response_head.socket_address = http_info->socket_address;
290 response_head.was_fetched_via_spdy = http_info->was_fetched_via_spdy;
291 response_head.was_alpn_negotiated = http_info->was_alpn_negotiated;
292 response_head.alpn_negotiated_protocol = http_info->alpn_negotiated_protocol;
293
294 response_head.load_timing = load_timing_info_;
295
242 client_info_->OnReceiveResponse(response_head, http_info->ssl_info, 296 client_info_->OnReceiveResponse(response_head, http_info->ssl_info,
243 mojom::DownloadedTempFilePtr()); 297 mojom::DownloadedTempFilePtr());
244 298
245 client_info_->OnStartLoadingResponseBody( 299 client_info_->OnStartLoadingResponseBody(
246 std::move(data_pipe_.consumer_handle)); 300 std::move(data_pipe_.consumer_handle));
247 } 301 }
248 302
249 void AppCacheURLLoaderJob::ReadMore() { 303 void AppCacheURLLoaderJob::ReadMore() {
250 DCHECK(!pending_write_.get()); 304 DCHECK(!pending_write_.get());
251 305
(...skipping 30 matching lines...) Expand all
282 if (result != MOJO_RESULT_OK) { 336 if (result != MOJO_RESULT_OK) {
283 DCHECK(false); 337 DCHECK(false);
284 NotifyCompleted(net::ERR_FAILED); 338 NotifyCompleted(net::ERR_FAILED);
285 } 339 }
286 ReadMore(); 340 ReadMore();
287 } 341 }
288 342
289 void AppCacheURLLoaderJob::NotifyCompleted(int error_code) { 343 void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
290 if (storage_.get()) 344 if (storage_.get())
291 storage_->CancelDelegateCallbacks(this); 345 storage_->CancelDelegateCallbacks(this);
292 // TODO(ananta) 346
293 // Fill other details in the ResourceRequestCompletionStatus structure. 347 const net::HttpResponseInfo* http_info = is_range_request()
348 ? range_response_info_.get()
349 : info_->http_response_info();
350
294 ResourceRequestCompletionStatus request_complete_data; 351 ResourceRequestCompletionStatus request_complete_data;
295 request_complete_data.error_code = error_code; 352 request_complete_data.error_code = error_code;
353
354 // TODO(ananta)
355 // Fill other details in the ResourceRequestCompletionStatus structure in
356 // case of an error.
357 if (!request_complete_data.error_code) {
358 request_complete_data.exists_in_cache = http_info->was_cached;
359 request_complete_data.completion_time = base::TimeTicks::Now();
360 request_complete_data.encoded_body_length =
361 is_range_request() ? range_response_info_->headers->GetContentLength()
362 : info_->response_data_size();
363 request_complete_data.decoded_body_length =
364 request_complete_data.encoded_body_length;
365 }
296 client_info_->OnComplete(request_complete_data); 366 client_info_->OnComplete(request_complete_data);
297 } 367 }
298 368
299 } // namespace content 369 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/appcache/appcache_url_loader_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698