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

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

Issue 2974733002: Add support for subresource request fallback in AppCache for the network service.. (Closed)
Patch Set: Format changes 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
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" 9 #include "content/browser/appcache/appcache_subresource_url_factory.h"
10 #include "content/browser/appcache/appcache_url_loader_request.h"
10 #include "content/browser/url_loader_factory_getter.h" 11 #include "content/browser/url_loader_factory_getter.h"
11 #include "content/common/net_adapters.h" 12 #include "content/common/net_adapters.h"
12 #include "content/public/common/resource_type.h" 13 #include "content/public/common/resource_type.h"
13 #include "net/http/http_status_code.h" 14 #include "net/http/http_status_code.h"
14 15
15 namespace content { 16 namespace content {
16 17
17 SubresourceLoadInfo::SubresourceLoadInfo() 18 SubresourceLoadInfo::SubresourceLoadInfo()
18 : routing_id(-1), request_id(-1), options(0) {} 19 : routing_id(-1), request_id(-1), options(0) {}
19 20
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() - 70 AppCacheHistograms::AddNetworkJobStartDelaySample(base::TimeTicks::Now() -
70 start_time_tick_); 71 start_time_tick_);
71 72
72 if (IsResourceTypeFrame(request_.resource_type)) { 73 if (IsResourceTypeFrame(request_.resource_type)) {
73 DCHECK(!main_resource_loader_callback_.is_null()); 74 DCHECK(!main_resource_loader_callback_.is_null());
74 // In network service land, if we are processing a navigation request, we 75 // In network service land, if we are processing a navigation request, we
75 // need to inform the loader callback that we are not going to handle this 76 // need to inform the loader callback that we are not going to handle this
76 // request. The loader callback is valid only for navigation requests. 77 // request. The loader callback is valid only for navigation requests.
77 std::move(main_resource_loader_callback_).Run(StartLoaderCallback()); 78 std::move(main_resource_loader_callback_).Run(StartLoaderCallback());
78 } else { 79 } else {
80 mojom::URLLoaderClientPtr client_ptr;
81 network_loader_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
82
79 default_url_loader_factory_getter_->GetNetworkFactory() 83 default_url_loader_factory_getter_->GetNetworkFactory()
80 ->get() 84 ->get()
81 ->CreateLoaderAndStart( 85 ->CreateLoaderAndStart(
82 mojo::MakeRequest(&network_loader_request_), 86 mojo::MakeRequest(&network_loader_),
83 subresource_load_info_->routing_id, 87 subresource_load_info_->routing_id,
84 subresource_load_info_->request_id, subresource_load_info_->options, 88 subresource_load_info_->request_id, subresource_load_info_->options,
85 subresource_load_info_->request, std::move(client_info_), 89 subresource_load_info_->request, std::move(client_ptr),
86 subresource_load_info_->traffic_annotation); 90 subresource_load_info_->traffic_annotation);
87 } 91 }
88 } 92 }
89 93
90 void AppCacheURLLoaderJob::DeliverErrorResponse() { 94 void AppCacheURLLoaderJob::DeliverErrorResponse() {
91 delivery_type_ = ERROR_DELIVERY; 95 delivery_type_ = ERROR_DELIVERY;
92 96
93 // We expect the URLLoaderClient pointer to be valid at this point. 97 // We expect the URLLoaderClient pointer to be valid at this point.
94 DCHECK(client_info_); 98 DCHECK(client_);
95 99
96 // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems 100 // AppCacheURLRequestJob uses ERR_FAILED as the error code here. That seems
97 // to map to HTTP_INTERNAL_SERVER_ERROR. 101 // to map to HTTP_INTERNAL_SERVER_ERROR.
98 std::string status("HTTP/1.1 "); 102 std::string status("HTTP/1.1 ");
99 status.append(base::IntToString(net::HTTP_INTERNAL_SERVER_ERROR)); 103 status.append(base::IntToString(net::HTTP_INTERNAL_SERVER_ERROR));
100 status.append(" "); 104 status.append(" ");
101 status.append(net::GetHttpReasonPhrase(net::HTTP_INTERNAL_SERVER_ERROR)); 105 status.append(net::GetHttpReasonPhrase(net::HTTP_INTERNAL_SERVER_ERROR));
102 status.append("\0\0", 2); 106 status.append("\0\0", 2);
103 107
104 ResourceResponseHead response; 108 ResourceResponseHead response;
105 response.headers = new net::HttpResponseHeaders(status); 109 response.headers = new net::HttpResponseHeaders(status);
106 client_info_->OnReceiveResponse(response, base::nullopt, nullptr); 110 client_->OnReceiveResponse(response, base::nullopt, nullptr);
107 111
108 NotifyCompleted(net::ERR_FAILED); 112 NotifyCompleted(net::ERR_FAILED);
109 113
110 AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() - 114 AppCacheHistograms::AddErrorJobStartDelaySample(base::TimeTicks::Now() -
111 start_time_tick_); 115 start_time_tick_);
112 } 116 }
113 117
114 const GURL& AppCacheURLLoaderJob::GetURL() const { 118 const GURL& AppCacheURLLoaderJob::GetURL() const {
115 return request_.url; 119 return request_.url;
116 } 120 }
117 121
118 AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() { 122 AppCacheURLLoaderJob* AppCacheURLLoaderJob::AsURLLoaderJob() {
119 return this; 123 return this;
120 } 124 }
121 125
122 void AppCacheURLLoaderJob::FollowRedirect() { 126 void AppCacheURLLoaderJob::FollowRedirect() {
123 if (network_loader_request_) 127 if (network_loader_)
124 network_loader_request_->FollowRedirect(); 128 network_loader_->FollowRedirect();
125 } 129 }
126 130
127 void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority, 131 void AppCacheURLLoaderJob::SetPriority(net::RequestPriority priority,
128 int32_t intra_priority_value) { 132 int32_t intra_priority_value) {
129 if (network_loader_request_) 133 if (network_loader_)
130 network_loader_request_->SetPriority(priority, intra_priority_value); 134 network_loader_->SetPriority(priority, intra_priority_value);
135 }
136
137 void AppCacheURLLoaderJob::OnReceiveResponse(
138 const ResourceResponseHead& response_head,
139 const base::Optional<net::SSLInfo>& ssl_info,
140 mojom::DownloadedTempFilePtr downloaded_file) {
141 appcache_request_->set_response(response_head);
142 // The MaybeLoadFallbackForResponse() call below can pass a fallback
143 // response to us. Reset the delivery_type_ to ensure that we can
144 // receive it
145 delivery_type_ = AWAITING_DELIVERY_ORDERS;
146 if (!sub_resource_handler_->MaybeLoadFallbackForResponse(nullptr)) {
147 client_->OnReceiveResponse(response_head, ssl_info,
148 std::move(downloaded_file));
149 } else {
150 // Disconnect from the network loader as we are delivering a fallback
151 // response to the client.
152 DisconnectFromNetworkLoader();
153 }
154 }
155
156 void AppCacheURLLoaderJob::OnReceiveRedirect(
157 const net::RedirectInfo& redirect_info,
158 const ResourceResponseHead& response_head) {
159 appcache_request_->set_response(response_head);
160 // The MaybeLoadFallbackForRedirect() call below can pass a fallback
161 // response to us. Reset the delivery_type_ to ensure that we can
162 // receive it
163 delivery_type_ = AWAITING_DELIVERY_ORDERS;
164 if (!sub_resource_handler_->MaybeLoadFallbackForRedirect(
165 nullptr, redirect_info.new_url)) {
166 client_->OnReceiveRedirect(redirect_info, response_head);
167 } else {
168 // Disconnect from the network loader as we are delivering a fallback
169 // response to the client.
170 DisconnectFromNetworkLoader();
171 }
172 }
173
174 void AppCacheURLLoaderJob::OnDataDownloaded(int64_t data_len,
175 int64_t encoded_data_len) {
176 client_->OnDataDownloaded(data_len, encoded_data_len);
177 }
178
179 void AppCacheURLLoaderJob::OnUploadProgress(
180 int64_t current_position,
181 int64_t total_size,
182 OnUploadProgressCallback ack_callback) {
183 client_->OnUploadProgress(current_position, total_size,
184 std::move(ack_callback));
185 }
186
187 void AppCacheURLLoaderJob::OnReceiveCachedMetadata(
188 const std::vector<uint8_t>& data) {
189 client_->OnReceiveCachedMetadata(data);
190 }
191
192 void AppCacheURLLoaderJob::OnTransferSizeUpdated(int32_t transfer_size_diff) {
193 client_->OnTransferSizeUpdated(transfer_size_diff);
194 }
195
196 void AppCacheURLLoaderJob::OnStartLoadingResponseBody(
197 mojo::ScopedDataPipeConsumerHandle body) {
198 client_->OnStartLoadingResponseBody(std::move(body));
199 }
200
201 void AppCacheURLLoaderJob::OnComplete(
202 const ResourceRequestCompletionStatus& status) {
203 delivery_type_ = AWAITING_DELIVERY_ORDERS;
204 if (!sub_resource_handler_->MaybeLoadFallbackForResponse(nullptr)) {
205 client_->OnComplete(status);
206 } else {
207 // Disconnect from the network loader as we are delivering a fallback
208 // response to the client.
209 DisconnectFromNetworkLoader();
210 }
131 } 211 }
132 212
133 void AppCacheURLLoaderJob::SetSubresourceLoadInfo( 213 void AppCacheURLLoaderJob::SetSubresourceLoadInfo(
134 std::unique_ptr<SubresourceLoadInfo> subresource_load_info, 214 std::unique_ptr<SubresourceLoadInfo> subresource_load_info,
135 URLLoaderFactoryGetter* default_url_loader) { 215 URLLoaderFactoryGetter* default_url_loader) {
136 subresource_load_info_ = std::move(subresource_load_info); 216 subresource_load_info_ = std::move(subresource_load_info);
137 217
138 associated_binding_.reset(new mojo::AssociatedBinding<mojom::URLLoader>( 218 associated_binding_.reset(new mojo::AssociatedBinding<mojom::URLLoader>(
139 this, std::move(subresource_load_info_->url_loader_request))); 219 this, std::move(subresource_load_info_->url_loader_request)));
140 associated_binding_->set_connection_error_handler(base::Bind( 220 associated_binding_->set_connection_error_handler(base::Bind(
141 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this))); 221 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
142 222
143 client_info_ = std::move(subresource_load_info_->client); 223 client_ = std::move(subresource_load_info_->client);
144 default_url_loader_factory_getter_ = default_url_loader; 224 default_url_loader_factory_getter_ = default_url_loader;
145 } 225 }
146 226
147 void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request, 227 void AppCacheURLLoaderJob::Start(mojom::URLLoaderRequest request,
148 mojom::URLLoaderClientPtr client) { 228 mojom::URLLoaderClientPtr client) {
149 DCHECK(!binding_.is_bound()); 229 DCHECK(!binding_.is_bound());
150 binding_.Bind(std::move(request)); 230 binding_.Bind(std::move(request));
151 231
152 binding_.set_connection_error_handler(base::Bind( 232 binding_.set_connection_error_handler(base::Bind(
153 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this))); 233 &AppCacheURLLoaderJob::OnConnectionError, StaticAsWeakPtr(this)));
154 234
155 client_info_ = std::move(client); 235 client_ = std::move(client);
156 236
157 // Send the cached AppCacheResponse if any. 237 // Send the cached AppCacheResponse if any.
158 if (info_.get()) 238 if (info_.get())
159 SendResponseInfo(); 239 SendResponseInfo();
160 } 240 }
161 241
162 AppCacheURLLoaderJob::AppCacheURLLoaderJob(const ResourceRequest& request, 242 AppCacheURLLoaderJob::AppCacheURLLoaderJob(
163 AppCacheStorage* storage) 243 const ResourceRequest& request,
244 AppCacheURLLoaderRequest* appcache_request,
245 AppCacheStorage* storage)
164 : request_(request), 246 : request_(request),
165 storage_(storage->GetWeakPtr()), 247 storage_(storage->GetWeakPtr()),
166 start_time_tick_(base::TimeTicks::Now()), 248 start_time_tick_(base::TimeTicks::Now()),
167 cache_id_(kAppCacheNoCacheId), 249 cache_id_(kAppCacheNoCacheId),
168 is_fallback_(false), 250 is_fallback_(false),
169 binding_(this), 251 binding_(this),
170 writable_handle_watcher_(FROM_HERE, 252 writable_handle_watcher_(FROM_HERE,
171 mojo::SimpleWatcher::ArmingPolicy::MANUAL) {} 253 mojo::SimpleWatcher::ArmingPolicy::MANUAL),
254 network_loader_client_binding_(this),
255 appcache_request_(appcache_request) {}
172 256
173 void AppCacheURLLoaderJob::OnResponseInfoLoaded( 257 void AppCacheURLLoaderJob::OnResponseInfoLoaded(
174 AppCacheResponseInfo* response_info, 258 AppCacheResponseInfo* response_info,
175 int64_t response_id) { 259 int64_t response_id) {
176 DCHECK(IsDeliveringAppCacheResponse()); 260 DCHECK(IsDeliveringAppCacheResponse());
177 261
178 if (!storage_.get()) { 262 if (!storage_.get()) {
179 DeliverErrorResponse(); 263 DeliverErrorResponse();
180 return; 264 return;
181 } 265 }
(...skipping 17 matching lines...) Expand all
199 // TODO(ananta) 283 // TODO(ananta)
200 // Move the asynchronous reading and mojo pipe handling code to a helper 284 // Move the asynchronous reading and mojo pipe handling code to a helper
201 // class. That would also need a change to BlobURLLoader. 285 // class. That would also need a change to BlobURLLoader.
202 286
203 // Wait for the data pipe to be ready to accept data. 287 // Wait for the data pipe to be ready to accept data.
204 writable_handle_watcher_.Watch( 288 writable_handle_watcher_.Watch(
205 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, 289 response_body_stream_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
206 base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady, 290 base::Bind(&AppCacheURLLoaderJob::OnResponseBodyStreamReady,
207 StaticAsWeakPtr(this))); 291 StaticAsWeakPtr(this)));
208 292
209 if (client_info_) 293 if (client_)
210 SendResponseInfo(); 294 SendResponseInfo();
211 295
212 ReadMore(); 296 ReadMore();
213 } else { 297 } else {
214 // Error case here. We fallback to the network. 298 // Error case here. We fallback to the network.
215 DeliverNetworkResponse(); 299 DeliverNetworkResponse();
216 AppCacheHistograms::CountResponseRetrieval( 300 AppCacheHistograms::CountResponseRetrieval(
217 false, IsResourceTypeFrame(request_.resource_type), 301 false, IsResourceTypeFrame(request_.resource_type),
218 manifest_url_.GetOrigin()); 302 manifest_url_.GetOrigin());
219 303
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 ReadMore(); 337 ReadMore();
254 } 338 }
255 339
256 void AppCacheURLLoaderJob::OnConnectionError() { 340 void AppCacheURLLoaderJob::OnConnectionError() {
257 if (storage_.get()) 341 if (storage_.get())
258 storage_->CancelDelegateCallbacks(this); 342 storage_->CancelDelegateCallbacks(this);
259 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); 343 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
260 } 344 }
261 345
262 void AppCacheURLLoaderJob::SendResponseInfo() { 346 void AppCacheURLLoaderJob::SendResponseInfo() {
263 DCHECK(client_info_); 347 DCHECK(client_);
264 // If this is null it means the response information was sent to the client. 348 // If this is null it means the response information was sent to the client.
265 if (!data_pipe_.consumer_handle.is_valid()) 349 if (!data_pipe_.consumer_handle.is_valid())
266 return; 350 return;
267 351
268 const net::HttpResponseInfo* http_info = is_range_request() 352 const net::HttpResponseInfo* http_info = is_range_request()
269 ? range_response_info_.get() 353 ? range_response_info_.get()
270 : info_->http_response_info(); 354 : info_->http_response_info();
271 355
272 ResourceResponseHead response_head; 356 ResourceResponseHead response_head;
273 response_head.headers = http_info->headers; 357 response_head.headers = http_info->headers;
(...skipping 12 matching lines...) Expand all
286 : info_->response_data_size(); 370 : info_->response_data_size();
287 371
288 response_head.connection_info = http_info->connection_info; 372 response_head.connection_info = http_info->connection_info;
289 response_head.socket_address = http_info->socket_address; 373 response_head.socket_address = http_info->socket_address;
290 response_head.was_fetched_via_spdy = http_info->was_fetched_via_spdy; 374 response_head.was_fetched_via_spdy = http_info->was_fetched_via_spdy;
291 response_head.was_alpn_negotiated = http_info->was_alpn_negotiated; 375 response_head.was_alpn_negotiated = http_info->was_alpn_negotiated;
292 response_head.alpn_negotiated_protocol = http_info->alpn_negotiated_protocol; 376 response_head.alpn_negotiated_protocol = http_info->alpn_negotiated_protocol;
293 377
294 response_head.load_timing = load_timing_info_; 378 response_head.load_timing = load_timing_info_;
295 379
296 client_info_->OnReceiveResponse(response_head, http_info->ssl_info, 380 appcache_request_->set_response(response_head);
297 mojom::DownloadedTempFilePtr());
298 381
299 client_info_->OnStartLoadingResponseBody( 382 client_->OnReceiveResponse(response_head, http_info->ssl_info,
300 std::move(data_pipe_.consumer_handle)); 383 mojom::DownloadedTempFilePtr());
384
385 client_->OnStartLoadingResponseBody(std::move(data_pipe_.consumer_handle));
301 } 386 }
302 387
303 void AppCacheURLLoaderJob::ReadMore() { 388 void AppCacheURLLoaderJob::ReadMore() {
304 DCHECK(!pending_write_.get()); 389 DCHECK(!pending_write_.get());
305 390
306 uint32_t num_bytes; 391 uint32_t num_bytes;
307 // TODO: we should use the abstractions in MojoAsyncResourceHandler. 392 // TODO: we should use the abstractions in MojoAsyncResourceHandler.
308 MojoResult result = NetToMojoPendingBuffer::BeginWrite( 393 MojoResult result = NetToMojoPendingBuffer::BeginWrite(
309 &response_body_stream_, &pending_write_, &num_bytes); 394 &response_body_stream_, &pending_write_, &num_bytes);
310 if (result == MOJO_RESULT_SHOULD_WAIT) { 395 if (result == MOJO_RESULT_SHOULD_WAIT) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 // case of an error. 441 // case of an error.
357 if (!request_complete_data.error_code) { 442 if (!request_complete_data.error_code) {
358 request_complete_data.exists_in_cache = http_info->was_cached; 443 request_complete_data.exists_in_cache = http_info->was_cached;
359 request_complete_data.completion_time = base::TimeTicks::Now(); 444 request_complete_data.completion_time = base::TimeTicks::Now();
360 request_complete_data.encoded_body_length = 445 request_complete_data.encoded_body_length =
361 is_range_request() ? range_response_info_->headers->GetContentLength() 446 is_range_request() ? range_response_info_->headers->GetContentLength()
362 : info_->response_data_size(); 447 : info_->response_data_size();
363 request_complete_data.decoded_body_length = 448 request_complete_data.decoded_body_length =
364 request_complete_data.encoded_body_length; 449 request_complete_data.encoded_body_length;
365 } 450 }
366 client_info_->OnComplete(request_complete_data); 451 client_->OnComplete(request_complete_data);
452 }
453
454 void AppCacheURLLoaderJob::DisconnectFromNetworkLoader() {
455 // Close the pipe to the network loader as we are delivering a fallback
456 // response to the client.
457 network_loader_client_binding_.Close();
458 network_loader_ = nullptr;
367 } 459 }
368 460
369 } // namespace content 461 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/appcache/appcache_url_loader_job.h ('k') | content/browser/appcache/appcache_url_loader_request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698