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

Side by Side Diff: chrome/browser/renderer_host/resource_dispatcher_host.cc

Issue 3127008: Preliminary work on resuming downloads whose connections have expired.
Patch Set: Waiting to send download automation error message until after other downloads are canceled. Created 10 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/renderer_host/resource_dispatcher_host.h" 7 #include "chrome/browser/renderer_host/resource_dispatcher_host.h"
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/file_util.h"
14 #include "base/format_macros.h"
13 #include "base/histogram.h" 15 #include "base/histogram.h"
14 #include "base/message_loop.h" 16 #include "base/message_loop.h"
15 #include "base/scoped_ptr.h" 17 #include "base/scoped_ptr.h"
16 #include "base/shared_memory.h" 18 #include "base/shared_memory.h"
17 #include "base/stl_util-inl.h" 19 #include "base/stl_util-inl.h"
18 #include "base/time.h" 20 #include "base/time.h"
19 #include "chrome/browser/cert_store.h" 21 #include "chrome/browser/cert_store.h"
20 #include "chrome/browser/child_process_security_policy.h" 22 #include "chrome/browser/child_process_security_policy.h"
21 #include "chrome/browser/chrome_blob_storage_context.h" 23 #include "chrome/browser/chrome_blob_storage_context.h"
22 #include "chrome/browser/cross_site_request_manager.h" 24 #include "chrome/browser/cross_site_request_manager.h"
23 #include "chrome/browser/download/download_file_manager.h" 25 #include "chrome/browser/download/download_file_manager.h"
24 #include "chrome/browser/download/download_manager.h" 26 #include "chrome/browser/download/download_manager.h"
25 #include "chrome/browser/download/download_request_limiter.h" 27 #include "chrome/browser/download/download_request_limiter.h"
28 #include "chrome/browser/download/download_util.h"
26 #include "chrome/browser/download/save_file_manager.h" 29 #include "chrome/browser/download/save_file_manager.h"
27 #include "chrome/browser/extensions/user_script_listener.h" 30 #include "chrome/browser/extensions/user_script_listener.h"
28 #include "chrome/browser/external_protocol_handler.h" 31 #include "chrome/browser/external_protocol_handler.h"
32 #include "chrome/browser/history/download_create_info.h"
29 #include "chrome/browser/in_process_webkit/webkit_thread.h" 33 #include "chrome/browser/in_process_webkit/webkit_thread.h"
30 #include "chrome/browser/login_prompt.h" 34 #include "chrome/browser/login_prompt.h"
31 #include "chrome/browser/net/chrome_url_request_context.h" 35 #include "chrome/browser/net/chrome_url_request_context.h"
32 #include "chrome/browser/net/url_request_tracking.h" 36 #include "chrome/browser/net/url_request_tracking.h"
33 #include "chrome/browser/plugin_service.h" 37 #include "chrome/browser/plugin_service.h"
34 #include "chrome/browser/profile.h" 38 #include "chrome/browser/profile.h"
35 #include "chrome/browser/renderer_host/async_resource_handler.h" 39 #include "chrome/browser/renderer_host/async_resource_handler.h"
36 #include "chrome/browser/renderer_host/buffered_resource_handler.h" 40 #include "chrome/browser/renderer_host/buffered_resource_handler.h"
37 #include "chrome/browser/renderer_host/cross_site_resource_handler.h" 41 #include "chrome/browser/renderer_host/cross_site_resource_handler.h"
38 #include "chrome/browser/renderer_host/download_resource_handler.h" 42 #include "chrome/browser/renderer_host/download_resource_handler.h"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // Maximum byte "cost" of all the outstanding requests for a renderer. 124 // Maximum byte "cost" of all the outstanding requests for a renderer.
121 // See delcaration of |max_outstanding_requests_cost_per_process_| for details. 125 // See delcaration of |max_outstanding_requests_cost_per_process_| for details.
122 // This bound is 25MB, which allows for around 6000 outstanding requests. 126 // This bound is 25MB, which allows for around 6000 outstanding requests.
123 const int kMaxOutstandingRequestsCostPerProcess = 26214400; 127 const int kMaxOutstandingRequestsCostPerProcess = 26214400;
124 128
125 // Consults the RendererSecurity policy to determine whether the 129 // Consults the RendererSecurity policy to determine whether the
126 // ResourceDispatcherHost should service this request. A request might be 130 // ResourceDispatcherHost should service this request. A request might be
127 // disallowed if the renderer is not authorized to retrieve the request URL or 131 // disallowed if the renderer is not authorized to retrieve the request URL or
128 // if the renderer is attempting to upload an unauthorized file. 132 // if the renderer is attempting to upload an unauthorized file.
129 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type, 133 bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type,
130 int child_id, 134 int process_unique_id,
131 const ViewHostMsg_Resource_Request& request_data) { 135 const ViewHostMsg_Resource_Request& request_data) {
132 if (process_type == ChildProcessInfo::PLUGIN_PROCESS) 136 if (process_type == ChildProcessInfo::PLUGIN_PROCESS)
133 return true; 137 return true;
134 138
135 if (request_data.resource_type == ResourceType::PREFETCH && 139 if (request_data.resource_type == ResourceType::PREFETCH &&
136 !ResourceDispatcherHost::is_prefetch_enabled()) 140 !ResourceDispatcherHost::is_prefetch_enabled())
137 return false; 141 return false;
138 142
139 ChildProcessSecurityPolicy* policy = 143 ChildProcessSecurityPolicy* policy =
140 ChildProcessSecurityPolicy::GetInstance(); 144 ChildProcessSecurityPolicy::GetInstance();
141 145
142 // Check if the renderer is permitted to request the requested URL. 146 // Check if the renderer is permitted to request the requested URL.
143 if (!policy->CanRequestURL(child_id, request_data.url)) { 147 if (!policy->CanRequestURL(process_unique_id, request_data.url)) {
144 LOG(INFO) << "Denied unauthorized request for " << 148 LOG(INFO) << "Denied unauthorized request for " <<
145 request_data.url.possibly_invalid_spec(); 149 request_data.url.possibly_invalid_spec();
146 return false; 150 return false;
147 } 151 }
148 152
149 // Check if the renderer is permitted to upload the requested files. 153 // Check if the renderer is permitted to upload the requested files.
150 if (request_data.upload_data) { 154 if (request_data.upload_data) {
151 const std::vector<net::UploadData::Element>* uploads = 155 const std::vector<net::UploadData::Element>* uploads =
152 request_data.upload_data->elements(); 156 request_data.upload_data->elements();
153 std::vector<net::UploadData::Element>::const_iterator iter; 157 std::vector<net::UploadData::Element>::const_iterator iter;
154 for (iter = uploads->begin(); iter != uploads->end(); ++iter) { 158 for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
155 if (iter->type() == net::UploadData::TYPE_FILE && 159 if (iter->type() == net::UploadData::TYPE_FILE &&
156 !policy->CanUploadFile(child_id, iter->file_path())) { 160 !policy->CanUploadFile(process_unique_id, iter->file_path())) {
157 NOTREACHED() << "Denied unauthorized upload of " 161 NOTREACHED() << "Denied unauthorized upload of "
158 << iter->file_path().value(); 162 << iter->file_path().value();
159 return false; 163 return false;
160 } 164 }
161 } 165 }
162 } 166 }
163 167
164 return true; 168 return true;
165 } 169 }
166 170
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 kMaxOutstandingRequestsCostPerProcess), 231 kMaxOutstandingRequestsCostPerProcess),
228 receiver_(NULL) { 232 receiver_(NULL) {
229 ResourceQueue::DelegateSet resource_queue_delegates; 233 ResourceQueue::DelegateSet resource_queue_delegates;
230 resource_queue_delegates.insert(user_script_listener_.get()); 234 resource_queue_delegates.insert(user_script_listener_.get());
231 resource_queue_.Initialize(resource_queue_delegates); 235 resource_queue_.Initialize(resource_queue_delegates);
232 } 236 }
233 237
234 ResourceDispatcherHost::~ResourceDispatcherHost() { 238 ResourceDispatcherHost::~ResourceDispatcherHost() {
235 AsyncResourceHandler::GlobalCleanup(); 239 AsyncResourceHandler::GlobalCleanup();
236 STLDeleteValues(&pending_requests_); 240 STLDeleteValues(&pending_requests_);
241 STLDeleteValues(&interrupted_requests_);
237 242
238 user_script_listener_->ShutdownMainThread(); 243 user_script_listener_->ShutdownMainThread();
239 } 244 }
240 245
241 void ResourceDispatcherHost::Initialize() { 246 void ResourceDispatcherHost::Initialize() {
242 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 247 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
243 webkit_thread_->Initialize(); 248 webkit_thread_->Initialize();
244 safe_browsing_->Initialize(); 249 safe_browsing_->Initialize();
245 ChromeThread::PostTask( 250 ChromeThread::PostTask(
246 ChromeThread::IO, FROM_HERE, 251 ChromeThread::IO,
252 FROM_HERE,
247 NewRunnableFunction(&appcache::AppCacheInterceptor::EnsureRegistered)); 253 NewRunnableFunction(&appcache::AppCacheInterceptor::EnsureRegistered));
248 } 254 }
249 255
250 void ResourceDispatcherHost::Shutdown() { 256 void ResourceDispatcherHost::Shutdown() {
251 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 257 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
252 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, new ShutdownTask(this)); 258 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, new ShutdownTask(this));
253 } 259 }
254 260
255 void ResourceDispatcherHost::SetRequestInfo( 261 void ResourceDispatcherHost::SetRequestInfo(
256 URLRequest* request, 262 URLRequest* request,
257 ResourceDispatcherHostRequestInfo* info) { 263 ResourceDispatcherHostRequestInfo* info) {
258 request->SetUserData(NULL, info); 264 request->SetUserData(NULL, info);
259 } 265 }
260 266
261 void ResourceDispatcherHost::OnShutdown() { 267 void ResourceDispatcherHost::OnShutdown() {
262 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 268 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
263 is_shutdown_ = true; 269 is_shutdown_ = true;
264 resource_queue_.Shutdown(); 270 resource_queue_.Shutdown();
265 STLDeleteValues(&pending_requests_); 271 STLDeleteValues(&pending_requests_);
272 STLDeleteValues(&interrupted_requests_);
266 // Make sure we shutdown the timer now, otherwise by the time our destructor 273 // Make sure we shutdown the timer now, otherwise by the time our destructor
267 // runs if the timer is still running the Task is deleted twice (once by 274 // runs if the timer is still running the Task is deleted twice (once by
268 // the MessageLoop and the second time by RepeatingTimer). 275 // the MessageLoop and the second time by RepeatingTimer).
269 update_load_states_timer_.Stop(); 276 update_load_states_timer_.Stop();
270 277
271 // Clear blocked requests if any left. 278 // Clear blocked requests if any left.
272 // Note that we have to do this in 2 passes as we cannot call 279 // Note that we have to do this in 2 passes as we cannot call
273 // CancelBlockedRequestsForRoute while iterating over 280 // CancelBlockedRequestsForRoute while iterating over
274 // blocked_requests_map_, as it modifies it. 281 // blocked_requests_map_, as it modifies it.
275 std::set<ProcessRouteIDs> ids; 282 std::set<ProcessRouteIDs> ids;
276 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); 283 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin();
277 iter != blocked_requests_map_.end(); ++iter) { 284 iter != blocked_requests_map_.end(); ++iter) {
278 std::pair<std::set<ProcessRouteIDs>::iterator, bool> result = 285 std::pair<std::set<ProcessRouteIDs>::iterator, bool> result =
279 ids.insert(iter->first); 286 ids.insert(iter->first);
280 // We should not have duplicates. 287 // We should not have duplicates.
281 DCHECK(result.second); 288 DCHECK(result.second);
282 } 289 }
283 for (std::set<ProcessRouteIDs>::const_iterator iter = ids.begin(); 290 for (std::set<ProcessRouteIDs>::const_iterator iter = ids.begin();
284 iter != ids.end(); ++iter) { 291 iter != ids.end(); ++iter) {
285 CancelBlockedRequestsForRoute(iter->first, iter->second); 292 CancelBlockedRequestsForRoute(iter->first, iter->second);
286 } 293 }
287 } 294 }
288 295
289 bool ResourceDispatcherHost::HandleExternalProtocol(int request_id, 296 bool ResourceDispatcherHost::HandleExternalProtocol(int request_id,
290 int child_id, 297 int process_unique_id,
291 int route_id, 298 int route_id,
292 const GURL& url, 299 const GURL& url,
293 ResourceType::Type type, 300 ResourceType::Type type,
294 ResourceHandler* handler) { 301 ResourceHandler* handler) {
295 if (!ResourceType::IsFrame(type) || URLRequest::IsHandledURL(url)) 302 if (!ResourceType::IsFrame(type) || URLRequest::IsHandledURL(url))
296 return false; 303 return false;
297 304
298 ChromeThread::PostTask( 305 ChromeThread::PostTask(
299 ChromeThread::UI, FROM_HERE, 306 ChromeThread::UI,
307 FROM_HERE,
300 NewRunnableFunction( 308 NewRunnableFunction(
301 &ExternalProtocolHandler::LaunchUrl, url, child_id, route_id)); 309 &ExternalProtocolHandler::LaunchUrl,
310 url,
311 process_unique_id,
312 route_id));
302 313
303 handler->OnResponseCompleted(request_id, URLRequestStatus( 314 handler->OnResponseCompleted(request_id, URLRequestStatus(
304 URLRequestStatus::FAILED, 315 URLRequestStatus::FAILED,
305 net::ERR_ABORTED), 316 net::ERR_ABORTED),
306 std::string()); // No security info necessary. 317 std::string()); // No security info necessary.
307 return true; 318 return true;
308 } 319 }
309 320
310 bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message, 321 bool ResourceDispatcherHost::OnMessageReceived(const IPC::Message& message,
311 Receiver* receiver, 322 Receiver* receiver,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 BeginRequest(request_id, request_data, sync_result, 366 BeginRequest(request_id, request_data, sync_result,
356 sync_result->routing_id()); 367 sync_result->routing_id());
357 } 368 }
358 369
359 void ResourceDispatcherHost::BeginRequest( 370 void ResourceDispatcherHost::BeginRequest(
360 int request_id, 371 int request_id,
361 const ViewHostMsg_Resource_Request& request_data, 372 const ViewHostMsg_Resource_Request& request_data,
362 IPC::Message* sync_result, // only valid for sync 373 IPC::Message* sync_result, // only valid for sync
363 int route_id) { 374 int route_id) {
364 ChildProcessInfo::ProcessType process_type = receiver_->type(); 375 ChildProcessInfo::ProcessType process_type = receiver_->type();
365 int child_id = receiver_->id(); 376 int child_process_unique_id = receiver_->id();
366 ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>( 377 ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>(
367 receiver_->GetRequestContext(request_id, request_data)); 378 receiver_->GetRequestContext(request_id, request_data));
368 if (!context) { 379 if (!context) {
369 URLRequestContextGetter* context_getter = 380 URLRequestContextGetter* context_getter =
370 Profile::GetDefaultRequestContext(); 381 Profile::GetDefaultRequestContext();
371 if (context_getter) { 382 if (context_getter) {
372 context = static_cast<ChromeURLRequestContext*>( 383 context = static_cast<ChromeURLRequestContext*>(
373 context_getter->GetURLRequestContext()); 384 context_getter->GetURLRequestContext());
374 } 385 }
375 } 386 }
376 387
377 // Might need to resolve the blob references in the upload data. 388 // Might need to resolve the blob references in the upload data.
378 if (request_data.upload_data) { 389 if (request_data.upload_data) {
379 context->blob_storage_context()->controller()-> 390 context->blob_storage_context()->controller()->
380 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); 391 ResolveBlobReferencesInUploadData(request_data.upload_data.get());
381 } 392 }
382 393
383 if (is_shutdown_ || 394 if (is_shutdown_ || !ShouldServiceRequest(process_type,
384 !ShouldServiceRequest(process_type, child_id, request_data)) { 395 child_process_unique_id,
396 request_data)) {
385 URLRequestStatus status(URLRequestStatus::FAILED, net::ERR_ABORTED); 397 URLRequestStatus status(URLRequestStatus::FAILED, net::ERR_ABORTED);
386 if (sync_result) { 398 if (sync_result) {
387 SyncLoadResult result; 399 SyncLoadResult result;
388 result.status = status; 400 result.status = status;
389 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result); 401 ViewHostMsg_SyncLoad::WriteReplyParams(sync_result, result);
390 receiver_->Send(sync_result); 402 receiver_->Send(sync_result);
391 } else { 403 } else {
392 // Tell the renderer that this request was disallowed. 404 // Tell the renderer that this request was disallowed.
393 receiver_->Send(new ViewMsg_Resource_RequestComplete( 405 receiver_->Send(new ViewMsg_Resource_RequestComplete(
394 route_id, 406 route_id,
395 request_id, 407 request_id,
396 status, 408 status,
397 std::string(), // No security info needed, connection was not 409 std::string(), // No security info needed, connection was not
398 base::Time())); // established. 410 base::Time())); // established.
399 } 411 }
400 return; 412 return;
401 } 413 }
402 414
403 // Ensure the Chrome plugins are loaded, as they may intercept network 415 // Ensure the Chrome plugins are loaded, as they may intercept network
404 // requests. Does nothing if they are already loaded. 416 // requests. Does nothing if they are already loaded.
405 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by 417 // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by
406 // starting the load earlier in a BG thread. 418 // starting the load earlier in a BG thread.
407 PluginService::GetInstance()->LoadChromePlugins(this); 419 PluginService::GetInstance()->LoadChromePlugins(this);
408 420
409 // Construct the event handler. 421 // Construct the event handler.
410 scoped_refptr<ResourceHandler> handler; 422 scoped_refptr<ResourceHandler> handler;
411 if (sync_result) { 423 if (sync_result) {
412 handler = new SyncResourceHandler(receiver_, 424 handler = new SyncResourceHandler(receiver_,
413 child_id, 425 child_process_unique_id,
414 request_data.url, 426 request_data.url,
415 sync_result, 427 sync_result,
416 this); 428 this);
417 } else { 429 } else {
418 handler = new AsyncResourceHandler(receiver_, 430 handler = new AsyncResourceHandler(receiver_,
419 child_id, 431 child_process_unique_id,
420 route_id, 432 route_id,
421 receiver_->handle(), 433 receiver_->handle(),
422 request_data.url, 434 request_data.url,
423 this); 435 this);
424 } 436 }
425 437
426 if (request_data.download_to_file) 438 if (request_data.download_to_file)
427 handler = new RedirectToFileResourceHandler(handler, child_id, this); 439 handler = new RedirectToFileResourceHandler(handler,
440 child_process_unique_id,
441 this);
428 442
429 if (HandleExternalProtocol(request_id, child_id, route_id, 443 if (HandleExternalProtocol(request_id, child_process_unique_id, route_id,
430 request_data.url, request_data.resource_type, 444 request_data.url, request_data.resource_type,
431 handler)) { 445 handler)) {
432 return; 446 return;
433 } 447 }
434 448
435 // Construct the request. 449 // Construct the request.
436 URLRequest* request = new URLRequest(request_data.url, this); 450 URLRequest* request = new URLRequest(request_data.url, this);
437 request->set_method(request_data.method); 451 request->set_method(request_data.method);
438 request->set_first_party_for_cookies(request_data.first_party_for_cookies); 452 request->set_first_party_for_cookies(request_data.first_party_for_cookies);
439 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( 453 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch(
(...skipping 22 matching lines...) Expand all
462 upload_size = request_data.upload_data->GetContentLength(); 476 upload_size = request_data.upload_data->GetContentLength();
463 } 477 }
464 478
465 // Install a CrossSiteResourceHandler if this request is coming from a 479 // Install a CrossSiteResourceHandler if this request is coming from a
466 // RenderViewHost with a pending cross-site request. We only check this for 480 // RenderViewHost with a pending cross-site request. We only check this for
467 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do 481 // MAIN_FRAME requests. Unblock requests only come from a blocked page, do
468 // not count as cross-site, otherwise it gets blocked indefinitely. 482 // not count as cross-site, otherwise it gets blocked indefinitely.
469 if (request_data.resource_type == ResourceType::MAIN_FRAME && 483 if (request_data.resource_type == ResourceType::MAIN_FRAME &&
470 process_type == ChildProcessInfo::RENDER_PROCESS && 484 process_type == ChildProcessInfo::RENDER_PROCESS &&
471 Singleton<CrossSiteRequestManager>::get()-> 485 Singleton<CrossSiteRequestManager>::get()->
472 HasPendingCrossSiteRequest(child_id, route_id)) { 486 HasPendingCrossSiteRequest(child_process_unique_id, route_id)) {
473 // Wrap the event handler to be sure the current page's onunload handler 487 // Wrap the event handler to be sure the current page's onunload handler
474 // has a chance to run before we render the new page. 488 // has a chance to run before we render the new page.
475 handler = new CrossSiteResourceHandler(handler, 489 handler = new CrossSiteResourceHandler(handler,
476 child_id, 490 child_process_unique_id,
477 route_id, 491 route_id,
478 this); 492 this);
479 } 493 }
480 494
481 // Insert a buffered event handler before the actual one. 495 // Insert a buffered event handler before the actual one.
482 handler = new BufferedResourceHandler(handler, this, request); 496 handler = new BufferedResourceHandler(handler, this, request);
483 497
484 // Insert safe browsing at the front of the chain, so it gets to decide 498 // Insert safe browsing at the front of the chain, so it gets to decide
485 // on policies first. 499 // on policies first.
486 if (safe_browsing_->enabled()) { 500 if (safe_browsing_->enabled()) {
487 handler = CreateSafeBrowsingResourceHandler(handler, child_id, route_id, 501 handler = CreateSafeBrowsingResourceHandler(handler,
502 child_process_unique_id,
503 route_id,
488 request_data.resource_type); 504 request_data.resource_type);
489 } 505 }
490 506
491 #if defined(OS_CHROMEOS) 507 #if defined(OS_CHROMEOS)
492 // We check offline first, then check safe browsing so that we still can block 508 // We check offline first, then check safe browsing so that we still can block
493 // unsafe site after we remove offline page. 509 // unsafe site after we remove offline page.
494 handler = 510 handler = new OfflineResourceHandler(handler,
495 new OfflineResourceHandler(handler, child_id, route_id, this, request); 511 child_process_unique_id,
512 route_id,
513 this,
514 request);
496 #endif 515 #endif
497 516
498 // Make extra info and read footer (contains request ID). 517 // Make extra info and read footer (contains request ID).
499 ResourceDispatcherHostRequestInfo* extra_info = 518 ResourceDispatcherHostRequestInfo* extra_info =
500 new ResourceDispatcherHostRequestInfo( 519 new ResourceDispatcherHostRequestInfo(
501 handler, 520 handler,
502 process_type, 521 process_type,
503 child_id, 522 child_process_unique_id,
504 route_id, 523 route_id,
505 request_id, 524 request_id,
506 request_data.frame_origin, 525 request_data.frame_origin,
507 request_data.main_frame_origin, 526 request_data.main_frame_origin,
508 request_data.resource_type, 527 request_data.resource_type,
509 upload_size, 528 upload_size,
510 false, // is download 529 false, // is download
511 ResourceType::IsFrame(request_data.resource_type), // allow_download 530 ResourceType::IsFrame(request_data.resource_type), // allow_download
512 request_data.host_renderer_id, 531 request_data.host_renderer_id,
513 request_data.host_render_view_id); 532 request_data.host_render_view_id);
514 ApplyExtensionLocalizationFilter(request_data.url, request_data.resource_type, 533 ApplyExtensionLocalizationFilter(request_data.url, request_data.resource_type,
515 extra_info); 534 extra_info);
516 SetRequestInfo(request, extra_info); // Request takes ownership. 535 SetRequestInfo(request, extra_info); // Request takes ownership.
517 chrome_browser_net::SetOriginProcessUniqueIDForRequest( 536 chrome_browser_net::SetOriginProcessUniqueIDForRequest(
518 request_data.origin_child_id, request); 537 request_data.origin_child_id, request);
519 538
520 // Have the appcache associate its extra info with the request. 539 // Have the appcache associate its extra info with the request.
521 appcache::AppCacheInterceptor::SetExtraRequestInfo( 540 appcache::AppCacheInterceptor::SetExtraRequestInfo(
522 request, context ? context->appcache_service() : NULL, child_id, 541 request,
523 request_data.appcache_host_id, request_data.resource_type); 542 context ? context->appcache_service() : NULL,
543 child_process_unique_id,
544 request_data.appcache_host_id,
545 request_data.resource_type);
524 546
525 BeginRequestInternal(request); 547 BeginRequestInternal(request);
526 } 548 }
527 549
528 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { 550 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) {
529 DataReceivedACK(receiver_->id(), request_id); 551 DataReceivedACK(receiver_->id(), request_id);
530 } 552 }
531 553
532 void ResourceDispatcherHost::DataReceivedACK(int child_id, 554 void ResourceDispatcherHost::DataReceivedACK(int process_unique_id,
533 int request_id) { 555 int request_id) {
534 PendingRequestList::iterator i = pending_requests_.find( 556 PendingRequestList::iterator i = pending_requests_.find(
535 GlobalRequestID(child_id, request_id)); 557 GlobalRequestID(process_unique_id, request_id));
536 if (i == pending_requests_.end()) 558 if (i == pending_requests_.end())
537 return; 559 return;
538 560
539 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); 561 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second);
540 562
541 // Decrement the number of pending data messages. 563 // Decrement the number of pending data messages.
542 info->DecrementPendingDataCount(); 564 info->DecrementPendingDataCount();
543 565
544 // If the pending data count was higher than the max, resume the request. 566 // If the pending data count was higher than the max, resume the request.
545 if (info->pending_data_count() == kMaxPendingDataMessages) { 567 if (info->pending_data_count() == kMaxPendingDataMessages) {
546 // Decrement the pending data count one more time because we also 568 // Decrement the pending data count one more time because we also
547 // incremented it before pausing the request. 569 // incremented it before pausing the request.
548 info->DecrementPendingDataCount(); 570 info->DecrementPendingDataCount();
549 571
550 // Resume the request. 572 // Resume the request.
551 PauseRequest(child_id, request_id, false); 573 PauseRequest(process_unique_id, request_id, false);
552 } 574 }
553 } 575 }
554 576
555 bool ResourceDispatcherHost::Send(IPC::Message* message) { 577 bool ResourceDispatcherHost::Send(IPC::Message* message) {
556 delete message; 578 delete message;
557 return false; 579 return false;
558 } 580 }
559 581
560 void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { 582 void ResourceDispatcherHost::OnUploadProgressACK(int request_id) {
561 int child_id = receiver_->id(); 583 int child_process_unique_id = receiver_->id();
562 PendingRequestList::iterator i = pending_requests_.find( 584 PendingRequestList::iterator i = pending_requests_.find(
563 GlobalRequestID(child_id, request_id)); 585 GlobalRequestID(child_process_unique_id, request_id));
564 if (i == pending_requests_.end()) 586 if (i == pending_requests_.end())
565 return; 587 return;
566 588
567 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); 589 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second);
568 info->set_waiting_for_upload_progress_ack(false); 590 info->set_waiting_for_upload_progress_ack(false);
569 } 591 }
570 592
571 void ResourceDispatcherHost::OnCancelRequest(int request_id) { 593 void ResourceDispatcherHost::OnCancelRequest(int request_id) {
572 CancelRequest(receiver_->id(), request_id, true); 594 CancelRequest(receiver_->id(), request_id, true);
573 } 595 }
574 596
575 void ResourceDispatcherHost::OnFollowRedirect( 597 void ResourceDispatcherHost::OnFollowRedirect(
576 int request_id, 598 int request_id,
577 bool has_new_first_party_for_cookies, 599 bool has_new_first_party_for_cookies,
578 const GURL& new_first_party_for_cookies) { 600 const GURL& new_first_party_for_cookies) {
579 FollowDeferredRedirect(receiver_->id(), request_id, 601 FollowDeferredRedirect(receiver_->id(), request_id,
580 has_new_first_party_for_cookies, 602 has_new_first_party_for_cookies,
581 new_first_party_for_cookies); 603 new_first_party_for_cookies);
582 } 604 }
583 605
584 ResourceHandler* ResourceDispatcherHost::CreateSafeBrowsingResourceHandler( 606 ResourceHandler* ResourceDispatcherHost::CreateSafeBrowsingResourceHandler(
585 ResourceHandler* handler, int child_id, int route_id, 607 ResourceHandler* handler, int process_unique_id, int route_id,
586 ResourceType::Type resource_type) { 608 ResourceType::Type resource_type) {
587 return new SafeBrowsingResourceHandler(handler, 609 return new SafeBrowsingResourceHandler(handler,
588 child_id, 610 process_unique_id,
589 route_id, 611 route_id,
590 resource_type, 612 resource_type,
591 safe_browsing_, 613 safe_browsing_,
592 this, 614 this,
593 receiver_); 615 receiver_);
594 } 616 }
595 617
596 ResourceDispatcherHostRequestInfo* 618 ResourceDispatcherHostRequestInfo*
597 ResourceDispatcherHost::CreateRequestInfoForBrowserRequest( 619 ResourceDispatcherHost::CreateRequestInfoForBrowserRequest(
598 ResourceHandler* handler, int child_id, int route_id, bool download) { 620 ResourceHandler* handler,
621 int process_unique_id,
622 int route_id,
623 bool download) {
599 return new ResourceDispatcherHostRequestInfo(handler, 624 return new ResourceDispatcherHostRequestInfo(handler,
600 ChildProcessInfo::RENDER_PROCESS, 625 ChildProcessInfo::RENDER_PROCESS,
601 child_id, 626 process_unique_id,
602 route_id, 627 route_id,
603 request_id_, 628 request_id_,
604 "null", // frame_origin 629 "null", // frame_origin
605 "null", // main_frame_origin 630 "null", // main_frame_origin
606 ResourceType::SUB_RESOURCE, 631 ResourceType::SUB_RESOURCE,
607 0, // upload_size 632 0, // upload_size
608 download, // is_download 633 download, // is_download
609 download, // allow_download 634 download, // allow_download
610 -1, // Host renderer id 635 -1, // Host renderer id
611 -1); // Host render view id 636 -1); // Host render view id
(...skipping 22 matching lines...) Expand all
634 &RenderViewHost::ClosePageIgnoringUnloadEvents); 659 &RenderViewHost::ClosePageIgnoringUnloadEvents);
635 } 660 }
636 } 661 }
637 662
638 // We are explicitly forcing the download of 'url'. 663 // We are explicitly forcing the download of 'url'.
639 void ResourceDispatcherHost::BeginDownload( 664 void ResourceDispatcherHost::BeginDownload(
640 const GURL& url, 665 const GURL& url,
641 const GURL& referrer, 666 const GURL& referrer,
642 const DownloadSaveInfo& save_info, 667 const DownloadSaveInfo& save_info,
643 bool prompt_for_save_location, 668 bool prompt_for_save_location,
644 int child_id, 669 int process_unique_id,
645 int route_id, 670 int route_id,
646 URLRequestContext* request_context) { 671 URLRequestContext* request_context,
672 uint64 start_offset) {
647 if (is_shutdown_) 673 if (is_shutdown_)
648 return; 674 return;
649 675
650 // Check if the renderer is permitted to request the requested URL. 676 // Check if the renderer is permitted to request the requested URL.
651 if (!ChildProcessSecurityPolicy::GetInstance()-> 677 if (!ChildProcessSecurityPolicy::GetInstance()->
652 CanRequestURL(child_id, url)) { 678 CanRequestURL(process_unique_id, url)) {
653 LOG(INFO) << "Denied unauthorized download request for " << 679 LOG(INFO) << "Denied unauthorized download request for " <<
654 url.possibly_invalid_spec(); 680 url.possibly_invalid_spec();
655 return; 681 return;
656 } 682 }
657 683
658 // Ensure the Chrome plugins are loaded, as they may intercept network 684 // Ensure the Chrome plugins are loaded, as they may intercept network
659 // requests. Does nothing if they are already loaded. 685 // requests. Does nothing if they are already loaded.
660 PluginService::GetInstance()->LoadChromePlugins(this); 686 PluginService::GetInstance()->LoadChromePlugins(this);
661 URLRequest* request = new URLRequest(url, this); 687 URLRequest* request = new URLRequest(url, this);
662 688
663 request_id_--; 689 request_id_--;
664 690
665 scoped_refptr<ResourceHandler> handler = 691 scoped_refptr<ResourceHandler> handler =
666 new DownloadResourceHandler(this, 692 new DownloadResourceHandler(this,
667 child_id, 693 process_unique_id,
668 route_id, 694 route_id,
669 request_id_, 695 request_id_,
670 url, 696 url,
671 download_file_manager_.get(), 697 download_file_manager_.get(),
672 request, 698 request,
673 prompt_for_save_location, 699 prompt_for_save_location,
674 save_info); 700 save_info);
675 701
676 if (safe_browsing_->enabled()) { 702 if (safe_browsing_->enabled()) {
677 handler = CreateSafeBrowsingResourceHandler(handler, child_id, route_id, 703 handler = CreateSafeBrowsingResourceHandler(handler,
704 process_unique_id,
705 route_id,
678 ResourceType::MAIN_FRAME); 706 ResourceType::MAIN_FRAME);
679 } 707 }
680 708
681 if (!URLRequest::IsHandledURL(url)) { 709 if (!URLRequest::IsHandledURL(url)) {
682 LOG(INFO) << "Download request for unsupported protocol: " << 710 LOG(INFO) << "Download request for unsupported protocol: " <<
683 url.possibly_invalid_spec(); 711 url.possibly_invalid_spec();
684 return; 712 return;
685 } 713 }
686 714
687 request->set_method("GET"); 715 request->set_method("GET");
688 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( 716 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch(
689 switches::kNoReferrers) ? std::string() : referrer.spec()); 717 switches::kNoReferrers) ? std::string() : referrer.spec());
690 request->set_context(request_context); 718 request->set_context(request_context);
691 request->set_load_flags(request->load_flags() | 719 request->set_load_flags(request->load_flags() |
692 net::LOAD_IS_DOWNLOAD); 720 net::LOAD_IS_DOWNLOAD);
693 721
694 ResourceDispatcherHostRequestInfo* extra_info = 722 ResourceDispatcherHostRequestInfo* extra_info =
695 CreateRequestInfoForBrowserRequest(handler, child_id, route_id, true); 723 CreateRequestInfoForBrowserRequest(handler,
724 process_unique_id,
725 route_id,
726 true);
727
728 // If we're not at the beginning of the file, retrieve only the remaining
729 // portion.
730 if (start_offset > 0) {
731 request->SetExtraRequestHeaderByName(
732 "Range",
733 StringPrintf("bytes=%" PRId64 "-", start_offset),
734 false);
735 extra_info->set_was_interrupted(true);
736 extra_info->set_interrupted_bytes(start_offset);
737 }
738
696 SetRequestInfo(request, extra_info); // Request takes ownership. 739 SetRequestInfo(request, extra_info); // Request takes ownership.
697 chrome_browser_net::SetOriginProcessUniqueIDForRequest(child_id, request); 740 chrome_browser_net::SetOriginProcessUniqueIDForRequest(process_unique_id,
741 request);
698 742
699 BeginRequestInternal(request); 743 BeginRequestInternal(request);
700 } 744 }
701 745
702 // This function is only used for saving feature. 746 // This function is only used for saving feature.
703 void ResourceDispatcherHost::BeginSaveFile(const GURL& url, 747 void ResourceDispatcherHost::BeginSaveFile(const GURL& url,
704 const GURL& referrer, 748 const GURL& referrer,
705 int child_id, 749 int process_unique_id,
706 int route_id, 750 int route_id,
707 URLRequestContext* request_context) { 751 URLRequestContext* request_context) {
708 if (is_shutdown_) 752 if (is_shutdown_)
709 return; 753 return;
710 754
711 // Ensure the Chrome plugins are loaded, as they may intercept network 755 // Ensure the Chrome plugins are loaded, as they may intercept network
712 // requests. Does nothing if they are already loaded. 756 // requests. Does nothing if they are already loaded.
713 PluginService::GetInstance()->LoadChromePlugins(this); 757 PluginService::GetInstance()->LoadChromePlugins(this);
714 758
715 scoped_refptr<ResourceHandler> handler = 759 scoped_refptr<ResourceHandler> handler =
716 new SaveFileResourceHandler(child_id, 760 new SaveFileResourceHandler(process_unique_id,
717 route_id, 761 route_id,
718 url, 762 url,
719 save_file_manager_.get()); 763 save_file_manager_.get());
720 request_id_--; 764 request_id_--;
721 765
722 bool known_proto = URLRequest::IsHandledURL(url); 766 bool known_proto = URLRequest::IsHandledURL(url);
723 if (!known_proto) { 767 if (!known_proto) {
724 // Since any URLs which have non-standard scheme have been filtered 768 // Since any URLs which have non-standard scheme have been filtered
725 // by save manager(see GURL::SchemeIsStandard). This situation 769 // by save manager(see GURL::SchemeIsStandard). This situation
726 // should not happen. 770 // should not happen.
727 NOTREACHED(); 771 NOTREACHED();
728 return; 772 return;
729 } 773 }
730 774
731 URLRequest* request = new URLRequest(url, this); 775 URLRequest* request = new URLRequest(url, this);
732 request->set_method("GET"); 776 request->set_method("GET");
733 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch( 777 request->set_referrer(CommandLine::ForCurrentProcess()->HasSwitch(
734 switches::kNoReferrers) ? std::string() : referrer.spec()); 778 switches::kNoReferrers) ? std::string() : referrer.spec());
735 // So far, for saving page, we need fetch content from cache, in the 779 // So far, for saving page, we need fetch content from cache, in the
736 // future, maybe we can use a configuration to configure this behavior. 780 // future, maybe we can use a configuration to configure this behavior.
737 request->set_load_flags(net::LOAD_PREFERRING_CACHE); 781 request->set_load_flags(net::LOAD_PREFERRING_CACHE);
738 request->set_context(request_context); 782 request->set_context(request_context);
739 783
740 // Since we're just saving some resources we need, disallow downloading. 784 // Since we're just saving some resources we need, disallow downloading.
741 ResourceDispatcherHostRequestInfo* extra_info = 785 ResourceDispatcherHostRequestInfo* extra_info =
742 CreateRequestInfoForBrowserRequest(handler, child_id, route_id, false); 786 CreateRequestInfoForBrowserRequest(handler,
787 process_unique_id,
788 route_id,
789 false);
743 SetRequestInfo(request, extra_info); // Request takes ownership. 790 SetRequestInfo(request, extra_info); // Request takes ownership.
744 chrome_browser_net::SetOriginProcessUniqueIDForRequest(child_id, request); 791 chrome_browser_net::SetOriginProcessUniqueIDForRequest(process_unique_id,
792 request);
745 793
746 BeginRequestInternal(request); 794 BeginRequestInternal(request);
747 } 795 }
748 796
749 void ResourceDispatcherHost::FollowDeferredRedirect( 797 void ResourceDispatcherHost::FollowDeferredRedirect(
750 int child_id, 798 int process_unique_id,
751 int request_id, 799 int request_id,
752 bool has_new_first_party_for_cookies, 800 bool has_new_first_party_for_cookies,
753 const GURL& new_first_party_for_cookies) { 801 const GURL& new_first_party_for_cookies) {
754 PendingRequestList::iterator i = pending_requests_.find( 802 PendingRequestList::iterator i = pending_requests_.find(
755 GlobalRequestID(child_id, request_id)); 803 GlobalRequestID(process_unique_id, request_id));
756 if (i == pending_requests_.end() || !i->second->status().is_success()) { 804 if (i == pending_requests_.end() || !i->second->status().is_success()) {
757 DLOG(WARNING) << "FollowDeferredRedirect for invalid request"; 805 DLOG(WARNING) << "FollowDeferredRedirect for invalid request";
758 return; 806 return;
759 } 807 }
760 808
761 if (has_new_first_party_for_cookies) 809 if (has_new_first_party_for_cookies)
762 i->second->set_first_party_for_cookies(new_first_party_for_cookies); 810 i->second->set_first_party_for_cookies(new_first_party_for_cookies);
763 i->second->FollowDeferredRedirect(); 811 i->second->FollowDeferredRedirect();
764 } 812 }
765 813
766 void ResourceDispatcherHost::StartDeferredRequest(int process_unique_id, 814 void ResourceDispatcherHost::StartDeferredRequest(int process_unique_id,
767 int request_id) { 815 int request_id) {
768 GlobalRequestID global_id(process_unique_id, request_id); 816 GlobalRequestID global_id(process_unique_id, request_id);
769 PendingRequestList::iterator i = pending_requests_.find(global_id); 817 PendingRequestList::iterator i = pending_requests_.find(global_id);
770 if (i == pending_requests_.end()) { 818 if (i == pending_requests_.end()) {
771 // The request may have been destroyed 819 // The request may have been destroyed
772 LOG(WARNING) << "Trying to resume a non-existent request (" 820 LOG(WARNING) << "Trying to resume a non-existent request ("
773 << process_unique_id << ", " << request_id << ")"; 821 << process_unique_id << ", " << request_id << ")";
774 return; 822 return;
775 } 823 }
776 824
777 // TODO(eroman): are there other considerations for paused or blocked 825 // TODO(eroman): are there other considerations for paused or blocked
778 // requests? 826 // requests?
779 827
780 URLRequest* request = i->second; 828 URLRequest* request = i->second;
781 InsertIntoResourceQueue(request, *InfoForRequest(request)); 829 InsertIntoResourceQueue(request, *InfoForRequest(request));
782 } 830 }
783 831
784 bool ResourceDispatcherHost::WillSendData(int child_id, 832 bool ResourceDispatcherHost::WillSendData(int process_unique_id,
785 int request_id) { 833 int request_id) {
786 PendingRequestList::iterator i = pending_requests_.find( 834 PendingRequestList::iterator i = pending_requests_.find(
787 GlobalRequestID(child_id, request_id)); 835 GlobalRequestID(process_unique_id, request_id));
788 if (i == pending_requests_.end()) { 836 if (i == pending_requests_.end()) {
789 NOTREACHED() << "WillSendData for invalid request"; 837 NOTREACHED() << "WillSendData for invalid request";
790 return false; 838 return false;
791 } 839 }
792 840
793 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); 841 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second);
794 842
795 info->IncrementPendingDataCount(); 843 info->IncrementPendingDataCount();
796 if (info->pending_data_count() > kMaxPendingDataMessages) { 844 if (info->pending_data_count() > kMaxPendingDataMessages) {
797 // We reached the max number of data messages that can be sent to 845 // We reached the max number of data messages that can be sent to
798 // the renderer for a given request. Pause the request and wait for 846 // the renderer for a given request. Pause the request and wait for
799 // the renderer to start processing them before resuming it. 847 // the renderer to start processing them before resuming it.
800 PauseRequest(child_id, request_id, true); 848 PauseRequest(process_unique_id, request_id, true);
801 return false; 849 return false;
802 } 850 }
803 851
804 return true; 852 return true;
805 } 853 }
806 854
807 void ResourceDispatcherHost::PauseRequest(int child_id, 855 void ResourceDispatcherHost::PauseRequest(int process_unique_id,
808 int request_id, 856 int request_id,
809 bool pause) { 857 bool pause) {
810 GlobalRequestID global_id(child_id, request_id); 858 GlobalRequestID global_id(process_unique_id, request_id);
811 PendingRequestList::iterator i = pending_requests_.find(global_id); 859 PendingRequestList::iterator i = pending_requests_.find(global_id);
812 if (i == pending_requests_.end()) { 860 if (i == pending_requests_.end()) {
813 DLOG(WARNING) << "Pausing a request that wasn't found"; 861 DLOG(WARNING) << "Pausing a request that wasn't found";
814 return; 862 return;
815 } 863 }
816 864
817 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); 865 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second);
818 int pause_count = info->pause_count() + (pause ? 1 : -1); 866 int pause_count = info->pause_count() + (pause ? 1 : -1);
819 if (pause_count < 0) { 867 if (pause_count < 0) {
820 NOTREACHED(); // Unbalanced call to pause. 868 NOTREACHED(); // Unbalanced call to pause.
821 return; 869 return;
822 } 870 }
823 info->set_pause_count(pause_count); 871 info->set_pause_count(pause_count);
824 872
825 RESOURCE_LOG("To pause (" << pause << "): " << i->second->url().spec()); 873 RESOURCE_LOG("To pause (" << pause << "): " << i->second->url().spec());
826 874
827 // If we're resuming, kick the request to start reading again. Run the read 875 // If we're resuming, kick the request to start reading again. Run the read
828 // asynchronously to avoid recursion problems. 876 // asynchronously to avoid recursion problems.
829 if (info->pause_count() == 0) { 877 if (info->pause_count() == 0) {
830 MessageLoop::current()->PostTask(FROM_HERE, 878 MessageLoop::current()->PostTask(
879 FROM_HERE,
831 method_runner_.NewRunnableMethod( 880 method_runner_.NewRunnableMethod(
832 &ResourceDispatcherHost::ResumeRequest, global_id)); 881 &ResourceDispatcherHost::ResumeRequest, global_id));
833 } 882 }
834 } 883 }
835 884
885 void ResourceDispatcherHost::RestartRequest(int process_unique_id,
886 int request_id,
887 DownloadCreateInfo* create_info) {
888 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
889 GlobalRequestID global_id(process_unique_id, request_id);
890 RESOURCE_LOG("Restart : " << url.spec());
891
892 // Copy the IDs from the existing interrupted request.
893 PendingRequestList::iterator i = interrupted_requests_.find(global_id);
894 if (i != interrupted_requests_.end()) {
895 URLRequest* request = i->second;
896 if (request) {
897 ResourceDispatcherHostRequestInfo* req_info = InfoForRequest(request);
898 create_info->render_view_id = req_info->route_id();
899 create_info->child_id = req_info->child_id();
900 }
901
902 MoveInterruptedRequestToPending(process_unique_id, request_id);
903 }
904
905 // Restart the request to continue reading. Run the read asynchronously to
906 // avoid recursion problems.
907 ChromeThread::PostTask(
908 ChromeThread::FILE,
909 FROM_HERE,
910 NewRunnableFunction(&ResourceDispatcherHost::RestartDownload,
911 this,
912 global_id,
913 create_info));
914 }
915
836 int ResourceDispatcherHost::GetOutstandingRequestsMemoryCost( 916 int ResourceDispatcherHost::GetOutstandingRequestsMemoryCost(
837 int child_id) const { 917 int process_unique_id) const {
838 OutstandingRequestsMemoryCostMap::const_iterator entry = 918 OutstandingRequestsMemoryCostMap::const_iterator entry =
839 outstanding_requests_memory_cost_map_.find(child_id); 919 outstanding_requests_memory_cost_map_.find(process_unique_id);
840 return (entry == outstanding_requests_memory_cost_map_.end()) ? 920 return (entry == outstanding_requests_memory_cost_map_.end()) ?
841 0 : entry->second; 921 0 : entry->second;
842 } 922 }
843 923
844 // The object died, so cancel and detach all requests associated with it except 924 // The object died, so cancel and detach all requests associated with it except
845 // for downloads, which belong to the browser process even if initiated via a 925 // for downloads, which belong to the browser process even if initiated via a
846 // renderer. 926 // renderer.
847 void ResourceDispatcherHost::CancelRequestsForProcess(int child_id) { 927 void ResourceDispatcherHost::CancelRequestsForProcess(int process_unique_id) {
848 socket_stream_dispatcher_host_->CancelRequestsForProcess(child_id); 928 socket_stream_dispatcher_host_->CancelRequestsForProcess(process_unique_id);
849 CancelRequestsForRoute(child_id, -1 /* cancel all */); 929 CancelRequestsForRoute(process_unique_id, -1 /* cancel all */);
850 } 930 }
851 931
852 void ResourceDispatcherHost::CancelRequestsForRoute(int child_id, 932 std::vector<GlobalRequestID> ResourceDispatcherHost::GetMatchingRequests(
933 int process_unique_id,
934 int route_id,
935 const PendingRequestList& requests) {
936 std::vector<GlobalRequestID> matching_requests;
937 for (PendingRequestList::const_iterator i = requests.begin();
938 i != requests.end(); ++i) {
939 if (i->first.child_id == process_unique_id) {
940 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second);
941 if (!info->is_download() &&
942 (route_id == -1 || route_id == info->route_id())) {
943 matching_requests.push_back(
944 GlobalRequestID(process_unique_id, i->first.request_id));
945 }
946 }
947 }
948 return matching_requests;
949 }
950
951 void ResourceDispatcherHost::CancelRequestsForRoute(int process_unique_id,
853 int route_id) { 952 int route_id) {
854 // Since pending_requests_ is a map, we first build up a list of all of the 953 // Since pending_requests_ is a map, we first build up a list of all of the
855 // matching requests to be cancelled, and then we cancel them. Since there 954 // matching requests to be cancelled, and then we cancel them. Since there
856 // may be more than one request to cancel, we cannot simply hold onto the map 955 // may be more than one request to cancel, we cannot simply hold onto the map
857 // iterators found in the first loop. 956 // iterators found in the first loop.
858 957
859 // Find the global ID of all matching elements. 958 // Find the global ID of all matching elements.
860 std::vector<GlobalRequestID> matching_requests; 959 std::vector<GlobalRequestID> matching_requests =
861 for (PendingRequestList::const_iterator i = pending_requests_.begin(); 960 GetMatchingRequests(process_unique_id, route_id, pending_requests_);
862 i != pending_requests_.end(); ++i) { 961 std::vector<GlobalRequestID> matching_requests2 =
863 if (i->first.child_id == child_id) { 962 GetMatchingRequests(process_unique_id, route_id, interrupted_requests_);
864 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); 963 matching_requests.insert(matching_requests.begin(),
865 if (!info->is_download() && 964 matching_requests2.begin(),
866 (route_id == -1 || route_id == info->route_id())) { 965 matching_requests2.end());
867 matching_requests.push_back(
868 GlobalRequestID(child_id, i->first.request_id));
869 }
870 }
871 }
872 966
873 // Remove matches. 967 // Remove matches.
874 for (size_t i = 0; i < matching_requests.size(); ++i) { 968 for (size_t i = 0; i < matching_requests.size(); ++i) {
875 PendingRequestList::iterator iter = 969 PendingRequestList::iterator iter =
876 pending_requests_.find(matching_requests[i]); 970 pending_requests_.find(matching_requests[i]);
877 // Although every matching request was in pending_requests_ when we built 971 // Although every matching request was in pending_requests_ when we built
878 // matching_requests, it is normal for a matching request to be not found 972 // matching_requests, it is normal for a matching request to be not found
879 // in pending_requests_ after we have removed some matching requests from 973 // in pending_requests_ after we have removed some matching requests from
880 // pending_requests_. For example, deleting a URLRequest that has 974 // pending_requests_. For example, deleting a URLRequest that has
881 // exclusive (write) access to an HTTP cache entry may unblock another 975 // exclusive (write) access to an HTTP cache entry may unblock another
882 // URLRequest that needs exclusive access to the same cache entry, and 976 // URLRequest that needs exclusive access to the same cache entry, and
883 // that URLRequest may complete and remove itself from pending_requests_. 977 // that URLRequest may complete and remove itself from pending_requests_.
884 // So we need to check that iter is not equal to pending_requests_.end(). 978 // So we need to check that iter is not equal to pending_requests_.end().
885 if (iter != pending_requests_.end()) 979 if (iter != pending_requests_.end())
886 RemovePendingRequest(iter); 980 RemoveRequestFromMap(iter);
981 // Same for interrupted requests.
982 iter = interrupted_requests_.find(matching_requests[i]);
983 if (iter != interrupted_requests_.end())
984 RemoveRequestFromMap(iter);
887 } 985 }
888 986
889 // Now deal with blocked requests if any. 987 // Now deal with blocked requests if any.
890 if (route_id != -1) { 988 if (route_id != -1) {
891 if (blocked_requests_map_.find(std::pair<int, int>(child_id, route_id)) != 989 if (blocked_requests_map_.find(std::pair<int, int>(process_unique_id,
990 route_id)) !=
892 blocked_requests_map_.end()) { 991 blocked_requests_map_.end()) {
893 CancelBlockedRequestsForRoute(child_id, route_id); 992 CancelBlockedRequestsForRoute(process_unique_id, route_id);
894 } 993 }
895 } else { 994 } else {
896 // We have to do all render views for the process |child_id|. 995 // We have to do all render views for the process |process_unique_id|.
897 // Note that we have to do this in 2 passes as we cannot call 996 // Note that we have to do this in 2 passes as we cannot call
898 // CancelBlockedRequestsForRoute while iterating over 997 // CancelBlockedRequestsForRoute while iterating over
899 // blocked_requests_map_, as it modifies it. 998 // blocked_requests_map_, as it modifies it.
900 std::set<int> route_ids; 999 std::set<int> route_ids;
901 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin(); 1000 for (BlockedRequestMap::const_iterator iter = blocked_requests_map_.begin();
902 iter != blocked_requests_map_.end(); ++iter) { 1001 iter != blocked_requests_map_.end(); ++iter) {
903 if (iter->first.first == child_id) 1002 if (iter->first.first == process_unique_id)
904 route_ids.insert(iter->first.second); 1003 route_ids.insert(iter->first.second);
905 } 1004 }
906 for (std::set<int>::const_iterator iter = route_ids.begin(); 1005 for (std::set<int>::const_iterator iter = route_ids.begin();
907 iter != route_ids.end(); ++iter) { 1006 iter != route_ids.end(); ++iter) {
908 CancelBlockedRequestsForRoute(child_id, *iter); 1007 CancelBlockedRequestsForRoute(process_unique_id, *iter);
909 } 1008 }
910 } 1009 }
911 } 1010 }
912 1011
913 // Cancels the request and removes it from the list. 1012 // Cancels the request and removes it from the list.
914 void ResourceDispatcherHost::RemovePendingRequest(int child_id, 1013 void ResourceDispatcherHost::RemovePendingRequest(int process_unique_id,
915 int request_id) { 1014 int request_id) {
916 PendingRequestList::iterator i = pending_requests_.find( 1015 GlobalRequestID id(process_unique_id, request_id);
917 GlobalRequestID(child_id, request_id)); 1016 PendingRequestList::iterator i = pending_requests_.find(id);
918 if (i == pending_requests_.end()) { 1017 if (i == pending_requests_.end()) {
1018 i = interrupted_requests_.find(id);
1019 if (i != interrupted_requests_.end())
1020 return;
919 NOTREACHED() << "Trying to remove a request that's not here"; 1021 NOTREACHED() << "Trying to remove a request that's not here";
920 return; 1022 return;
921 } 1023 }
922 RemovePendingRequest(i); 1024 RemoveRequestFromMap(i);
923 } 1025 }
924 1026
925 void ResourceDispatcherHost::RemovePendingRequest( 1027 // Cancels the request and removes it from the list.
1028 void ResourceDispatcherHost::RemoveInterruptedRequest(int process_unique_id,
1029 int request_id) {
1030 GlobalRequestID id(process_unique_id, request_id);
1031 PendingRequestList::iterator i = interrupted_requests_.find(id);
1032 if (i == interrupted_requests_.end()) {
1033 NOTREACHED() << "Trying to remove a request that's not here";
1034 return;
1035 }
1036 RemoveRequestFromMap(i);
1037 }
1038
1039 void ResourceDispatcherHost::MovePendingRequestToInterrupted(
1040 int process_unique_id, int request_id) {
1041 GlobalRequestID id(process_unique_id, request_id);
1042 PendingRequestList::iterator iter = pending_requests_.find(id);
1043 if (iter == pending_requests_.end())
1044 return;
1045
1046 URLRequest* url_req = iter->second;
1047
1048 ResourceDispatcherHostRequestInfo* info = InfoForRequest(url_req);
1049
1050 info->set_was_interrupted(true);
1051
1052 interrupted_requests_[id] = pending_requests_[id];
1053 pending_requests_.erase(iter);
1054
1055 // If we have no more pending requests, then stop the load state monitor
1056 if (pending_requests_.empty())
1057 update_load_states_timer_.Stop();
1058 }
1059
1060 void ResourceDispatcherHost::MoveInterruptedRequestToPending(
1061 int process_unique_id, int request_id) {
1062 GlobalRequestID id(process_unique_id, request_id);
1063 PendingRequestList::iterator iter = interrupted_requests_.find(id);
1064 if (iter == interrupted_requests_.end())
1065 return;
1066
1067 // Don't need to call info->set_was_interrupted(false), as we will have
1068 // a new URLRequest when we resume downloading. If we clear it here,
1069 // then the information won't be available to
1070 // DownloadResourceHandler::OnResponseStarted().
1071
1072 pending_requests_[id] = interrupted_requests_[id];
1073 interrupted_requests_.erase(iter);
1074 }
1075
1076 void ResourceDispatcherHost::RemoveRequestFromMap(
926 const PendingRequestList::iterator& iter) { 1077 const PendingRequestList::iterator& iter) {
927 ResourceDispatcherHostRequestInfo* info = InfoForRequest(iter->second); 1078 ResourceDispatcherHostRequestInfo* info = InfoForRequest(iter->second);
928 1079
929 // Remove the memory credit that we added when pushing the request onto 1080 // Remove the memory credit that we added when pushing the request onto
930 // the pending list. 1081 // the pending list.
931 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(), 1082 IncrementOutstandingRequestsMemoryCost(-1 * info->memory_cost(),
932 info->child_id()); 1083 info->child_id());
933 1084
934 // Notify interested parties that the request object is going away. 1085 // Notify interested parties that the request object is going away.
935 if (info->login_handler()) 1086 if (info->login_handler())
936 info->login_handler()->OnRequestCancelled(); 1087 info->login_handler()->OnRequestCancelled();
937 if (info->ssl_client_auth_handler()) 1088 if (info->ssl_client_auth_handler())
938 info->ssl_client_auth_handler()->OnRequestCancelled(); 1089 info->ssl_client_auth_handler()->OnRequestCancelled();
939 resource_queue_.RemoveRequest(iter->first); 1090
1091 GlobalRequestID id = iter->first;
1092 resource_queue_.RemoveRequest(id);
940 1093
941 delete iter->second; 1094 delete iter->second;
942 pending_requests_.erase(iter); 1095 if (pending_requests_.find(id) != pending_requests_.end()) {
1096 pending_requests_.erase(iter);
943 1097
944 // If we have no more pending requests, then stop the load state monitor 1098 // If we have no more pending requests, then stop the load state monitor
945 if (pending_requests_.empty()) 1099 if (pending_requests_.empty())
946 update_load_states_timer_.Stop(); 1100 update_load_states_timer_.Stop();
1101 }
1102 if (interrupted_requests_.find(id) != interrupted_requests_.end())
1103 interrupted_requests_.erase(iter);
947 } 1104 }
948 1105
949 // URLRequest::Delegate ------------------------------------------------------- 1106 // URLRequest::Delegate -------------------------------------------------------
950 1107
951 void ResourceDispatcherHost::OnReceivedRedirect(URLRequest* request, 1108 void ResourceDispatcherHost::OnReceivedRedirect(URLRequest* request,
952 const GURL& new_url, 1109 const GURL& new_url,
953 bool* defer_redirect) { 1110 bool* defer_redirect) {
954 RESOURCE_LOG("OnReceivedRedirect: " << request->url().spec()); 1111 RESOURCE_LOG("OnReceivedRedirect: " << request->url().spec());
955 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); 1112 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
956 1113
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 request->ssl_info().security_bits == 0) && 1254 request->ssl_info().security_bits == 0) &&
1098 !request->ssl_info().connection_status); 1255 !request->ssl_info().connection_status);
1099 } 1256 }
1100 1257
1101 NotifyResponseStarted(request, info->child_id()); 1258 NotifyResponseStarted(request, info->child_id());
1102 info->set_called_on_response_started(true); 1259 info->set_called_on_response_started(true);
1103 return info->resource_handler()->OnResponseStarted(info->request_id(), 1260 return info->resource_handler()->OnResponseStarted(info->request_id(),
1104 response.get()); 1261 response.get());
1105 } 1262 }
1106 1263
1107 void ResourceDispatcherHost::CancelRequest(int child_id, 1264 void ResourceDispatcherHost::CancelRequest(int process_unique_id,
1108 int request_id, 1265 int request_id,
1109 bool from_renderer) { 1266 bool from_renderer) {
1110 PendingRequestList::iterator i = pending_requests_.find( 1267 GlobalRequestID id(process_unique_id, request_id);
1111 GlobalRequestID(child_id, request_id)); 1268 PendingRequestList::iterator i = pending_requests_.find(id);
1112 if (i == pending_requests_.end()) { 1269 if (i == pending_requests_.end()) {
1113 // We probably want to remove this warning eventually, but I wanted to be 1270 i = interrupted_requests_.find(id);
1114 // able to notice when this happens during initial development since it 1271 if (i == interrupted_requests_.end()) {
1115 // should be rare and may indicate a bug. 1272 // We probably want to remove this warning eventually, but I wanted to be
1116 DLOG(WARNING) << "Canceling a request that wasn't found"; 1273 // able to notice when this happens during initial development since it
1117 return; 1274 // should be rare and may indicate a bug.
1275 DLOG(WARNING) << "Canceling a request that wasn't found";
1276 return;
1277 }
1118 } 1278 }
1119 CancelRequestInternal(i->second, from_renderer); 1279 CancelRequestInternal(i->second, from_renderer);
1120 } 1280 }
1121 1281
1122 void ResourceDispatcherHost::CancelRequestInternal(URLRequest* request, 1282 void ResourceDispatcherHost::CancelRequestInternal(URLRequest* request,
1123 bool from_renderer) { 1283 bool from_renderer) {
1124 RESOURCE_LOG("CancelRequest: " << request->url().spec()); 1284 RESOURCE_LOG("CancelRequest: " << request->url().spec());
1125 1285
1126 // WebKit will send us a cancel for downloads since it no longer handles them. 1286 // WebKit will send us a cancel for downloads since it no longer handles them.
1127 // In this case, ignore the cancel since we handle downloads in the browser. 1287 // In this case, ignore the cancel since we handle downloads in the browser.
(...skipping 12 matching lines...) Expand all
1140 DCHECK(IsValidRequest(request)); 1300 DCHECK(IsValidRequest(request));
1141 } 1301 }
1142 1302
1143 // Do not remove from the pending requests, as the request will still 1303 // Do not remove from the pending requests, as the request will still
1144 // call AllDataReceived, and may even have more data before it does 1304 // call AllDataReceived, and may even have more data before it does
1145 // that. 1305 // that.
1146 } 1306 }
1147 1307
1148 int ResourceDispatcherHost::IncrementOutstandingRequestsMemoryCost( 1308 int ResourceDispatcherHost::IncrementOutstandingRequestsMemoryCost(
1149 int cost, 1309 int cost,
1150 int child_id) { 1310 int process_unique_id) {
1151 // Retrieve the previous value (defaulting to 0 if not found). 1311 // Retrieve the previous value (defaulting to 0 if not found).
1152 OutstandingRequestsMemoryCostMap::iterator prev_entry = 1312 OutstandingRequestsMemoryCostMap::iterator prev_entry =
1153 outstanding_requests_memory_cost_map_.find(child_id); 1313 outstanding_requests_memory_cost_map_.find(process_unique_id);
1154 int new_cost = 0; 1314 int new_cost = 0;
1155 if (prev_entry != outstanding_requests_memory_cost_map_.end()) 1315 if (prev_entry != outstanding_requests_memory_cost_map_.end())
1156 new_cost = prev_entry->second; 1316 new_cost = prev_entry->second;
1157 1317
1158 // Insert/update the total; delete entries when their value reaches 0. 1318 // Insert/update the total; delete entries when their value reaches 0.
1159 new_cost += cost; 1319 new_cost += cost;
1160 CHECK(new_cost >= 0); 1320 CHECK(new_cost >= 0);
1161 if (new_cost == 0) 1321 if (new_cost == 0)
1162 outstanding_requests_memory_cost_map_.erase(prev_entry); 1322 outstanding_requests_memory_cost_map_.erase(prev_entry);
1163 else 1323 else
1164 outstanding_requests_memory_cost_map_[child_id] = new_cost; 1324 outstanding_requests_memory_cost_map_[process_unique_id] = new_cost;
1165 1325
1166 return new_cost; 1326 return new_cost;
1167 } 1327 }
1168 1328
1169 // static 1329 // static
1170 int ResourceDispatcherHost::CalculateApproximateMemoryCost( 1330 int ResourceDispatcherHost::CalculateApproximateMemoryCost(
1171 URLRequest* request) { 1331 URLRequest* request) {
1172 // The following fields should be a minor size contribution (experimentally 1332 // The following fields should be a minor size contribution (experimentally
1173 // on the order of 100). However since they are variable length, it could 1333 // on the order of 100). However since they are variable length, it could
1174 // in theory be a sizeable contribution. 1334 // in theory be a sizeable contribution.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 void ResourceDispatcherHost::ResumeRequest(const GlobalRequestID& request_id) { 1445 void ResourceDispatcherHost::ResumeRequest(const GlobalRequestID& request_id) {
1286 PendingRequestList::iterator i = pending_requests_.find(request_id); 1446 PendingRequestList::iterator i = pending_requests_.find(request_id);
1287 if (i == pending_requests_.end()) // The request may have been destroyed 1447 if (i == pending_requests_.end()) // The request may have been destroyed
1288 return; 1448 return;
1289 1449
1290 URLRequest* request = i->second; 1450 URLRequest* request = i->second;
1291 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); 1451 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
1292 if (!info->is_paused()) 1452 if (!info->is_paused())
1293 return; 1453 return;
1294 1454
1295 RESOURCE_LOG("Resuming: " << i->second->url().spec()); 1455 RESOURCE_LOG("Resuming: " << request->url().spec());
1296 1456
1297 info->set_is_paused(false); 1457 info->set_is_paused(false);
1298 1458
1299 if (info->called_on_response_started()) { 1459 if (info->called_on_response_started()) {
1300 if (info->has_started_reading()) { 1460 if (info->has_started_reading()) {
1301 OnReadCompleted(i->second, info->paused_read_bytes()); 1461 OnReadCompleted(request, info->paused_read_bytes());
1302 } else { 1462 } else {
1303 StartReading(request); 1463 StartReading(request);
1304 } 1464 }
1305 } else { 1465 } else {
1306 OnResponseStarted(i->second); 1466 OnResponseStarted(request);
1307 } 1467 }
1308 } 1468 }
1309 1469
1470 // static
1471 void ResourceDispatcherHost::RestartDownload(
1472 ResourceDispatcherHost* rdh,
1473 const GlobalRequestID& request_id,
1474 DownloadCreateInfo* info) {
1475 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
1476 RESOURCE_LOG("Restarting: " << info->url.spec());
1477
1478 // Restart the request.
1479 download_util::RestartDownloadUrl(rdh,
1480 info->url,
1481 info->referrer_url,
1482 info->path,
1483 info->received_bytes,
1484 request_id.child_id,
1485 info->render_view_id);
1486
1487 // Clean up.
1488 delete info;
1489 }
1490
1310 void ResourceDispatcherHost::StartReading(URLRequest* request) { 1491 void ResourceDispatcherHost::StartReading(URLRequest* request) {
1311 // Start reading. 1492 // Start reading.
1312 int bytes_read = 0; 1493 int bytes_read = 0;
1313 if (Read(request, &bytes_read)) { 1494 if (Read(request, &bytes_read)) {
1314 OnReadCompleted(request, bytes_read); 1495 OnReadCompleted(request, bytes_read);
1315 } else if (!request->status().is_io_pending()) { 1496 } else if (!request->status().is_io_pending()) {
1316 DCHECK(!InfoForRequest(request)->is_paused()); 1497 DCHECK(!InfoForRequest(request)->is_paused());
1317 // If the error is not an IO pending, then we're done reading. 1498 // If the error is not an IO pending, then we're done reading.
1318 OnResponseCompleted(request); 1499 OnResponseCompleted(request);
1319 } 1500 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 int cert_id = CertStore::GetSharedInstance()->StoreCert(ssl_info.cert, 1607 int cert_id = CertStore::GetSharedInstance()->StoreCert(ssl_info.cert,
1427 info->child_id()); 1608 info->child_id());
1428 security_info = SSLManager::SerializeSecurityInfo( 1609 security_info = SSLManager::SerializeSecurityInfo(
1429 cert_id, ssl_info.cert_status, ssl_info.security_bits, 1610 cert_id, ssl_info.cert_status, ssl_info.security_bits,
1430 ssl_info.connection_status); 1611 ssl_info.connection_status);
1431 } 1612 }
1432 1613
1433 if (info->resource_handler()->OnResponseCompleted(info->request_id(), 1614 if (info->resource_handler()->OnResponseCompleted(info->request_id(),
1434 request->status(), 1615 request->status(),
1435 security_info)) { 1616 security_info)) {
1617 if ((request->status().status() == URLRequestStatus::FAILED) &&
1618 (request->status().os_error() < 0)) {
1619 MovePendingRequestToInterrupted(info->child_id(), info->request_id());
1620 }
1621
1436 NotifyResponseCompleted(request, info->child_id()); 1622 NotifyResponseCompleted(request, info->child_id());
1437 1623
1438 // The request is complete so we can remove it. 1624 // The request is complete so we can remove it.
1439 RemovePendingRequest(info->child_id(), info->request_id()); 1625 RemovePendingRequest(info->child_id(), info->request_id());
1440 } 1626 }
1441 // If the handler's OnResponseCompleted returns false, we are deferring the 1627 // If the handler's OnResponseCompleted returns false, we are deferring the
1442 // call until later. We will notify the world and clean up when we resume. 1628 // call until later. We will notify the world and clean up when we resume.
1443 } 1629 }
1444 1630
1445 // static 1631 // static
1446 ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest( 1632 ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest(
1447 URLRequest* request) { 1633 URLRequest* request) {
1448 // Avoid writing this function twice by casting the cosnt version. 1634 // Avoid writing this function twice by casting the const version.
1449 const URLRequest* const_request = request; 1635 const URLRequest* const_request = request;
1450 return const_cast<ResourceDispatcherHostRequestInfo*>( 1636 return const_cast<ResourceDispatcherHostRequestInfo*>(
1451 InfoForRequest(const_request)); 1637 InfoForRequest(const_request));
1452 } 1638 }
1453 1639
1454 // static 1640 // static
1455 const ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest( 1641 const ResourceDispatcherHostRequestInfo* ResourceDispatcherHost::InfoForRequest(
1456 const URLRequest* request) { 1642 const URLRequest* request) {
1457 const ResourceDispatcherHostRequestInfo* info = 1643 const ResourceDispatcherHostRequestInfo* info =
1458 static_cast<const ResourceDispatcherHostRequestInfo*>( 1644 static_cast<const ResourceDispatcherHostRequestInfo*>(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 void ResourceDispatcherHost::RemoveObserver(Observer* obs) { 1688 void ResourceDispatcherHost::RemoveObserver(Observer* obs) {
1503 observer_list_.RemoveObserver(obs); 1689 observer_list_.RemoveObserver(obs);
1504 } 1690 }
1505 1691
1506 URLRequest* ResourceDispatcherHost::GetURLRequest( 1692 URLRequest* ResourceDispatcherHost::GetURLRequest(
1507 const GlobalRequestID& request_id) const { 1693 const GlobalRequestID& request_id) const {
1508 // This should be running in the IO loop. 1694 // This should be running in the IO loop.
1509 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 1695 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
1510 1696
1511 PendingRequestList::const_iterator i = pending_requests_.find(request_id); 1697 PendingRequestList::const_iterator i = pending_requests_.find(request_id);
1512 if (i == pending_requests_.end()) 1698 if (i == pending_requests_.end()) {
1513 return NULL; 1699 i = interrupted_requests_.find(request_id);
1700 if (i == interrupted_requests_.end())
1701 return NULL;
1702 }
1514 1703
1515 return i->second; 1704 return i->second;
1516 } 1705 }
1517 1706
1518 static int GetCertID(URLRequest* request, int child_id) { 1707 static int GetCertID(URLRequest* request, int process_unique_id) {
1519 if (request->ssl_info().cert) { 1708 if (request->ssl_info().cert) {
1520 return CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert, 1709 return CertStore::GetSharedInstance()->StoreCert(request->ssl_info().cert,
1521 child_id); 1710 process_unique_id);
1522 } 1711 }
1523 // If there is no SSL info attached to this request, we must either be a non 1712 // If there is no SSL info attached to this request, we must either be a non
1524 // secure request, or the request has been canceled or failed (before the SSL 1713 // secure request, or the request has been canceled or failed (before the SSL
1525 // info was populated), or the response is an error (we have seen 403, 404, 1714 // info was populated), or the response is an error (we have seen 403, 404,
1526 // and 501) made up by the proxy. 1715 // and 501) made up by the proxy.
1527 DCHECK(!request->url().SchemeIsSecure() || 1716 DCHECK(!request->url().SchemeIsSecure() ||
1528 (request->status().status() == URLRequestStatus::CANCELED) || 1717 (request->status().status() == URLRequestStatus::CANCELED) ||
1529 (request->status().status() == URLRequestStatus::FAILED) || 1718 (request->status().status() == URLRequestStatus::FAILED) ||
1530 ((request->response_headers()->response_code() >= 400) && 1719 ((request->response_headers()->response_code() >= 400) &&
1531 (request->response_headers()->response_code() <= 599))); 1720 (request->response_headers()->response_code() <= 599)));
1532 return 0; 1721 return 0;
1533 } 1722 }
1534 1723
1535 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request, 1724 void ResourceDispatcherHost::NotifyResponseStarted(URLRequest* request,
1536 int child_id) { 1725 int process_unique_id) {
1537 // Notify the observers on the IO thread. 1726 // Notify the observers on the IO thread.
1538 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request)); 1727 FOR_EACH_OBSERVER(Observer, observer_list_, OnRequestStarted(this, request));
1539 1728
1540 int render_process_id, render_view_id; 1729 int render_process_id, render_view_id;
1541 if (!RenderViewForRequest(request, &render_process_id, &render_view_id)) 1730 if (!RenderViewForRequest(request, &render_process_id, &render_view_id))
1542 return; 1731 return;
1543 1732
1544 // Notify the observers on the UI thread. 1733 // Notify the observers on the UI thread.
1545 CallRenderViewHostResourceDelegate( 1734 CallRenderViewHostResourceDelegate(
1546 render_process_id, render_view_id, 1735 render_process_id, render_view_id,
1547 &RenderViewHostDelegate::Resource::DidStartReceivingResourceResponse, 1736 &RenderViewHostDelegate::Resource::DidStartReceivingResourceResponse,
1548 ResourceRequestDetails(request, GetCertID(request, child_id))); 1737 ResourceRequestDetails(request, GetCertID(request, process_unique_id)));
1549 } 1738 }
1550 1739
1551 void ResourceDispatcherHost::NotifyResponseCompleted(URLRequest* request, 1740 void ResourceDispatcherHost::NotifyResponseCompleted(URLRequest* request,
1552 int child_id) { 1741 int process_unique_id) {
1553 // Notify the observers on the IO thread. 1742 // Notify the observers on the IO thread.
1554 FOR_EACH_OBSERVER(Observer, observer_list_, 1743 FOR_EACH_OBSERVER(Observer, observer_list_,
1555 OnResponseCompleted(this, request)); 1744 OnResponseCompleted(this, request));
1556 } 1745 }
1557 1746
1558 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request, 1747 void ResourceDispatcherHost::NotifyReceivedRedirect(URLRequest* request,
1559 int child_id, 1748 int process_unique_id,
1560 const GURL& new_url) { 1749 const GURL& new_url) {
1561 // Notify the observers on the IO thread. 1750 // Notify the observers on the IO thread.
1562 FOR_EACH_OBSERVER(Observer, observer_list_, 1751 FOR_EACH_OBSERVER(Observer, observer_list_,
1563 OnReceivedRedirect(this, request, new_url)); 1752 OnReceivedRedirect(this, request, new_url));
1564 1753
1565 int render_process_id, render_view_id; 1754 int render_process_id, render_view_id;
1566 if (!RenderViewForRequest(request, &render_process_id, &render_view_id)) 1755 if (!RenderViewForRequest(request, &render_process_id, &render_view_id))
1567 return; 1756 return;
1568 1757
1569 // Notify the observers on the UI thread. 1758 // Notify the observers on the UI thread.
1570 CallRenderViewHostResourceDelegate( 1759 CallRenderViewHostResourceDelegate(
1571 render_process_id, render_view_id, 1760 render_process_id, render_view_id,
1572 &RenderViewHostDelegate::Resource::DidRedirectResource, 1761 &RenderViewHostDelegate::Resource::DidRedirectResource,
1573 ResourceRedirectDetails(request, GetCertID(request, child_id), new_url)); 1762 ResourceRedirectDetails(request,
1763 GetCertID(request, process_unique_id),
1764 new_url));
1574 } 1765 }
1575 1766
1576 namespace { 1767 namespace {
1577 1768
1578 // This function attempts to return the "more interesting" load state of |a| 1769 // This function attempts to return the "more interesting" load state of |a|
1579 // and |b|. We don't have temporal information about these load states 1770 // and |b|. We don't have temporal information about these load states
1580 // (meaning we don't know when we transitioned into these states), so we just 1771 // (meaning we don't know when we transitioned into these states), so we just
1581 // rank them according to how "interesting" the states are. 1772 // rank them according to how "interesting" the states are.
1582 // 1773 //
1583 // We take advantage of the fact that the load states are an enumeration listed 1774 // We take advantage of the fact that the load states are an enumeration listed
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 position, size); 1914 position, size);
1724 info->set_waiting_for_upload_progress_ack(true); 1915 info->set_waiting_for_upload_progress_ack(true);
1725 } 1916 }
1726 info->set_last_upload_ticks(TimeTicks::Now()); 1917 info->set_last_upload_ticks(TimeTicks::Now());
1727 info->set_last_upload_position(position); 1918 info->set_last_upload_position(position);
1728 return true; 1919 return true;
1729 } 1920 }
1730 return false; 1921 return false;
1731 } 1922 }
1732 1923
1733 void ResourceDispatcherHost::BlockRequestsForRoute(int child_id, int route_id) { 1924 void ResourceDispatcherHost::BlockRequestsForRoute(int process_unique_id,
1734 std::pair<int, int> key(child_id, route_id); 1925 int route_id) {
1926 std::pair<int, int> key(process_unique_id, route_id);
1735 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) << 1927 DCHECK(blocked_requests_map_.find(key) == blocked_requests_map_.end()) <<
1736 "BlockRequestsForRoute called multiple time for the same RVH"; 1928 "BlockRequestsForRoute called multiple time for the same RVH";
1737 blocked_requests_map_[key] = new BlockedRequestsList(); 1929 blocked_requests_map_[key] = new BlockedRequestsList();
1738 } 1930 }
1739 1931
1740 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(int child_id, 1932 void ResourceDispatcherHost::ResumeBlockedRequestsForRoute(
1741 int route_id) { 1933 int process_unique_id,
1742 ProcessBlockedRequestsForRoute(child_id, route_id, false); 1934 int route_id) {
1935 ProcessBlockedRequestsForRoute(process_unique_id, route_id, false);
1743 } 1936 }
1744 1937
1745 void ResourceDispatcherHost::CancelBlockedRequestsForRoute(int child_id, 1938 void ResourceDispatcherHost::CancelBlockedRequestsForRoute(
1746 int route_id) { 1939 int process_unique_id,
1747 ProcessBlockedRequestsForRoute(child_id, route_id, true); 1940 int route_id) {
1941 ProcessBlockedRequestsForRoute(process_unique_id, route_id, true);
1748 } 1942 }
1749 1943
1750 void ResourceDispatcherHost::ProcessBlockedRequestsForRoute( 1944 void ResourceDispatcherHost::ProcessBlockedRequestsForRoute(
1751 int child_id, 1945 int process_unique_id,
1752 int route_id, 1946 int route_id,
1753 bool cancel_requests) { 1947 bool cancel_requests) {
1754 BlockedRequestMap::iterator iter = blocked_requests_map_.find( 1948 BlockedRequestMap::iterator iter = blocked_requests_map_.find(
1755 std::pair<int, int>(child_id, route_id)); 1949 std::pair<int, int>(process_unique_id, route_id));
1756 if (iter == blocked_requests_map_.end()) { 1950 if (iter == blocked_requests_map_.end()) {
1757 // It's possible to reach here if the renderer crashed while an interstitial 1951 // It's possible to reach here if the renderer crashed while an interstitial
1758 // page was showing. 1952 // page was showing.
1759 return; 1953 return;
1760 } 1954 }
1761 1955
1762 BlockedRequestsList* requests = iter->second; 1956 BlockedRequestsList* requests = iter->second;
1763 1957
1764 // Removing the vector from the map unblocks any subsequent requests. 1958 // Removing the vector from the map unblocks any subsequent requests.
1765 blocked_requests_map_.erase(iter); 1959 blocked_requests_map_.erase(iter);
(...skipping 12 matching lines...) Expand all
1778 BeginRequestInternal(request); 1972 BeginRequestInternal(request);
1779 } 1973 }
1780 1974
1781 delete requests; 1975 delete requests;
1782 } 1976 }
1783 1977
1784 bool ResourceDispatcherHost::IsValidRequest(URLRequest* request) { 1978 bool ResourceDispatcherHost::IsValidRequest(URLRequest* request) {
1785 if (!request) 1979 if (!request)
1786 return false; 1980 return false;
1787 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request); 1981 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
1788 return pending_requests_.find( 1982 GlobalRequestID id(info->child_id(), info->request_id());
1789 GlobalRequestID(info->child_id(), info->request_id())) != 1983 return (pending_requests_.find(id) != pending_requests_.end()) ||
1790 pending_requests_.end(); 1984 (interrupted_requests_.find(id) != interrupted_requests_.end());
1985 }
1986
1987 bool ResourceDispatcherHost::IsInterruptedRequest(URLRequest* request) {
1988 if (!request)
1989 return false;
1990 ResourceDispatcherHostRequestInfo* info = InfoForRequest(request);
1991 GlobalRequestID id(info->child_id(), info->request_id());
1992 return interrupted_requests_.find(id) != interrupted_requests_.end();
1791 } 1993 }
1792 1994
1793 // static 1995 // static
1794 bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( 1996 bool ResourceDispatcherHost::IsResourceDispatcherHostMessage(
1795 const IPC::Message& message) { 1997 const IPC::Message& message) {
1796 switch (message.type()) { 1998 switch (message.type()) {
1797 case ViewHostMsg_RequestResource::ID: 1999 case ViewHostMsg_RequestResource::ID:
1798 case ViewHostMsg_CancelRequest::ID: 2000 case ViewHostMsg_CancelRequest::ID:
1799 case ViewHostMsg_FollowRedirect::ID: 2001 case ViewHostMsg_FollowRedirect::ID:
1800 case ViewHostMsg_ClosePage_ACK::ID: 2002 case ViewHostMsg_ClosePage_ACK::ID:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 return is_prefetch_enabled_; 2083 return is_prefetch_enabled_;
1882 } 2084 }
1883 2085
1884 // static 2086 // static
1885 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { 2087 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) {
1886 is_prefetch_enabled_ = value; 2088 is_prefetch_enabled_ = value;
1887 } 2089 }
1888 2090
1889 // static 2091 // static
1890 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; 2092 bool ResourceDispatcherHost::is_prefetch_enabled_ = false;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698