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

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

Issue 23496076: WIP - Refactor programmatic downloads Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_impl.h ('k') | content/browser/net/referrer.h » ('j') | 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) 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 <set> 9 #include <set>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/command_line.h"
15 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
16 #include "base/debug/alias.h" 15 #include "base/debug/alias.h"
17 #include "base/logging.h" 16 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/shared_memory.h" 18 #include "base/memory/shared_memory.h"
20 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
21 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
22 #include "base/metrics/sparse_histogram.h" 21 #include "base/metrics/sparse_histogram.h"
23 #include "base/stl_util.h" 22 #include "base/stl_util.h"
24 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 23 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
(...skipping 10 matching lines...) Expand all
35 #include "content/browser/loader/cross_site_resource_handler.h" 34 #include "content/browser/loader/cross_site_resource_handler.h"
36 #include "content/browser/loader/power_save_block_resource_throttle.h" 35 #include "content/browser/loader/power_save_block_resource_throttle.h"
37 #include "content/browser/loader/redirect_to_file_resource_handler.h" 36 #include "content/browser/loader/redirect_to_file_resource_handler.h"
38 #include "content/browser/loader/resource_message_filter.h" 37 #include "content/browser/loader/resource_message_filter.h"
39 #include "content/browser/loader/resource_request_info_impl.h" 38 #include "content/browser/loader/resource_request_info_impl.h"
40 #include "content/browser/loader/stream_resource_handler.h" 39 #include "content/browser/loader/stream_resource_handler.h"
41 #include "content/browser/loader/sync_resource_handler.h" 40 #include "content/browser/loader/sync_resource_handler.h"
42 #include "content/browser/loader/throttling_resource_handler.h" 41 #include "content/browser/loader/throttling_resource_handler.h"
43 #include "content/browser/loader/transfer_navigation_resource_throttle.h" 42 #include "content/browser/loader/transfer_navigation_resource_throttle.h"
44 #include "content/browser/loader/upload_data_stream_builder.h" 43 #include "content/browser/loader/upload_data_stream_builder.h"
44 #include "content/browser/net/referrer.h"
45 #include "content/browser/plugin_service_impl.h" 45 #include "content/browser/plugin_service_impl.h"
46 #include "content/browser/renderer_host/render_view_host_delegate.h" 46 #include "content/browser/renderer_host/render_view_host_delegate.h"
47 #include "content/browser/renderer_host/render_view_host_impl.h" 47 #include "content/browser/renderer_host/render_view_host_impl.h"
48 #include "content/browser/resource_context_impl.h" 48 #include "content/browser/resource_context_impl.h"
49 #include "content/browser/streams/stream.h" 49 #include "content/browser/streams/stream.h"
50 #include "content/browser/streams/stream_context.h" 50 #include "content/browser/streams/stream_context.h"
51 #include "content/browser/streams/stream_registry.h" 51 #include "content/browser/streams/stream_registry.h"
52 #include "content/browser/worker_host/worker_service_impl.h" 52 #include "content/browser/worker_host/worker_service_impl.h"
53 #include "content/common/resource_messages.h" 53 #include "content/common/resource_messages.h"
54 #include "content/common/ssl_status_serialization.h" 54 #include "content/common/ssl_status_serialization.h"
55 #include "content/common/view_messages.h" 55 #include "content/common/view_messages.h"
56 #include "content/public/browser/browser_thread.h" 56 #include "content/public/browser/browser_thread.h"
57 #include "content/public/browser/content_browser_client.h" 57 #include "content/public/browser/content_browser_client.h"
58 #include "content/public/browser/download_manager.h" 58 #include "content/public/browser/download_manager.h"
59 #include "content/public/browser/download_url_parameters.h" 59 #include "content/public/browser/download_url_parameters.h"
60 #include "content/public/browser/global_request_id.h" 60 #include "content/public/browser/global_request_id.h"
61 #include "content/public/browser/resource_dispatcher_host_delegate.h" 61 #include "content/public/browser/resource_dispatcher_host_delegate.h"
62 #include "content/public/browser/resource_request_details.h" 62 #include "content/public/browser/resource_request_details.h"
63 #include "content/public/browser/resource_throttle.h" 63 #include "content/public/browser/resource_throttle.h"
64 #include "content/public/browser/stream_handle.h" 64 #include "content/public/browser/stream_handle.h"
65 #include "content/public/browser/user_metrics.h" 65 #include "content/public/browser/user_metrics.h"
66 #include "content/public/common/content_switches.h"
67 #include "content/public/common/process_type.h" 66 #include "content/public/common/process_type.h"
68 #include "content/public/common/url_constants.h" 67 #include "content/public/common/url_constants.h"
69 #include "ipc/ipc_message_macros.h" 68 #include "ipc/ipc_message_macros.h"
70 #include "ipc/ipc_message_start.h" 69 #include "ipc/ipc_message_start.h"
71 #include "net/base/auth.h" 70 #include "net/base/auth.h"
72 #include "net/base/load_flags.h" 71 #include "net/base/load_flags.h"
73 #include "net/base/mime_util.h" 72 #include "net/base/mime_util.h"
74 #include "net/base/net_errors.h" 73 #include "net/base/net_errors.h"
75 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 74 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
76 #include "net/base/request_priority.h" 75 #include "net/base/request_priority.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary 120 // net::LOAD_MAYBE_USER_GESTURE load flag. This is a fairly arbitrary
122 // guess at how long to expect direct impact from a user gesture, but 121 // guess at how long to expect direct impact from a user gesture, but
123 // this should be OK as the load flag is a best-effort thing only, 122 // this should be OK as the load flag is a best-effort thing only,
124 // rather than being intended as fully accurate. 123 // rather than being intended as fully accurate.
125 const int kUserGestureWindowMs = 3500; 124 const int kUserGestureWindowMs = 3500;
126 125
127 // Ratio of |max_num_in_flight_requests_| that any one renderer is allowed to 126 // Ratio of |max_num_in_flight_requests_| that any one renderer is allowed to
128 // use. Arbitrarily chosen. 127 // use. Arbitrarily chosen.
129 const double kMaxRequestsPerProcessRatio = 0.45; 128 const double kMaxRequestsPerProcessRatio = 0.45;
130 129
131 // All possible error codes from the network module. Note that the error codes
132 // are all positive (since histograms expect positive sample values).
133 const int kAllNetErrorCodes[] = {
134 #define NET_ERROR(label, value) -(value),
135 #include "net/base/net_error_list.h"
136 #undef NET_ERROR
137 };
138
139 // Aborts a request before an URLRequest has actually been created. 130 // Aborts a request before an URLRequest has actually been created.
140 void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, 131 void AbortRequestBeforeItStarts(ResourceMessageFilter* filter,
141 IPC::Message* sync_result, 132 IPC::Message* sync_result,
142 int request_id) { 133 int request_id) {
143 if (sync_result) { 134 if (sync_result) {
144 SyncLoadResult result; 135 SyncLoadResult result;
145 result.error_code = net::ERR_ABORTED; 136 result.error_code = net::ERR_ABORTED;
146 ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result); 137 ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result);
147 filter->Send(sync_result); 138 filter->Send(sync_result);
148 } else { 139 } else {
149 // Tell the renderer that this request was disallowed. 140 // Tell the renderer that this request was disallowed.
150 filter->Send(new ResourceMsg_RequestComplete( 141 filter->Send(new ResourceMsg_RequestComplete(
151 request_id, 142 request_id,
152 net::ERR_ABORTED, 143 net::ERR_ABORTED,
153 false, 144 false,
154 std::string(), // No security info needed, connection not established. 145 std::string(), // No security info needed, connection not established.
155 base::TimeTicks())); 146 base::TimeTicks()));
156 } 147 }
157 } 148 }
158 149
159 void SetReferrerForRequest(net::URLRequest* request, const Referrer& referrer) {
160 if (!referrer.url.is_valid() ||
161 CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoReferrers)) {
162 request->SetReferrer(std::string());
163 } else {
164 request->SetReferrer(referrer.url.spec());
165 }
166
167 net::URLRequest::ReferrerPolicy net_referrer_policy =
168 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
169 switch (referrer.policy) {
170 case WebKit::WebReferrerPolicyDefault:
171 net_referrer_policy =
172 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
173 break;
174 case WebKit::WebReferrerPolicyAlways:
175 case WebKit::WebReferrerPolicyNever:
176 case WebKit::WebReferrerPolicyOrigin:
177 net_referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER;
178 break;
179 }
180 request->set_referrer_policy(net_referrer_policy);
181 }
182
183 // Consults the RendererSecurity policy to determine whether the 150 // Consults the RendererSecurity policy to determine whether the
184 // ResourceDispatcherHostImpl should service this request. A request might be 151 // ResourceDispatcherHostImpl should service this request. A request might be
185 // disallowed if the renderer is not authorized to retrieve the request URL or 152 // disallowed if the renderer is not authorized to retrieve the request URL or
186 // if the renderer is attempting to upload an unauthorized file. 153 // if the renderer is attempting to upload an unauthorized file.
187 bool ShouldServiceRequest(int process_type, 154 bool ShouldServiceRequest(int process_type,
188 int child_id, 155 int child_id,
189 const ResourceHostMsg_Request& request_data, 156 const ResourceHostMsg_Request& request_data,
190 fileapi::FileSystemContext* file_system_context) { 157 fileapi::FileSystemContext* file_system_context) {
191 if (process_type == PROCESS_TYPE_PLUGIN) 158 if (process_type == PROCESS_TYPE_PLUGIN)
192 return true; 159 return true;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 #if defined(OS_WIN) 204 #if defined(OS_WIN)
238 #pragma warning(disable: 4748) 205 #pragma warning(disable: 4748)
239 #pragma optimize("", off) 206 #pragma optimize("", off)
240 #endif 207 #endif
241 208
242 #if defined(OS_WIN) 209 #if defined(OS_WIN)
243 #pragma optimize("", on) 210 #pragma optimize("", on)
244 #pragma warning(default: 4748) 211 #pragma warning(default: 4748)
245 #endif 212 #endif
246 213
247 net::Error CallbackAndReturn(
248 const DownloadUrlParameters::OnStartedCallback& started_cb,
249 net::Error net_error) {
250 if (started_cb.is_null())
251 return net_error;
252 BrowserThread::PostTask(
253 BrowserThread::UI, FROM_HERE,
254 base::Bind(started_cb, static_cast<DownloadItem*>(NULL), net_error));
255
256 return net_error;
257 }
258
259 int GetCertID(net::URLRequest* request, int child_id) { 214 int GetCertID(net::URLRequest* request, int child_id) {
260 if (request->ssl_info().cert.get()) { 215 if (request->ssl_info().cert.get()) {
261 return CertStore::GetInstance()->StoreCert(request->ssl_info().cert.get(), 216 return CertStore::GetInstance()->StoreCert(request->ssl_info().cert.get(),
262 child_id); 217 child_id);
263 } 218 }
264 return 0; 219 return 0;
265 } 220 }
266 221
267 void NotifyRedirectOnUI(int render_process_id, 222 void NotifyRedirectOnUI(int render_process_id,
268 int render_view_id, 223 int render_view_id,
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 i != blocked_loaders_map_.end(); ++i) { 393 i != blocked_loaders_map_.end(); ++i) {
439 BlockedLoadersList* loaders = i->second; 394 BlockedLoadersList* loaders = i->second;
440 if (!loaders->empty()) { 395 if (!loaders->empty()) {
441 ResourceRequestInfoImpl* info = loaders->front()->GetRequestInfo(); 396 ResourceRequestInfoImpl* info = loaders->front()->GetRequestInfo();
442 // http://crbug.com/90971 397 // http://crbug.com/90971
443 CHECK_NE(info->GetContext(), context); 398 CHECK_NE(info->GetContext(), context);
444 } 399 }
445 } 400 }
446 } 401 }
447 402
448 net::Error ResourceDispatcherHostImpl::BeginDownload(
449 scoped_ptr<net::URLRequest> request,
450 const Referrer& referrer,
451 bool is_content_initiated,
452 ResourceContext* context,
453 int child_id,
454 int route_id,
455 bool prefer_cache,
456 scoped_ptr<DownloadSaveInfo> save_info,
457 uint32 download_id,
458 const DownloadStartedCallback& started_callback) {
459 if (is_shutdown_)
460 return CallbackAndReturn(started_callback, net::ERR_INSUFFICIENT_RESOURCES);
461
462 const GURL& url = request->original_url();
463
464 // http://crbug.com/90971
465 char url_buf[128];
466 base::strlcpy(url_buf, url.spec().c_str(), arraysize(url_buf));
467 base::debug::Alias(url_buf);
468 CHECK(ContainsKey(active_resource_contexts_, context));
469
470 SetReferrerForRequest(request.get(), referrer);
471
472 int extra_load_flags = net::LOAD_IS_DOWNLOAD;
473 if (prefer_cache) {
474 // If there is upload data attached, only retrieve from cache because there
475 // is no current mechanism to prompt the user for their consent for a
476 // re-post. For GETs, try to retrieve data from the cache and skip
477 // validating the entry if present.
478 if (request->get_upload() != NULL)
479 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE;
480 else
481 extra_load_flags |= net::LOAD_PREFERRING_CACHE;
482 } else {
483 extra_load_flags |= net::LOAD_DISABLE_CACHE;
484 }
485 request->set_load_flags(request->load_flags() | extra_load_flags);
486
487 // No need to get offline load flags for downloads, but make sure
488 // we have an OfflinePolicy to receive request completions.
489 GlobalRoutingID id(child_id, route_id);
490 if (!offline_policy_map_[id])
491 offline_policy_map_[id] = new OfflinePolicy();
492
493 // Check if the renderer is permitted to request the requested URL.
494 if (!ChildProcessSecurityPolicyImpl::GetInstance()->
495 CanRequestURL(child_id, url)) {
496 VLOG(1) << "Denied unauthorized download request for "
497 << url.possibly_invalid_spec();
498 return CallbackAndReturn(started_callback, net::ERR_ACCESS_DENIED);
499 }
500
501 request_id_--;
502
503 const net::URLRequestContext* request_context = context->GetRequestContext();
504 if (!request_context->job_factory()->IsHandledURL(url)) {
505 VLOG(1) << "Download request for unsupported protocol: "
506 << url.possibly_invalid_spec();
507 return CallbackAndReturn(started_callback, net::ERR_ACCESS_DENIED);
508 }
509
510 ResourceRequestInfoImpl* extra_info =
511 CreateRequestInfo(child_id, route_id, true, context);
512 extra_info->AssociateWithRequest(request.get()); // Request takes ownership.
513
514 if (request->url().SchemeIs(chrome::kBlobScheme)) {
515 ChromeBlobStorageContext* blob_context =
516 GetChromeBlobStorageContextForResourceContext(context);
517 webkit_blob::BlobProtocolHandler::SetRequestedBlobDataHandle(
518 request.get(),
519 blob_context->context()->GetBlobDataFromPublicURL(request->url()));
520 }
521
522 // From this point forward, the |DownloadResourceHandler| is responsible for
523 // |started_callback|.
524 scoped_ptr<ResourceHandler> handler(
525 CreateResourceHandlerForDownload(request.get(), is_content_initiated,
526 true, download_id, save_info.Pass(),
527 started_callback));
528
529 BeginRequestInternal(request.Pass(), handler.Pass());
530
531 return net::OK;
532 }
533
534 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( 403 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest(
535 net::URLRequest* request) { 404 net::URLRequest* request) {
536 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); 405 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
537 if (info) { 406 if (info) {
538 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); 407 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID());
539 if (loader) 408 if (loader)
540 loader->ClearLoginDelegate(); 409 loader->ClearLoginDelegate();
541 } 410 }
542 } 411 }
543 412
544 void ResourceDispatcherHostImpl::Shutdown() { 413 void ResourceDispatcherHostImpl::Shutdown() {
545 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
546 BrowserThread::PostTask(BrowserThread::IO, 415 BrowserThread::PostTask(BrowserThread::IO,
547 FROM_HERE, 416 FROM_HERE,
548 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, 417 base::Bind(&ResourceDispatcherHostImpl::OnShutdown,
549 base::Unretained(this))); 418 base::Unretained(this)));
550 } 419 }
551 420
552 scoped_ptr<ResourceHandler> 421 scoped_ptr<ResourceHandler>
553 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( 422 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload(
554 net::URLRequest* request, 423 net::URLRequest* request,
555 bool is_content_initiated, 424 bool must_download) {
556 bool must_download, 425 scoped_ptr<ResourceHandler> handler(new DownloadResourceHandler(request));
557 uint32 id,
558 scoped_ptr<DownloadSaveInfo> save_info,
559 const DownloadUrlParameters::OnStartedCallback& started_cb) {
560 scoped_ptr<ResourceHandler> handler(
561 new DownloadResourceHandler(id, request, started_cb, save_info.Pass()));
562 if (delegate_) { 426 if (delegate_) {
563 const ResourceRequestInfo* request_info( 427 const ResourceRequestInfo* request_info(
564 ResourceRequestInfo::ForRequest(request)); 428 ResourceRequestInfo::ForRequest(request));
565 429
566 ScopedVector<ResourceThrottle> throttles; 430 ScopedVector<ResourceThrottle> throttles;
567 delegate_->DownloadStarting( 431 delegate_->DownloadStarting(
568 request, request_info->GetContext(), request_info->GetChildID(), 432 request, request_info->GetContext(), request_info->GetChildID(),
569 request_info->GetRouteID(), request_info->GetRequestID(), 433 request_info->GetRouteID(), request_info->GetRequestID(),
570 is_content_initiated, must_download, &throttles); 434 true /* content_intiated */, must_download, &throttles);
571 if (!throttles.empty()) { 435 if (!throttles.empty()) {
572 handler.reset( 436 handler.reset(
573 new ThrottlingResourceHandler( 437 new ThrottlingResourceHandler(
574 handler.Pass(), request_info->GetChildID(), 438 handler.Pass(), request_info->GetChildID(),
575 request_info->GetRequestID(), throttles.Pass())); 439 request_info->GetRequestID(), throttles.Pass()));
576 } 440 }
577 } 441 }
578 return handler.Pass(); 442 return handler.Pass();
579 } 443 }
580 444
(...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS) 1732 if ((load_flags & net::LOAD_REPORT_RAW_HEADERS)
1869 && !policy->CanReadRawCookies(child_id)) { 1733 && !policy->CanReadRawCookies(child_id)) {
1870 VLOG(1) << "Denied unauthorized request for raw headers"; 1734 VLOG(1) << "Denied unauthorized request for raw headers";
1871 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS; 1735 load_flags &= ~net::LOAD_REPORT_RAW_HEADERS;
1872 } 1736 }
1873 1737
1874 return load_flags; 1738 return load_flags;
1875 } 1739 }
1876 1740
1877 } // namespace content 1741 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_dispatcher_host_impl.h ('k') | content/browser/net/referrer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698