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

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

Issue 1041993004: content::ResourceDispatcherHostImpl changes for stale-while-revalidate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@s-w-r-yhirano-patch
Patch Set: Cleanups from tyoshino review. Created 5 years, 6 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading
6 6
7 #include "content/browser/loader/resource_dispatcher_host_impl.h" 7 #include "content/browser/loader/resource_dispatcher_host_impl.h"
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <set> 10 #include <set>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/debug/alias.h" 17 #include "base/debug/alias.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
20 #include "base/memory/shared_memory.h" 20 #include "base/memory/shared_memory.h"
21 #include "base/message_loop/message_loop.h" 21 #include "base/message_loop/message_loop.h"
22 #include "base/metrics/field_trial.h"
22 #include "base/metrics/histogram_macros.h" 23 #include "base/metrics/histogram_macros.h"
23 #include "base/metrics/sparse_histogram.h" 24 #include "base/metrics/sparse_histogram.h"
24 #include "base/profiler/scoped_tracker.h" 25 #include "base/profiler/scoped_tracker.h"
25 #include "base/stl_util.h" 26 #include "base/stl_util.h"
26 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 27 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
27 #include "base/time/time.h" 28 #include "base/time/time.h"
28 #include "content/browser/appcache/appcache_interceptor.h" 29 #include "content/browser/appcache/appcache_interceptor.h"
29 #include "content/browser/appcache/chrome_appcache_service.h" 30 #include "content/browser/appcache/chrome_appcache_service.h"
30 #include "content/browser/cert_store_impl.h" 31 #include "content/browser/cert_store_impl.h"
31 #include "content/browser/child_process_security_policy_impl.h" 32 #include "content/browser/child_process_security_policy_impl.h"
32 #include "content/browser/download/download_resource_handler.h" 33 #include "content/browser/download/download_resource_handler.h"
33 #include "content/browser/download/save_file_manager.h" 34 #include "content/browser/download/save_file_manager.h"
34 #include "content/browser/download/save_file_resource_handler.h" 35 #include "content/browser/download/save_file_resource_handler.h"
35 #include "content/browser/fileapi/chrome_blob_storage_context.h" 36 #include "content/browser/fileapi/chrome_blob_storage_context.h"
36 #include "content/browser/frame_host/navigation_request_info.h" 37 #include "content/browser/frame_host/navigation_request_info.h"
37 #include "content/browser/frame_host/navigator.h" 38 #include "content/browser/frame_host/navigator.h"
38 #include "content/browser/loader/async_resource_handler.h" 39 #include "content/browser/loader/async_resource_handler.h"
39 #include "content/browser/loader/buffered_resource_handler.h" 40 #include "content/browser/loader/buffered_resource_handler.h"
40 #include "content/browser/loader/cross_site_resource_handler.h" 41 #include "content/browser/loader/cross_site_resource_handler.h"
41 #include "content/browser/loader/detachable_resource_handler.h" 42 #include "content/browser/loader/detachable_resource_handler.h"
42 #include "content/browser/loader/navigation_resource_handler.h" 43 #include "content/browser/loader/navigation_resource_handler.h"
43 #include "content/browser/loader/navigation_url_loader_impl_core.h" 44 #include "content/browser/loader/navigation_url_loader_impl_core.h"
45 #include "content/browser/loader/null_resource_handler.h"
44 #include "content/browser/loader/power_save_block_resource_throttle.h" 46 #include "content/browser/loader/power_save_block_resource_throttle.h"
45 #include "content/browser/loader/redirect_to_file_resource_handler.h" 47 #include "content/browser/loader/redirect_to_file_resource_handler.h"
46 #include "content/browser/loader/resource_message_filter.h" 48 #include "content/browser/loader/resource_message_filter.h"
47 #include "content/browser/loader/resource_request_info_impl.h" 49 #include "content/browser/loader/resource_request_info_impl.h"
48 #include "content/browser/loader/stream_resource_handler.h" 50 #include "content/browser/loader/stream_resource_handler.h"
49 #include "content/browser/loader/sync_resource_handler.h" 51 #include "content/browser/loader/sync_resource_handler.h"
50 #include "content/browser/loader/throttling_resource_handler.h" 52 #include "content/browser/loader/throttling_resource_handler.h"
51 #include "content/browser/loader/upload_data_stream_builder.h" 53 #include "content/browser/loader/upload_data_stream_builder.h"
52 #include "content/browser/renderer_host/render_view_host_delegate.h" 54 #include "content/browser/renderer_host/render_view_host_delegate.h"
53 #include "content/browser/renderer_host/render_view_host_impl.h" 55 #include "content/browser/renderer_host/render_view_host_impl.h"
(...skipping 28 matching lines...) Expand all
82 #include "net/base/load_flags.h" 84 #include "net/base/load_flags.h"
83 #include "net/base/mime_util.h" 85 #include "net/base/mime_util.h"
84 #include "net/base/net_errors.h" 86 #include "net/base/net_errors.h"
85 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 87 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
86 #include "net/base/request_priority.h" 88 #include "net/base/request_priority.h"
87 #include "net/base/upload_data_stream.h" 89 #include "net/base/upload_data_stream.h"
88 #include "net/cert/cert_status_flags.h" 90 #include "net/cert/cert_status_flags.h"
89 #include "net/cookies/cookie_monster.h" 91 #include "net/cookies/cookie_monster.h"
90 #include "net/http/http_response_headers.h" 92 #include "net/http/http_response_headers.h"
91 #include "net/http/http_response_info.h" 93 #include "net/http/http_response_info.h"
94 #include "net/http/http_transaction_factory.h"
95 #include "net/http/http_util.h"
92 #include "net/ssl/ssl_cert_request_info.h" 96 #include "net/ssl/ssl_cert_request_info.h"
93 #include "net/url_request/url_request.h" 97 #include "net/url_request/url_request.h"
94 #include "net/url_request/url_request_context.h" 98 #include "net/url_request/url_request_context.h"
95 #include "net/url_request/url_request_job_factory.h" 99 #include "net/url_request/url_request_job_factory.h"
96 #include "storage/browser/blob/blob_data_handle.h" 100 #include "storage/browser/blob/blob_data_handle.h"
97 #include "storage/browser/blob/blob_storage_context.h" 101 #include "storage/browser/blob/blob_storage_context.h"
98 #include "storage/browser/blob/blob_url_request_job_factory.h" 102 #include "storage/browser/blob/blob_url_request_job_factory.h"
99 #include "storage/browser/blob/shareable_file_reference.h" 103 #include "storage/browser/blob/shareable_file_reference.h"
100 #include "storage/browser/fileapi/file_permission_policy.h" 104 #include "storage/browser/fileapi/file_permission_policy.h"
101 #include "storage/browser/fileapi/file_system_context.h" 105 #include "storage/browser/fileapi/file_system_context.h"
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 DCHECK_CURRENTLY_ON(BrowserThread::UI); 413 DCHECK_CURRENTLY_ON(BrowserThread::UI);
410 RenderFrameHostImpl* host = 414 RenderFrameHostImpl* host =
411 RenderFrameHostImpl::FromID(render_process_id, render_frame_id); 415 RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
412 if (host != NULL) { 416 if (host != NULL) {
413 DCHECK(host->frame_tree_node()->IsMainFrame()); 417 DCHECK(host->frame_tree_node()->IsMainFrame());
414 host->frame_tree_node()->navigator()->LogResourceRequestTime( 418 host->frame_tree_node()->navigator()->LogResourceRequestTime(
415 timestamp, url); 419 timestamp, url);
416 } 420 }
417 } 421 }
418 422
423 bool QualifiesForAsyncRevalidation(const ResourceHostMsg_Request& request) {
424 if (request.load_flags &
425 (net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
426 net::LOAD_VALIDATE_CACHE | net::LOAD_PREFERRING_CACHE |
427 net::LOAD_ONLY_FROM_CACHE)) {
428 return false;
429 }
430 if (request.method != "GET")
431 return false;
432 // A GET request should not have a body, but don't leave it to chance.
433 if (request.request_body.get())
434 return false;
435 if (!request.url.SchemeIsHTTPOrHTTPS())
436 return false;
437 return true;
438 }
439
440 std::pair<net::HttpCache*, std::string> AsyncRevalidationKey(
tyoshino (SeeGerritForStatus) 2015/06/15 09:30:39 how about GetAsyncRevalidationKeyFor? or Create..
Adam Rice 2015/06/15 11:36:20 I chose GenerateAsyncRevalidationKeyFor() to be li
441 net::HttpTransactionFactory* http_transaction_factory,
442 const GURL& url) {
443 net::HttpCache* http_cache = http_transaction_factory->GetCache();
444 std::string url_key = net::HttpUtil::SpecForRequest(url);
445 return std::make_pair(http_cache, url_key);
446 }
447
419 } // namespace 448 } // namespace
420 449
421 // static 450 // static
422 ResourceDispatcherHost* ResourceDispatcherHost::Get() { 451 ResourceDispatcherHost* ResourceDispatcherHost::Get() {
423 return g_resource_dispatcher_host; 452 return g_resource_dispatcher_host;
424 } 453 }
425 454
426 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() 455 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl()
427 : save_file_manager_(new SaveFileManager()), 456 : save_file_manager_(new SaveFileManager()),
428 request_id_(-1), 457 request_id_(-1),
429 is_shutdown_(false), 458 is_shutdown_(false),
430 num_in_flight_requests_(0), 459 num_in_flight_requests_(0),
431 max_num_in_flight_requests_(base::SharedMemory::GetHandleLimit()), 460 max_num_in_flight_requests_(base::SharedMemory::GetHandleLimit()),
432 max_num_in_flight_requests_per_process_( 461 max_num_in_flight_requests_per_process_(static_cast<int>(
433 static_cast<int>( 462 max_num_in_flight_requests_ * kMaxRequestsPerProcessRatio)),
434 max_num_in_flight_requests_ * kMaxRequestsPerProcessRatio)),
435 max_outstanding_requests_cost_per_process_( 463 max_outstanding_requests_cost_per_process_(
436 kMaxOutstandingRequestsCostPerProcess), 464 kMaxOutstandingRequestsCostPerProcess),
437 filter_(NULL), 465 filter_(NULL),
438 delegate_(NULL), 466 delegate_(NULL),
439 allow_cross_origin_auth_prompt_(false) { 467 allow_cross_origin_auth_prompt_(false),
468 async_revalidation_enabled_(false) {
440 DCHECK_CURRENTLY_ON(BrowserThread::UI); 469 DCHECK_CURRENTLY_ON(BrowserThread::UI);
441 DCHECK(!g_resource_dispatcher_host); 470 DCHECK(!g_resource_dispatcher_host);
442 g_resource_dispatcher_host = this; 471 g_resource_dispatcher_host = this;
443 472
444 GetContentClient()->browser()->ResourceDispatcherHostCreated(); 473 GetContentClient()->browser()->ResourceDispatcherHostCreated();
445 474
446 ANNOTATE_BENIGN_RACE( 475 ANNOTATE_BENIGN_RACE(
447 &last_user_gesture_time_, 476 &last_user_gesture_time_,
448 "We don't care about the precise value, see http://crbug.com/92889"); 477 "We don't care about the precise value, see http://crbug.com/92889");
449 478
450 BrowserThread::PostTask(BrowserThread::IO, 479 BrowserThread::PostTask(BrowserThread::IO,
451 FROM_HERE, 480 FROM_HERE,
452 base::Bind(&ResourceDispatcherHostImpl::OnInit, 481 base::Bind(&ResourceDispatcherHostImpl::OnInit,
453 base::Unretained(this))); 482 base::Unretained(this)));
454 483
455 update_load_states_timer_.reset( 484 update_load_states_timer_.reset(
456 new base::RepeatingTimer<ResourceDispatcherHostImpl>()); 485 new base::RepeatingTimer<ResourceDispatcherHostImpl>());
486
487 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
488 if (base::FieldTrialList::FindFullName("StaleWhileRevalidate") == "Enabled" ||
489 command_line->HasSwitch(switches::kEnableStaleWhileRevalidate)) {
490 async_revalidation_enabled_ = true;
491 }
457 } 492 }
458 493
459 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { 494 ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() {
460 DCHECK(outstanding_requests_stats_map_.empty()); 495 DCHECK(outstanding_requests_stats_map_.empty());
461 DCHECK(g_resource_dispatcher_host); 496 DCHECK(g_resource_dispatcher_host);
462 g_resource_dispatcher_host = NULL; 497 g_resource_dispatcher_host = NULL;
463 } 498 }
464 499
465 // static 500 // static
466 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() { 501 ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() {
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 new_url)); 847 new_url));
813 BrowserThread::PostTask( 848 BrowserThread::PostTask(
814 BrowserThread::UI, FROM_HERE, 849 BrowserThread::UI, FROM_HERE,
815 base::Bind( 850 base::Bind(
816 &NotifyRedirectOnUI, 851 &NotifyRedirectOnUI,
817 render_process_id, render_frame_host, base::Passed(&detail))); 852 render_process_id, render_frame_host, base::Passed(&detail)));
818 } 853 }
819 854
820 void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) { 855 void ResourceDispatcherHostImpl::DidReceiveResponse(ResourceLoader* loader) {
821 ResourceRequestInfoImpl* info = loader->GetRequestInfo(); 856 ResourceRequestInfoImpl* info = loader->GetRequestInfo();
822 857 net::URLRequest* request = loader->request();
823 if (loader->request()->was_fetched_via_proxy() && 858 if (request->was_fetched_via_proxy() &&
824 loader->request()->was_fetched_via_spdy() && 859 request->was_fetched_via_spdy() &&
825 loader->request()->url().SchemeIs(url::kHttpScheme)) { 860 request->url().SchemeIs(url::kHttpScheme)) {
826 scheduler_->OnReceivedSpdyProxiedHttpResponse( 861 scheduler_->OnReceivedSpdyProxiedHttpResponse(
827 info->GetChildID(), info->GetRouteID()); 862 info->GetChildID(), info->GetRouteID());
828 } 863 }
829 864
865 if (request->response_info().async_revalidation_required)
866 BeginAsyncRevalidation(request);
867
830 int render_process_id, render_frame_host; 868 int render_process_id, render_frame_host;
831 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) 869 if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host))
832 return; 870 return;
833 871
834 // Notify the observers on the UI thread. 872 // Notify the observers on the UI thread.
835 scoped_ptr<ResourceRequestDetails> detail(new ResourceRequestDetails( 873 scoped_ptr<ResourceRequestDetails> detail(new ResourceRequestDetails(
836 loader->request(), 874 request,
837 GetCertID(loader->request(), info->GetChildID()))); 875 GetCertID(request, info->GetChildID())));
838 BrowserThread::PostTask( 876 BrowserThread::PostTask(
839 BrowserThread::UI, FROM_HERE, 877 BrowserThread::UI, FROM_HERE,
840 base::Bind( 878 base::Bind(
841 &NotifyResponseOnUI, 879 &NotifyResponseOnUI,
842 render_process_id, render_frame_host, base::Passed(&detail))); 880 render_process_id, render_frame_host, base::Passed(&detail)));
843 } 881 }
844 882
845 void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) { 883 void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
846 ResourceRequestInfo* info = loader->GetRequestInfo(); 884 ResourceRequestInfo* info = loader->GetRequestInfo();
847 885
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 } 1217 }
1180 1218
1181 // Allow the observer to block/handle the request. 1219 // Allow the observer to block/handle the request.
1182 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, 1220 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method,
1183 request_data.url, 1221 request_data.url,
1184 request_data.resource_type, 1222 request_data.resource_type,
1185 resource_context)) { 1223 resource_context)) {
1186 AbortRequestBeforeItStarts(filter_, sync_result, request_id); 1224 AbortRequestBeforeItStarts(filter_, sync_result, request_id);
1187 return; 1225 return;
1188 } 1226 }
1227 bool is_async_revalidation = false;
1228 BeginRequestFromData(request_id, request_data, sync_result, process_type,
1229 child_id, route_id, is_async_revalidation,
1230 request_context, resource_context);
1231 }
1189 1232
1233 void ResourceDispatcherHostImpl::BeginRequestFromData(
1234 int request_id,
1235 const ResourceHostMsg_Request& request_data,
1236 IPC::Message* sync_result,
1237 int process_type,
1238 int child_id,
1239 int route_id,
1240 bool is_async_revalidation,
1241 net::URLRequestContext* request_context,
1242 ResourceContext* resource_context) {
1190 // Construct the request. 1243 // Construct the request.
1191 scoped_ptr<net::URLRequest> new_request; 1244 scoped_ptr<net::URLRequest> new_request;
1192 new_request = request_context->CreateRequest( 1245 new_request = request_context->CreateRequest(
1193 request_data.url, request_data.priority, NULL); 1246 request_data.url, request_data.priority, NULL);
1194 1247
1195 new_request->set_method(request_data.method); 1248 new_request->set_method(request_data.method);
1196 new_request->set_first_party_for_cookies( 1249 new_request->set_first_party_for_cookies(
1197 request_data.first_party_for_cookies); 1250 request_data.first_party_for_cookies);
1198 1251
1199 // If the request is a MAIN_FRAME request, the first-party URL gets updated on 1252 // If the request is a MAIN_FRAME request, the first-party URL gets updated on
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 // Only block image loads, as the attack applies largely to the "src" 1305 // Only block image loads, as the attack applies largely to the "src"
1253 // property of the <img> tag. It is common for web properties to allow 1306 // property of the <img> tag. It is common for web properties to allow
1254 // untrusted values for <img src>; this is considered a fair thing for an 1307 // untrusted values for <img src>; this is considered a fair thing for an
1255 // HTML sanitizer to do. Conversely, any HTML sanitizer that didn't 1308 // HTML sanitizer to do. Conversely, any HTML sanitizer that didn't
1256 // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags 1309 // filter sources for <script>, <link>, <embed>, <object>, <iframe> tags
1257 // would be considered vulnerable in and of itself. 1310 // would be considered vulnerable in and of itself.
1258 do_not_prompt_for_login = true; 1311 do_not_prompt_for_login = true;
1259 load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; 1312 load_flags |= net::LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
1260 } 1313 }
1261 1314
1315 // Check if request is eligible for async revalidation.
1316 bool support_async_revalidation =
1317 (async_revalidation_enabled_ && !is_sync_load && !is_async_revalidation &&
1318 QualifiesForAsyncRevalidation(request_data));
tyoshino (SeeGerritForStatus) 2015/06/15 09:30:39 Could you please move "!is_async_revalidation" to
Adam Rice 2015/06/15 11:36:20 Done.
1319 if (support_async_revalidation)
1320 load_flags |= net::LOAD_SUPPORT_ASYNC_REVALIDATION;
1321
1262 // Sync loads should have maximum priority and should be the only 1322 // Sync loads should have maximum priority and should be the only
1263 // requets that have the ignore limits flag set. 1323 // requets that have the ignore limits flag set.
1264 if (is_sync_load) { 1324 if (is_sync_load) {
1265 DCHECK_EQ(request_data.priority, net::MAXIMUM_PRIORITY); 1325 DCHECK_EQ(request_data.priority, net::MAXIMUM_PRIORITY);
1266 DCHECK_NE(load_flags & net::LOAD_IGNORE_LIMITS, 0); 1326 DCHECK_NE(load_flags & net::LOAD_IGNORE_LIMITS, 0);
1267 } else { 1327 } else {
1268 DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0); 1328 DCHECK_EQ(load_flags & net::LOAD_IGNORE_LIMITS, 0);
1269 } 1329 }
1270 new_request->SetLoadFlags(load_flags); 1330 new_request->SetLoadFlags(load_flags);
1271 1331
(...skipping 13 matching lines...) Expand all
1285 false, // is download 1345 false, // is download
1286 false, // is stream 1346 false, // is stream
1287 allow_download, 1347 allow_download,
1288 request_data.has_user_gesture, 1348 request_data.has_user_gesture,
1289 request_data.enable_load_timing, 1349 request_data.enable_load_timing,
1290 request_data.enable_upload_progress, 1350 request_data.enable_upload_progress,
1291 do_not_prompt_for_login, 1351 do_not_prompt_for_login,
1292 request_data.referrer_policy, 1352 request_data.referrer_policy,
1293 request_data.visiblity_state, 1353 request_data.visiblity_state,
1294 resource_context, filter_->GetWeakPtr(), 1354 resource_context, filter_->GetWeakPtr(),
1295 !is_sync_load); 1355 !is_sync_load,
1356 is_async_revalidation,
1357 support_async_revalidation ? &request_data : NULL);
1296 // Request takes ownership. 1358 // Request takes ownership.
1297 extra_info->AssociateWithRequest(new_request.get()); 1359 extra_info->AssociateWithRequest(new_request.get());
1298 1360
1299 if (new_request->url().SchemeIs(url::kBlobScheme)) { 1361 if (new_request->url().SchemeIs(url::kBlobScheme)) {
1300 // Hang on to a reference to ensure the blob is not released prior 1362 // Hang on to a reference to ensure the blob is not released prior
1301 // to the job being started. 1363 // to the job being started.
1302 storage::BlobProtocolHandler::SetRequestedBlobDataHandle( 1364 storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
1303 new_request.get(), 1365 new_request.get(),
1304 filter_->blob_storage_context()->context()->GetBlobDataFromPublicURL( 1366 filter_->blob_storage_context()->context()->GetBlobDataFromPublicURL(
1305 new_request->url())); 1367 new_request->url()));
(...skipping 14 matching lines...) Expand all
1320 request_data.fetch_request_context_type, 1382 request_data.fetch_request_context_type,
1321 request_data.fetch_frame_type, 1383 request_data.fetch_frame_type,
1322 request_data.request_body); 1384 request_data.request_body);
1323 1385
1324 // Have the appcache associate its extra info with the request. 1386 // Have the appcache associate its extra info with the request.
1325 AppCacheInterceptor::SetExtraRequestInfo( 1387 AppCacheInterceptor::SetExtraRequestInfo(
1326 new_request.get(), filter_->appcache_service(), child_id, 1388 new_request.get(), filter_->appcache_service(), child_id,
1327 request_data.appcache_host_id, request_data.resource_type, 1389 request_data.appcache_host_id, request_data.resource_type,
1328 request_data.should_reset_appcache); 1390 request_data.should_reset_appcache);
1329 1391
1330 scoped_ptr<ResourceHandler> handler( 1392 scoped_ptr<ResourceHandler> handler(CreateResourceHandler(
1331 CreateResourceHandler( 1393 new_request.get(), request_data, sync_result, route_id, process_type,
1332 new_request.get(), 1394 child_id, is_async_revalidation, resource_context));
1333 request_data, sync_result, route_id, process_type, child_id,
1334 resource_context));
1335 1395
1336 if (handler) 1396 if (handler)
1337 BeginRequestInternal(new_request.Pass(), handler.Pass()); 1397 BeginRequestInternal(new_request.Pass(), handler.Pass());
1338 } 1398 }
1339 1399
1340 scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler( 1400 scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
1341 net::URLRequest* request, 1401 net::URLRequest* request,
1342 const ResourceHostMsg_Request& request_data, 1402 const ResourceHostMsg_Request& request_data,
1343 IPC::Message* sync_result, 1403 IPC::Message* sync_result,
1344 int route_id, 1404 int route_id,
1345 int process_type, 1405 int process_type,
1346 int child_id, 1406 int child_id,
1407 bool is_async_revalidation,
1347 ResourceContext* resource_context) { 1408 ResourceContext* resource_context) {
1348 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. 1409 // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed.
1349 tracked_objects::ScopedTracker tracking_profile( 1410 tracked_objects::ScopedTracker tracking_profile(
1350 FROM_HERE_WITH_EXPLICIT_FUNCTION( 1411 FROM_HERE_WITH_EXPLICIT_FUNCTION(
1351 "456331 ResourceDispatcherHostImpl::CreateResourceHandler")); 1412 "456331 ResourceDispatcherHostImpl::CreateResourceHandler"));
1352 // Construct the IPC resource handler. 1413 // Construct the IPC resource handler.
1353 scoped_ptr<ResourceHandler> handler; 1414 scoped_ptr<ResourceHandler> handler;
1354 if (sync_result) { 1415 if (sync_result) {
1355 // download_to_file is not supported for synchronous requests. 1416 // download_to_file is not supported for synchronous requests.
1356 if (request_data.download_to_file) { 1417 if (request_data.download_to_file) {
1357 RecordAction(base::UserMetricsAction("BadMessageTerminate_RDH")); 1418 RecordAction(base::UserMetricsAction("BadMessageTerminate_RDH"));
1358 filter_->BadMessageReceived(); 1419 filter_->BadMessageReceived();
1359 return scoped_ptr<ResourceHandler>(); 1420 return scoped_ptr<ResourceHandler>();
1360 } 1421 }
1361 1422
1362 handler.reset(new SyncResourceHandler(request, sync_result, this)); 1423 handler.reset(new SyncResourceHandler(request, sync_result, this));
1424 } else if (is_async_revalidation) {
1425 handler.reset(new NullResourceHandler(
1426 request, this, base::TimeDelta::FromSeconds(
1427 kNullResourceHandlerDefaultReadTimeoutSecs)));
1363 } else { 1428 } else {
1364 handler.reset(new AsyncResourceHandler(request, this)); 1429 handler.reset(new AsyncResourceHandler(request, this));
1365 1430
1366 // The RedirectToFileResourceHandler depends on being next in the chain. 1431 // The RedirectToFileResourceHandler depends on being next in the chain.
1367 if (request_data.download_to_file) { 1432 if (request_data.download_to_file) {
1368 handler.reset( 1433 handler.reset(
1369 new RedirectToFileResourceHandler(handler.Pass(), request)); 1434 new RedirectToFileResourceHandler(handler.Pass(), request));
1370 } 1435 }
1371 } 1436 }
1372 1437
(...skipping 20 matching lines...) Expand all
1393 if (!is_swappable_navigation && 1458 if (!is_swappable_navigation &&
1394 base::CommandLine::ForCurrentProcess()->HasSwitch( 1459 base::CommandLine::ForCurrentProcess()->HasSwitch(
1395 switches::kSitePerProcess)) { 1460 switches::kSitePerProcess)) {
1396 is_swappable_navigation = 1461 is_swappable_navigation =
1397 request_data.resource_type == RESOURCE_TYPE_SUB_FRAME; 1462 request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
1398 } 1463 }
1399 if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER) 1464 if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER)
1400 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request)); 1465 handler.reset(new CrossSiteResourceHandler(handler.Pass(), request));
1401 } 1466 }
1402 1467
1403 return AddStandardHandlers(request, request_data.resource_type, 1468 // The BufferedResourceHandler performs mime-type sniffing and redirecting of
1404 resource_context, filter_->appcache_service(), 1469 // downloads and plugin-handled content. The first we don't need for an
1405 child_id, route_id, handler.Pass()); 1470 // async_revalidation, and the second is dangerous.
1471 if (!is_async_revalidation) {
1472 handler = AddBufferedResourceHandler(request, handler.Pass());
1473 }
1474
1475 return AddThrottlesAndSchedule(request, request_data.resource_type,
1476 resource_context, filter_->appcache_service(),
1477 child_id, route_id, handler.Pass());
1406 } 1478 }
1407 1479
1408 scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers( 1480 scoped_ptr<ResourceHandler>
1481 ResourceDispatcherHostImpl::AddBufferedResourceHandler(
1482 net::URLRequest* request,
1483 scoped_ptr<ResourceHandler> handler) {
1484 PluginService* plugin_service = nullptr;
1485 #if defined(ENABLE_PLUGINS)
1486 plugin_service = PluginService::GetInstance();
1487 #endif
1488 // Insert a buffered event handler before the actual one.
1489 return make_scoped_ptr(new BufferedResourceHandler(handler.Pass(), this,
1490 plugin_service, request));
1491 }
1492
1493 scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddThrottlesAndSchedule(
1409 net::URLRequest* request, 1494 net::URLRequest* request,
1410 ResourceType resource_type, 1495 ResourceType resource_type,
1411 ResourceContext* resource_context, 1496 ResourceContext* resource_context,
1412 AppCacheService* appcache_service, 1497 AppCacheService* appcache_service,
1413 int child_id, 1498 int child_id,
1414 int route_id, 1499 int route_id,
1415 scoped_ptr<ResourceHandler> handler) { 1500 scoped_ptr<ResourceHandler> handler) {
1416
1417 PluginService* plugin_service = nullptr;
1418 #if defined(ENABLE_PLUGINS)
1419 plugin_service = PluginService::GetInstance();
1420 #endif
1421 // Insert a buffered event handler before the actual one.
1422 handler.reset(
1423 new BufferedResourceHandler(
1424 handler.Pass(), this, plugin_service, request));
1425
1426 ScopedVector<ResourceThrottle> throttles; 1501 ScopedVector<ResourceThrottle> throttles;
1427 if (delegate_) { 1502 if (delegate_) {
1428 delegate_->RequestBeginning(request, 1503 delegate_->RequestBeginning(request,
1429 resource_context, 1504 resource_context,
1430 appcache_service, 1505 appcache_service,
1431 resource_type, 1506 resource_type,
1432 &throttles); 1507 &throttles);
1433 } 1508 }
1434 1509
1435 if (request->has_upload()) { 1510 if (request->has_upload()) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 false, // is_stream 1621 false, // is_stream
1547 download, // allow_download 1622 download, // allow_download
1548 false, // has_user_gesture 1623 false, // has_user_gesture
1549 false, // enable_load_timing 1624 false, // enable_load_timing
1550 false, // enable_upload_progress 1625 false, // enable_upload_progress
1551 false, // do_not_prompt_for_login 1626 false, // do_not_prompt_for_login
1552 blink::WebReferrerPolicyDefault, 1627 blink::WebReferrerPolicyDefault,
1553 blink::WebPageVisibilityStateVisible, 1628 blink::WebPageVisibilityStateVisible,
1554 context, 1629 context,
1555 base::WeakPtr<ResourceMessageFilter>(), // filter 1630 base::WeakPtr<ResourceMessageFilter>(), // filter
1556 true); // is_async 1631 true, // is_async
1632 false, // is_async_revalidation
1633 NULL); // original_message
tyoshino (SeeGerritForStatus) 2015/06/15 09:30:39 original_request
Adam Rice 2015/06/15 11:36:20 Done.
1557 } 1634 }
1558 1635
1559 void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id, 1636 void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id,
1560 int route_id, 1637 int route_id,
1561 bool is_visible, 1638 bool is_visible,
1562 bool is_audible) { 1639 bool is_audible) {
1563 scheduler_->OnClientCreated(child_id, route_id, is_visible, is_audible); 1640 scheduler_->OnClientCreated(child_id, route_id, is_visible, is_audible);
1564 } 1641 }
1565 1642
1566 void ResourceDispatcherHostImpl::OnRenderViewHostDeleted( 1643 void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 1774
1698 ResourceRequestInfoImpl* info = i->second->GetRequestInfo(); 1775 ResourceRequestInfoImpl* info = i->second->GetRequestInfo();
1699 1776
1700 GlobalRequestID id(child_id, i->first.request_id); 1777 GlobalRequestID id(child_id, i->first.request_id);
1701 DCHECK(id == i->first); 1778 DCHECK(id == i->first);
1702 // Don't cancel navigations that are expected to live beyond this process. 1779 // Don't cancel navigations that are expected to live beyond this process.
1703 if (IsTransferredNavigation(id)) 1780 if (IsTransferredNavigation(id))
1704 any_requests_transferring = true; 1781 any_requests_transferring = true;
1705 if (info->detachable_handler()) { 1782 if (info->detachable_handler()) {
1706 info->detachable_handler()->Detach(); 1783 info->detachable_handler()->Detach();
1707 } else if (!info->IsDownload() && !info->is_stream() && 1784 } else if (!info->IsDownload() &&
1785 !info->is_stream() && !info->IsAsyncRevalidation() &&
1708 !IsTransferredNavigation(id) && 1786 !IsTransferredNavigation(id) &&
1709 (route_id == -1 || route_id == info->GetRouteID())) { 1787 (route_id == -1 || route_id == info->GetRouteID())) {
1710 matching_requests.push_back(id); 1788 matching_requests.push_back(id);
1711 } 1789 }
1712 } 1790 }
1713 1791
1714 // Remove matches. 1792 // Remove matches.
1715 for (size_t i = 0; i < matching_requests.size(); ++i) { 1793 for (size_t i = 0; i < matching_requests.size(); ++i) {
1716 LoaderMap::iterator iter = pending_loaders_.find(matching_requests[i]); 1794 LoaderMap::iterator iter = pending_loaders_.find(matching_requests[i]);
1717 // Although every matching request was in pending_requests_ when we built 1795 // Although every matching request was in pending_requests_ when we built
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 if (i == pending_loaders_.end()) { 1845 if (i == pending_loaders_.end()) {
1768 NOTREACHED() << "Trying to remove a request that's not here"; 1846 NOTREACHED() << "Trying to remove a request that's not here";
1769 return; 1847 return;
1770 } 1848 }
1771 RemovePendingLoader(i); 1849 RemovePendingLoader(i);
1772 } 1850 }
1773 1851
1774 void ResourceDispatcherHostImpl::RemovePendingLoader( 1852 void ResourceDispatcherHostImpl::RemovePendingLoader(
1775 const LoaderMap::iterator& iter) { 1853 const LoaderMap::iterator& iter) {
1776 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo(); 1854 ResourceRequestInfoImpl* info = iter->second->GetRequestInfo();
1855 if (info->IsAsyncRevalidation()) {
1856 net::URLRequest* request = iter->second->request();
1857 auto async_revalidation_key =
1858 AsyncRevalidationKey(request->context()->http_transaction_factory(),
1859 request->original_url());
1860 bool erased =
1861 in_progress_async_revalidations_.erase(async_revalidation_key);
1862 DCHECK(erased);
1863 }
1777 1864
1778 // Remove the memory credit that we added when pushing the request onto 1865 // Remove the memory credit that we added when pushing the request onto
1779 // the pending list. 1866 // the pending list.
1780 IncrementOutstandingRequestsMemory(-1, *info); 1867 IncrementOutstandingRequestsMemory(-1, *info);
1781 1868
1782 pending_loaders_.erase(iter); 1869 pending_loaders_.erase(iter);
1783 } 1870 }
1784 1871
1785 void ResourceDispatcherHostImpl::CancelRequest(int child_id, 1872 void ResourceDispatcherHostImpl::CancelRequest(int child_id,
1786 int request_id) { 1873 int request_id) {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 true, // enable_load_timing 2079 true, // enable_load_timing
1993 false, // enable_upload_progress 2080 false, // enable_upload_progress
1994 false, // do_not_prompt_for_login 2081 false, // do_not_prompt_for_login
1995 info.common_params.referrer.policy, 2082 info.common_params.referrer.policy,
1996 // TODO(davidben): This is only used for prerenders. Replace 2083 // TODO(davidben): This is only used for prerenders. Replace
1997 // is_showing with something for that. Or maybe it just comes from the 2084 // is_showing with something for that. Or maybe it just comes from the
1998 // same mechanism as the cookie one. 2085 // same mechanism as the cookie one.
1999 blink::WebPageVisibilityStateVisible, 2086 blink::WebPageVisibilityStateVisible,
2000 resource_context, 2087 resource_context,
2001 base::WeakPtr<ResourceMessageFilter>(), // filter 2088 base::WeakPtr<ResourceMessageFilter>(), // filter
2002 true); 2089 true, // is_async
2090 false, // is_async_revalidation
2091 NULL); // original_message
2003 // Request takes ownership. 2092 // Request takes ownership.
2004 extra_info->AssociateWithRequest(new_request.get()); 2093 extra_info->AssociateWithRequest(new_request.get());
2005 2094
2006 if (new_request->url().SchemeIs(url::kBlobScheme)) { 2095 if (new_request->url().SchemeIs(url::kBlobScheme)) {
2007 // Hang on to a reference to ensure the blob is not released prior 2096 // Hang on to a reference to ensure the blob is not released prior
2008 // to the job being started. 2097 // to the job being started.
2009 ChromeBlobStorageContext* blob_context = 2098 ChromeBlobStorageContext* blob_context =
2010 GetChromeBlobStorageContextForResourceContext(resource_context); 2099 GetChromeBlobStorageContextForResourceContext(resource_context);
2011 storage::BlobProtocolHandler::SetRequestedBlobDataHandle( 2100 storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
2012 new_request.get(), 2101 new_request.get(),
2013 blob_context->context()->GetBlobDataFromPublicURL(new_request->url())); 2102 blob_context->context()->GetBlobDataFromPublicURL(new_request->url()));
2014 } 2103 }
2015 2104
2016 // TODO(davidben): Attach ServiceWorkerRequestHandler. 2105 // TODO(davidben): Attach ServiceWorkerRequestHandler.
2017 // TODO(michaeln): Help out with this and that. 2106 // TODO(michaeln): Help out with this and that.
2018 // TODO(davidben): Attach AppCacheInterceptor. 2107 // TODO(davidben): Attach AppCacheInterceptor.
2019 2108
2020 scoped_ptr<ResourceHandler> handler(new NavigationResourceHandler( 2109 scoped_ptr<ResourceHandler> handler(new NavigationResourceHandler(
2021 new_request.get(), loader)); 2110 new_request.get(), loader));
2022 2111
2023 // TODO(davidben): Pass in the appropriate appcache_service. Also fix the 2112 // TODO(davidben): Pass in the appropriate appcache_service. Also fix the
2024 // dependency on child_id/route_id. Those are used by the ResourceScheduler; 2113 // dependency on child_id/route_id. Those are used by the ResourceScheduler;
2025 // currently it's a no-op. 2114 // currently it's a no-op.
2026 handler = AddStandardHandlers(new_request.get(), resource_type, 2115 handler = AddThrottlesAndSchedule(
2027 resource_context, 2116 new_request.get(), resource_type, resource_context,
2028 nullptr, // appcache_service 2117 nullptr, // appcache_service
2029 -1, // child_id 2118 -1, // child_id
2030 -1, // route_id 2119 -1, // route_id
2031 handler.Pass()); 2120 AddBufferedResourceHandler(new_request.get(), handler.Pass()));
2032 2121
2033 BeginRequestInternal(new_request.Pass(), handler.Pass()); 2122 BeginRequestInternal(new_request.Pass(), handler.Pass());
2034 } 2123 }
2035 2124
2036 // static 2125 // static
2037 int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost( 2126 int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
2038 net::URLRequest* request) { 2127 net::URLRequest* request) {
2039 // The following fields should be a minor size contribution (experimentally 2128 // The following fields should be a minor size contribution (experimentally
2040 // on the order of 100). However since they are variable length, it could 2129 // on the order of 100). However since they are variable length, it could
2041 // in theory be a sizeable contribution. 2130 // in theory be a sizeable contribution.
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 } 2454 }
2366 2455
2367 // Add a flag to selectively bypass the data reduction proxy if the resource 2456 // Add a flag to selectively bypass the data reduction proxy if the resource
2368 // type is not an image. 2457 // type is not an image.
2369 if (request_data.resource_type != RESOURCE_TYPE_IMAGE) 2458 if (request_data.resource_type != RESOURCE_TYPE_IMAGE)
2370 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY; 2459 load_flags |= net::LOAD_BYPASS_DATA_REDUCTION_PROXY;
2371 2460
2372 return load_flags; 2461 return load_flags;
2373 } 2462 }
2374 2463
2464 void ResourceDispatcherHostImpl::BeginAsyncRevalidation(
2465 net::URLRequest* for_request) {
2466 ResourceRequestInfoImpl* info =
2467 ResourceRequestInfoImpl::ForRequest(for_request);
2468 DCHECK(info);
2469 DCHECK(!info->IsAsyncRevalidation());
2470 ResourceHostMsg_Request* original_request_data = info->original_request();
2471 DCHECK(original_request_data);
2472
2473 ResourceHostMsg_Request new_request_data = *original_request_data;
2474 new_request_data.do_not_prompt_for_login = true;
2475 new_request_data.allow_download = false;
2476 new_request_data.enable_load_timing = false;
2477 new_request_data.download_to_file = false;
2478 new_request_data.transferred_request_child_id = -1;
2479 new_request_data.transferred_request_request_id = -1;
2480 new_request_data.priority = net::MINIMUM_PRIORITY;
2481
2482 int process_type = PROCESS_TYPE_BROWSER;
2483 int child_id = info->GetChildID();
2484 int route_id = info->GetRouteID();
2485 int request_id = --request_id_;
2486 bool is_async_revalidation = true;
2487
2488 ResourceContext* resource_context = NULL;
2489 net::URLRequestContext* request_context = NULL;
2490 // TODO(ricea): How can we ensure that resource_context and request_context
2491 // live long enough to service the request?
2492 info->filter()->GetContexts(new_request_data, &resource_context,
2493 &request_context);
2494 if (is_shutdown_ || (delegate_ &&
2495 !delegate_->ShouldBeginRequest(
2496 new_request_data.method, new_request_data.url,
2497 new_request_data.resource_type, resource_context))) {
2498 return;
2499 }
2500
2501 auto async_revalidation_key = AsyncRevalidationKey(
2502 request_context->http_transaction_factory(), original_request_data->url);
2503 if (!in_progress_async_revalidations_.insert(async_revalidation_key).second) {
2504 // A matching async revalidation is already in progress for this cache; we
2505 // don't need another one.
2506 return;
2507 }
2508 CHECK(ContainsKey(active_resource_contexts_, resource_context));
2509
2510 // TODO(ricea): Make filter_ be passed around in a sane way.
2511 filter_ = info->filter();
2512 BeginRequestFromData(request_id, new_request_data, NULL, process_type,
2513 child_id, route_id, is_async_revalidation,
tyoshino (SeeGerritForStatus) 2015/06/15 09:30:39 Do the similar as L2090? I.e. true, // is_async
Adam Rice 2015/06/15 11:36:20 Done.
2514 request_context, resource_context);
2515 filter_ = NULL;
2516 }
2517
2375 } // namespace content 2518 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_impl.h ('k') | content/browser/loader/resource_dispatcher_host_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698