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

Side by Side Diff: content/browser/loader/navigation_url_loader_network_service.cc

Issue 2982363002: Add support for fallback content for the frame. This includes main and subframes. (Closed)
Patch Set: rebase to tip Created 3 years, 4 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 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/loader/navigation_url_loader_network_service.h" 5 #include "content/browser/loader/navigation_url_loader_network_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 : public mojom::URLLoaderClient { 98 : public mojom::URLLoaderClient {
99 public: 99 public:
100 URLLoaderRequestController( 100 URLLoaderRequestController(
101 std::unique_ptr<ResourceRequest> resource_request, 101 std::unique_ptr<ResourceRequest> resource_request,
102 ResourceContext* resource_context, 102 ResourceContext* resource_context,
103 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter, 103 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter,
104 const base::WeakPtr<NavigationURLLoaderNetworkService>& owner) 104 const base::WeakPtr<NavigationURLLoaderNetworkService>& owner)
105 : resource_request_(std::move(resource_request)), 105 : resource_request_(std::move(resource_request)),
106 resource_context_(resource_context), 106 resource_context_(resource_context),
107 default_url_loader_factory_getter_(default_url_loader_factory_getter), 107 default_url_loader_factory_getter_(default_url_loader_factory_getter),
108 owner_(owner) {} 108 owner_(owner),
109 response_loader_binding_(this) {}
109 110
110 ~URLLoaderRequestController() override { 111 ~URLLoaderRequestController() override {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO); 112 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 } 113 }
113 114
114 void Start( 115 void Start(
115 ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core, 116 ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
116 AppCacheNavigationHandleCore* appcache_handle_core, 117 AppCacheNavigationHandleCore* appcache_handle_core,
117 std::unique_ptr<NavigationRequestInfo> request_info, 118 std::unique_ptr<NavigationRequestInfo> request_info,
118 mojom::URLLoaderFactoryPtrInfo factory_for_webui, 119 mojom::URLLoaderFactoryPtrInfo factory_for_webui,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 if (appcache_handler) 171 if (appcache_handler)
171 handlers_.push_back(std::move(appcache_handler)); 172 handlers_.push_back(std::move(appcache_handler));
172 } 173 }
173 174
174 Restart(); 175 Restart();
175 } 176 }
176 177
177 // This could be called multiple times. 178 // This could be called multiple times.
178 void Restart() { 179 void Restart() {
179 handler_index_ = 0; 180 handler_index_ = 0;
181 received_response_ = false;
180 MaybeStartLoader(StartLoaderCallback()); 182 MaybeStartLoader(StartLoaderCallback());
181 } 183 }
182 184
183 void MaybeStartLoader(StartLoaderCallback start_loader_callback) { 185 void MaybeStartLoader(StartLoaderCallback start_loader_callback) {
184 if (start_loader_callback) { 186 if (start_loader_callback) {
185 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( 187 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
186 std::move(start_loader_callback), 188 std::move(start_loader_callback),
187 GetContentClient()->browser()->CreateURLLoaderThrottles( 189 GetContentClient()->browser()->CreateURLLoaderThrottles(
188 web_contents_getter_), 190 web_contents_getter_),
189 *resource_request_, this, kTrafficAnnotation); 191 *resource_request_, this, kTrafficAnnotation);
(...skipping 16 matching lines...) Expand all
206 base::Unretained(this))); 208 base::Unretained(this)));
207 return; 209 return;
208 } 210 }
209 211
210 mojom::URLLoaderFactory* factory = nullptr; 212 mojom::URLLoaderFactory* factory = nullptr;
211 DCHECK_EQ(handlers_.size(), handler_index_); 213 DCHECK_EQ(handlers_.size(), handler_index_);
212 if (resource_request_->url.SchemeIs(url::kBlobScheme)) { 214 if (resource_request_->url.SchemeIs(url::kBlobScheme)) {
213 factory = default_url_loader_factory_getter_->GetBlobFactory()->get(); 215 factory = default_url_loader_factory_getter_->GetBlobFactory()->get();
214 } else { 216 } else {
215 factory = default_url_loader_factory_getter_->GetNetworkFactory()->get(); 217 factory = default_url_loader_factory_getter_->GetNetworkFactory()->get();
218 default_loader_used_ = true;
216 } 219 }
217 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( 220 url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
218 factory, 221 factory,
219 GetContentClient()->browser()->CreateURLLoaderThrottles( 222 GetContentClient()->browser()->CreateURLLoaderThrottles(
220 web_contents_getter_), 223 web_contents_getter_),
221 0 /* routing_id? */, 0 /* request_id? */, 224 0 /* routing_id? */, 0 /* request_id? */,
222 mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType, 225 mojom::kURLLoadOptionSendSSLInfo | mojom::kURLLoadOptionSniffMimeType,
223 *resource_request_, this, kTrafficAnnotation); 226 *resource_request_, this, kTrafficAnnotation);
224 } 227 }
225 228
226 void FollowRedirect() { 229 void FollowRedirect() {
227 DCHECK_CURRENTLY_ON(BrowserThread::IO); 230 DCHECK_CURRENTLY_ON(BrowserThread::IO);
228 DCHECK(url_loader_); 231 DCHECK(url_loader_);
229 232
233 DCHECK(!response_url_loader_);
234
230 url_loader_->FollowRedirect(); 235 url_loader_->FollowRedirect();
231 } 236 }
232 237
233 // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the 238 // Ownership of the URLLoaderFactoryPtrInfo instance is transferred to the
234 // caller. 239 // caller.
235 mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() { 240 mojom::URLLoaderFactoryPtrInfo GetSubresourceURLLoaderFactory() {
236 return std::move(subresource_url_loader_factory_ptr_info_); 241 return std::move(subresource_url_loader_factory_ptr_info_);
237 } 242 }
238 243
239 private: 244 private:
240 // mojom::URLLoaderClient implementation: 245 // mojom::URLLoaderClient implementation:
241 void OnReceiveResponse( 246 void OnReceiveResponse(
242 const ResourceResponseHead& head, 247 const ResourceResponseHead& head,
243 const base::Optional<net::SSLInfo>& ssl_info, 248 const base::Optional<net::SSLInfo>& ssl_info,
244 mojom::DownloadedTempFilePtr downloaded_file) override { 249 mojom::DownloadedTempFilePtr downloaded_file) override {
250 received_response_ = true;
251 // If the default loader (network) was used to handle the URL load request
252 // we need to see if the handlers want to potentially create a new loader
253 // for the response. e.g. AppCache.
254 if (MaybeCreateLoaderForResponse(head))
255 return;
256
245 BrowserThread::PostTask( 257 BrowserThread::PostTask(
246 BrowserThread::UI, FROM_HERE, 258 BrowserThread::UI, FROM_HERE,
247 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse, 259 base::Bind(&NavigationURLLoaderNetworkService::OnReceiveResponse,
248 owner_, head, ssl_info, base::Passed(&downloaded_file))); 260 owner_, head, ssl_info, base::Passed(&downloaded_file)));
249 } 261 }
250 262
251 void OnReceiveRedirect(const net::RedirectInfo& redirect_info, 263 void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
252 const ResourceResponseHead& head) override { 264 const ResourceResponseHead& head) override {
253 BrowserThread::PostTask( 265 BrowserThread::PostTask(
254 BrowserThread::UI, FROM_HERE, 266 BrowserThread::UI, FROM_HERE,
(...skipping 15 matching lines...) Expand all
270 mojo::ScopedDataPipeConsumerHandle body) override { 282 mojo::ScopedDataPipeConsumerHandle body) override {
271 BrowserThread::PostTask( 283 BrowserThread::PostTask(
272 BrowserThread::UI, FROM_HERE, 284 BrowserThread::UI, FROM_HERE,
273 base::Bind( 285 base::Bind(
274 &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody, 286 &NavigationURLLoaderNetworkService::OnStartLoadingResponseBody,
275 owner_, base::Passed(&body))); 287 owner_, base::Passed(&body)));
276 } 288 }
277 289
278 void OnComplete( 290 void OnComplete(
279 const ResourceRequestCompletionStatus& completion_status) override { 291 const ResourceRequestCompletionStatus& completion_status) override {
292 if (completion_status.error_code != net::OK && !received_response_) {
293 // If the default loader (network) was used to handle the URL load
294 // request we need to see if the handlers want to potentially create a
295 // new loader for the response. e.g. AppCache.
296 if (MaybeCreateLoaderForResponse(ResourceResponseHead()))
297 return;
298 }
280 BrowserThread::PostTask( 299 BrowserThread::PostTask(
281 BrowserThread::UI, FROM_HERE, 300 BrowserThread::UI, FROM_HERE,
282 base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_, 301 base::Bind(&NavigationURLLoaderNetworkService::OnComplete, owner_,
283 completion_status)); 302 completion_status));
284 } 303 }
285 304
305 // Returns true if a handler wants to handle the response, i.e. return a
306 // different response. For e.g. AppCache may have fallback content to be
307 // returned for a TLD.
308 bool MaybeCreateLoaderForResponse(const ResourceResponseHead& response) {
309 if (!default_loader_used_)
310 return false;
311
312 // URLLoaderClient request pointer for response loaders, i.e loaders created
313 // for handing responses received from the network URLLoader.
314 mojom::URLLoaderClientRequest response_client_request;
315
316 for (size_t index = 0; index < handlers_.size(); ++index) {
317 if (handlers_[index]->MaybeCreateLoaderForResponse(
318 response, &response_url_loader_, &response_client_request)) {
319 OnResponseHandlerFound(std::move(response_client_request));
320 return true;
321 }
322 }
323 return false;
324 }
325
326 // Called if we find a handler who delivers different content for the URL.
327 void OnResponseHandlerFound(
328 mojom::URLLoaderClientRequest response_client_request) {
329 response_loader_binding_.Bind(std::move(response_client_request));
330 // We reset this flag as we expect a new response from the handler.
331 default_loader_used_ = false;
332 // Disconnect from the network loader to stop receiving further data
333 // or notifications for the URL.
334 url_loader_->DisconnectClient();
335 }
336
286 std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_; 337 std::vector<std::unique_ptr<URLLoaderRequestHandler>> handlers_;
287 size_t handler_index_ = 0; 338 size_t handler_index_ = 0;
288 339
289 std::unique_ptr<ResourceRequest> resource_request_; 340 std::unique_ptr<ResourceRequest> resource_request_;
290 ResourceContext* resource_context_; 341 ResourceContext* resource_context_;
291 base::Callback<WebContents*()> web_contents_getter_; 342 base::Callback<WebContents*()> web_contents_getter_;
292 343
293 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_; 344 scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
294 345
295 mojom::URLLoaderFactoryPtr webui_factory_ptr_; 346 mojom::URLLoaderFactoryPtr webui_factory_ptr_;
296 347
297 std::unique_ptr<ThrottlingURLLoader> url_loader_; 348 std::unique_ptr<ThrottlingURLLoader> url_loader_;
298 349
299 BlobHandles blob_handles_; 350 BlobHandles blob_handles_;
300 351
301 // Currently used by the AppCache loader to pass its factory to the 352 // Currently used by the AppCache loader to pass its factory to the
302 // renderer which enables it to handle subresources. 353 // renderer which enables it to handle subresources.
303 mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_; 354 mojom::URLLoaderFactoryPtrInfo subresource_url_loader_factory_ptr_info_;
304 355
305 // This is referenced only on the UI thread. 356 // This is referenced only on the UI thread.
306 base::WeakPtr<NavigationURLLoaderNetworkService> owner_; 357 base::WeakPtr<NavigationURLLoaderNetworkService> owner_;
307 358
359 // Set to true if the default URLLoader (network service) was used for the
360 // current navigation.
361 bool default_loader_used_ = false;
362
363 // URLLoaderClient binding for loaders created for responses received from the
364 // network loader.
365 mojo::Binding<mojom::URLLoaderClient> response_loader_binding_;
366
367 // URLLoader instance for response loaders, i.e loaders created for handing
368 // responses received from the network URLLoader.
369 mojom::URLLoaderPtr response_url_loader_;
370
371 // Set to true if we receive a valid response from a URLLoader, i.e.
372 // URLLoaderClient::OnReceivedResponse() is called.
373 bool received_response_ = false;
374
308 DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); 375 DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
309 }; 376 };
310 377
311 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( 378 NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService(
312 ResourceContext* resource_context, 379 ResourceContext* resource_context,
313 StoragePartition* storage_partition, 380 StoragePartition* storage_partition,
314 std::unique_ptr<NavigationRequestInfo> request_info, 381 std::unique_ptr<NavigationRequestInfo> request_info,
315 std::unique_ptr<NavigationUIData> navigation_ui_data, 382 std::unique_ptr<NavigationUIData> navigation_ui_data,
316 ServiceWorkerNavigationHandle* service_worker_navigation_handle, 383 ServiceWorkerNavigationHandle* service_worker_navigation_handle,
317 AppCacheNavigationHandle* appcache_handle, 384 AppCacheNavigationHandle* appcache_handle,
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", 520 TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted",
454 this, "&NavigationURLLoaderNetworkService", this, 521 this, "&NavigationURLLoaderNetworkService", this,
455 "success", false); 522 "success", false);
456 523
457 delegate_->OnRequestFailed(completion_status.exists_in_cache, 524 delegate_->OnRequestFailed(completion_status.exists_in_cache,
458 completion_status.error_code); 525 completion_status.error_code);
459 } 526 }
460 } 527 }
461 528
462 } // namespace content 529 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/appcache/appcache_url_loader_job.cc ('k') | content/browser/loader/url_loader_request_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698