OLD | NEW |
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 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 #include "net/base/net_errors.h" | 64 #include "net/base/net_errors.h" |
65 #include "net/base/request_priority.h" | 65 #include "net/base/request_priority.h" |
66 #include "net/base/ssl_cert_request_info.h" | 66 #include "net/base/ssl_cert_request_info.h" |
67 #include "net/base/upload_data.h" | 67 #include "net/base/upload_data.h" |
68 #include "net/http/http_response_headers.h" | 68 #include "net/http/http_response_headers.h" |
69 #include "net/url_request/url_request.h" | 69 #include "net/url_request/url_request.h" |
70 #include "net/url_request/url_request_context.h" | 70 #include "net/url_request/url_request_context.h" |
71 #include "webkit/appcache/appcache_interceptor.h" | 71 #include "webkit/appcache/appcache_interceptor.h" |
72 #include "webkit/appcache/appcache_interfaces.h" | 72 #include "webkit/appcache/appcache_interfaces.h" |
73 #include "webkit/blob/blob_storage_controller.h" | 73 #include "webkit/blob/blob_storage_controller.h" |
74 #include "webkit/blob/deletable_file_reference.h" | |
75 | 74 |
76 // TODO(oshima): Enable this for other platforms. | 75 // TODO(oshima): Enable this for other platforms. |
77 #if defined(OS_CHROMEOS) | 76 #if defined(OS_CHROMEOS) |
78 #include "chrome/browser/renderer_host/offline_resource_handler.h" | 77 #include "chrome/browser/renderer_host/offline_resource_handler.h" |
79 #endif | 78 #endif |
80 | 79 |
81 // Uncomment to enable logging of request traffic. | 80 // Uncomment to enable logging of request traffic. |
82 // #define LOG_RESOURCE_DISPATCHER_REQUESTS | 81 // #define LOG_RESOURCE_DISPATCHER_REQUESTS |
83 | 82 |
84 #ifdef LOG_RESOURCE_DISPATCHER_REQUESTS | 83 #ifdef LOG_RESOURCE_DISPATCHER_REQUESTS |
85 # define RESOURCE_LOG(stuff) LOG(INFO) << stuff | 84 # define RESOURCE_LOG(stuff) LOG(INFO) << stuff |
86 #else | 85 #else |
87 # define RESOURCE_LOG(stuff) | 86 # define RESOURCE_LOG(stuff) |
88 #endif | 87 #endif |
89 | 88 |
90 using base::Time; | 89 using base::Time; |
91 using base::TimeDelta; | 90 using base::TimeDelta; |
92 using base::TimeTicks; | 91 using base::TimeTicks; |
93 using webkit_blob::DeletableFileReference; | |
94 | 92 |
95 // ---------------------------------------------------------------------------- | 93 // ---------------------------------------------------------------------------- |
96 | 94 |
97 // A ShutdownTask proxies a shutdown task from the UI thread to the IO thread. | 95 // A ShutdownTask proxies a shutdown task from the UI thread to the IO thread. |
98 // It should be constructed on the UI thread and run in the IO thread. | 96 // It should be constructed on the UI thread and run in the IO thread. |
99 class ResourceDispatcherHost::ShutdownTask : public Task { | 97 class ResourceDispatcherHost::ShutdownTask : public Task { |
100 public: | 98 public: |
101 explicit ShutdownTask(ResourceDispatcherHost* resource_dispatcher_host) | 99 explicit ShutdownTask(ResourceDispatcherHost* resource_dispatcher_host) |
102 : rdh_(resource_dispatcher_host) { | 100 : rdh_(resource_dispatcher_host) { |
103 } | 101 } |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 return socket_stream_dispatcher_host_->OnMessageReceived( | 314 return socket_stream_dispatcher_host_->OnMessageReceived( |
317 message, receiver, message_was_ok); | 315 message, receiver, message_was_ok); |
318 } | 316 } |
319 | 317 |
320 *message_was_ok = true; | 318 *message_was_ok = true; |
321 receiver_ = receiver; | 319 receiver_ = receiver; |
322 | 320 |
323 IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHost, message, *message_was_ok) | 321 IPC_BEGIN_MESSAGE_MAP_EX(ResourceDispatcherHost, message, *message_was_ok) |
324 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) | 322 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestResource, OnRequestResource) |
325 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) | 323 IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SyncLoad, OnSyncLoad) |
326 IPC_MESSAGE_HANDLER(ViewHostMsg_ResourceLoaderDeleted, | |
327 OnResourceLoaderDeleted) | |
328 IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) | 324 IPC_MESSAGE_HANDLER(ViewHostMsg_DataReceived_ACK, OnDataReceivedACK) |
329 IPC_MESSAGE_HANDLER(ViewHostMsg_DataDownloaded_ACK, OnDataDownloadedACK) | |
330 IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) | 325 IPC_MESSAGE_HANDLER(ViewHostMsg_UploadProgress_ACK, OnUploadProgressACK) |
331 IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) | 326 IPC_MESSAGE_HANDLER(ViewHostMsg_CancelRequest, OnCancelRequest) |
332 IPC_MESSAGE_HANDLER(ViewHostMsg_FollowRedirect, OnFollowRedirect) | 327 IPC_MESSAGE_HANDLER(ViewHostMsg_FollowRedirect, OnFollowRedirect) |
333 IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK) | 328 IPC_MESSAGE_HANDLER(ViewHostMsg_ClosePage_ACK, OnClosePageACK) |
334 IPC_END_MESSAGE_MAP_EX() | 329 IPC_END_MESSAGE_MAP_EX() |
335 | 330 |
336 receiver_ = NULL; | 331 receiver_ = NULL; |
337 | 332 |
338 return true; | 333 return true; |
339 } | 334 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 if (!context) { | 368 if (!context) { |
374 URLRequestContextGetter* context_getter = | 369 URLRequestContextGetter* context_getter = |
375 Profile::GetDefaultRequestContext(); | 370 Profile::GetDefaultRequestContext(); |
376 if (context_getter) { | 371 if (context_getter) { |
377 context = static_cast<ChromeURLRequestContext*>( | 372 context = static_cast<ChromeURLRequestContext*>( |
378 context_getter->GetURLRequestContext()); | 373 context_getter->GetURLRequestContext()); |
379 } | 374 } |
380 } | 375 } |
381 | 376 |
382 // Might need to resolve the blob references in the upload data. | 377 // Might need to resolve the blob references in the upload data. |
383 if (request_data.upload_data && context) { | 378 if (request_data.upload_data) { |
384 context->blob_storage_context()->controller()-> | 379 context->blob_storage_context()->controller()-> |
385 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); | 380 ResolveBlobReferencesInUploadData(request_data.upload_data.get()); |
386 } | 381 } |
387 | 382 |
388 if (is_shutdown_ || | 383 if (is_shutdown_ || |
389 !ShouldServiceRequest(process_type, child_id, request_data)) { | 384 !ShouldServiceRequest(process_type, child_id, request_data)) { |
390 URLRequestStatus status(URLRequestStatus::FAILED, net::ERR_ABORTED); | 385 URLRequestStatus status(URLRequestStatus::FAILED, net::ERR_ABORTED); |
391 if (sync_result) { | 386 if (sync_result) { |
392 SyncLoadResult result; | 387 SyncLoadResult result; |
393 result.status = status; | 388 result.status = status; |
(...skipping 27 matching lines...) Expand all Loading... |
421 this); | 416 this); |
422 } else { | 417 } else { |
423 handler = new AsyncResourceHandler(receiver_, | 418 handler = new AsyncResourceHandler(receiver_, |
424 child_id, | 419 child_id, |
425 route_id, | 420 route_id, |
426 receiver_->handle(), | 421 receiver_->handle(), |
427 request_data.url, | 422 request_data.url, |
428 this); | 423 this); |
429 } | 424 } |
430 | 425 |
431 // The RedirectToFileResourceHandler depends on being next in the chain. | |
432 if (request_data.download_to_file) | 426 if (request_data.download_to_file) |
433 handler = new RedirectToFileResourceHandler(handler, child_id, this); | 427 handler = new RedirectToFileResourceHandler(handler, child_id, this); |
434 | 428 |
435 if (HandleExternalProtocol(request_id, child_id, route_id, | 429 if (HandleExternalProtocol(request_id, child_id, route_id, |
436 request_data.url, request_data.resource_type, | 430 request_data.url, request_data.resource_type, |
437 handler)) { | 431 handler)) { |
438 return; | 432 return; |
439 } | 433 } |
440 | 434 |
441 // Construct the request. | 435 // Construct the request. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 false, // is download | 510 false, // is download |
517 ResourceType::IsFrame(request_data.resource_type), // allow_download | 511 ResourceType::IsFrame(request_data.resource_type), // allow_download |
518 request_data.host_renderer_id, | 512 request_data.host_renderer_id, |
519 request_data.host_render_view_id); | 513 request_data.host_render_view_id); |
520 ApplyExtensionLocalizationFilter(request_data.url, request_data.resource_type, | 514 ApplyExtensionLocalizationFilter(request_data.url, request_data.resource_type, |
521 extra_info); | 515 extra_info); |
522 SetRequestInfo(request, extra_info); // Request takes ownership. | 516 SetRequestInfo(request, extra_info); // Request takes ownership. |
523 chrome_browser_net::SetOriginProcessUniqueIDForRequest( | 517 chrome_browser_net::SetOriginProcessUniqueIDForRequest( |
524 request_data.origin_child_id, request); | 518 request_data.origin_child_id, request); |
525 | 519 |
526 if (request->url().SchemeIs(chrome::kBlobScheme) && context) { | |
527 // Hang on to a reference to ensure the blob is not released prior | |
528 // to the job being started. | |
529 webkit_blob::BlobStorageController* controller = | |
530 context->blob_storage_context()->controller(); | |
531 extra_info->set_requested_blob_data( | |
532 controller->GetBlobDataFromUrl(request->url())); | |
533 } | |
534 | |
535 // Have the appcache associate its extra info with the request. | 520 // Have the appcache associate its extra info with the request. |
536 appcache::AppCacheInterceptor::SetExtraRequestInfo( | 521 appcache::AppCacheInterceptor::SetExtraRequestInfo( |
537 request, context ? context->appcache_service() : NULL, child_id, | 522 request, context ? context->appcache_service() : NULL, child_id, |
538 request_data.appcache_host_id, request_data.resource_type); | 523 request_data.appcache_host_id, request_data.resource_type); |
539 | 524 |
540 BeginRequestInternal(request); | 525 BeginRequestInternal(request); |
541 } | 526 } |
542 | 527 |
543 void ResourceDispatcherHost::OnResourceLoaderDeleted(int request_id) { | |
544 DCHECK(pending_requests_.end() == | |
545 pending_requests_.find(GlobalRequestID(receiver_->id(), request_id))); | |
546 UnregisterDownloadedTempFile(receiver_->id(), request_id); | |
547 } | |
548 | |
549 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { | 528 void ResourceDispatcherHost::OnDataReceivedACK(int request_id) { |
550 DataReceivedACK(receiver_->id(), request_id); | 529 DataReceivedACK(receiver_->id(), request_id); |
551 } | 530 } |
552 | 531 |
553 void ResourceDispatcherHost::DataReceivedACK(int child_id, | 532 void ResourceDispatcherHost::DataReceivedACK(int child_id, |
554 int request_id) { | 533 int request_id) { |
555 PendingRequestList::iterator i = pending_requests_.find( | 534 PendingRequestList::iterator i = pending_requests_.find( |
556 GlobalRequestID(child_id, request_id)); | 535 GlobalRequestID(child_id, request_id)); |
557 if (i == pending_requests_.end()) | 536 if (i == pending_requests_.end()) |
558 return; | 537 return; |
559 | 538 |
560 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); | 539 ResourceDispatcherHostRequestInfo* info = InfoForRequest(i->second); |
561 | 540 |
562 // Decrement the number of pending data messages. | 541 // Decrement the number of pending data messages. |
563 info->DecrementPendingDataCount(); | 542 info->DecrementPendingDataCount(); |
564 | 543 |
565 // If the pending data count was higher than the max, resume the request. | 544 // If the pending data count was higher than the max, resume the request. |
566 if (info->pending_data_count() == kMaxPendingDataMessages) { | 545 if (info->pending_data_count() == kMaxPendingDataMessages) { |
567 // Decrement the pending data count one more time because we also | 546 // Decrement the pending data count one more time because we also |
568 // incremented it before pausing the request. | 547 // incremented it before pausing the request. |
569 info->DecrementPendingDataCount(); | 548 info->DecrementPendingDataCount(); |
570 | 549 |
571 // Resume the request. | 550 // Resume the request. |
572 PauseRequest(child_id, request_id, false); | 551 PauseRequest(child_id, request_id, false); |
573 } | 552 } |
574 } | 553 } |
575 | 554 |
576 void ResourceDispatcherHost::OnDataDownloadedACK(int request_id) { | |
577 // TODO(michaeln): maybe throttle DataDownloaded messages | |
578 } | |
579 | |
580 void ResourceDispatcherHost::RegisterDownloadedTempFile( | |
581 int receiver_id, int request_id, DeletableFileReference* reference) { | |
582 // Note: receiver_id is the child_id is the render_process_id... | |
583 registered_temp_files_[receiver_id][request_id] = reference; | |
584 ChildProcessSecurityPolicy::GetInstance()->GrantUploadFile( | |
585 receiver_id, reference->path()); | |
586 } | |
587 | |
588 void ResourceDispatcherHost::UnregisterDownloadedTempFile( | |
589 int receiver_id, int request_id) { | |
590 DeletableFilesMap& map = registered_temp_files_[receiver_id]; | |
591 DeletableFilesMap::iterator found = map.find(request_id); | |
592 if (found == map.end()) | |
593 return; | |
594 map.erase(found); | |
595 // TODO(michaeln): revoke access to this file upon the file's deletion. | |
596 } | |
597 | |
598 | |
599 bool ResourceDispatcherHost::Send(IPC::Message* message) { | 555 bool ResourceDispatcherHost::Send(IPC::Message* message) { |
600 delete message; | 556 delete message; |
601 return false; | 557 return false; |
602 } | 558 } |
603 | 559 |
604 void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { | 560 void ResourceDispatcherHost::OnUploadProgressACK(int request_id) { |
605 int child_id = receiver_->id(); | 561 int child_id = receiver_->id(); |
606 PendingRequestList::iterator i = pending_requests_.find( | 562 PendingRequestList::iterator i = pending_requests_.find( |
607 GlobalRequestID(child_id, request_id)); | 563 GlobalRequestID(child_id, request_id)); |
608 if (i == pending_requests_.end()) | 564 if (i == pending_requests_.end()) |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 return (entry == outstanding_requests_memory_cost_map_.end()) ? | 840 return (entry == outstanding_requests_memory_cost_map_.end()) ? |
885 0 : entry->second; | 841 0 : entry->second; |
886 } | 842 } |
887 | 843 |
888 // The object died, so cancel and detach all requests associated with it except | 844 // The object died, so cancel and detach all requests associated with it except |
889 // for downloads, which belong to the browser process even if initiated via a | 845 // for downloads, which belong to the browser process even if initiated via a |
890 // renderer. | 846 // renderer. |
891 void ResourceDispatcherHost::CancelRequestsForProcess(int child_id) { | 847 void ResourceDispatcherHost::CancelRequestsForProcess(int child_id) { |
892 socket_stream_dispatcher_host_->CancelRequestsForProcess(child_id); | 848 socket_stream_dispatcher_host_->CancelRequestsForProcess(child_id); |
893 CancelRequestsForRoute(child_id, -1 /* cancel all */); | 849 CancelRequestsForRoute(child_id, -1 /* cancel all */); |
894 registered_temp_files_.erase(child_id); | |
895 } | 850 } |
896 | 851 |
897 void ResourceDispatcherHost::CancelRequestsForRoute(int child_id, | 852 void ResourceDispatcherHost::CancelRequestsForRoute(int child_id, |
898 int route_id) { | 853 int route_id) { |
899 // Since pending_requests_ is a map, we first build up a list of all of the | 854 // Since pending_requests_ is a map, we first build up a list of all of the |
900 // matching requests to be cancelled, and then we cancel them. Since there | 855 // matching requests to be cancelled, and then we cancel them. Since there |
901 // may be more than one request to cancel, we cannot simply hold onto the map | 856 // may be more than one request to cancel, we cannot simply hold onto the map |
902 // iterators found in the first loop. | 857 // iterators found in the first loop. |
903 | 858 |
904 // Find the global ID of all matching elements. | 859 // Find the global ID of all matching elements. |
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1836 } | 1791 } |
1837 | 1792 |
1838 // static | 1793 // static |
1839 bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( | 1794 bool ResourceDispatcherHost::IsResourceDispatcherHostMessage( |
1840 const IPC::Message& message) { | 1795 const IPC::Message& message) { |
1841 switch (message.type()) { | 1796 switch (message.type()) { |
1842 case ViewHostMsg_RequestResource::ID: | 1797 case ViewHostMsg_RequestResource::ID: |
1843 case ViewHostMsg_CancelRequest::ID: | 1798 case ViewHostMsg_CancelRequest::ID: |
1844 case ViewHostMsg_FollowRedirect::ID: | 1799 case ViewHostMsg_FollowRedirect::ID: |
1845 case ViewHostMsg_ClosePage_ACK::ID: | 1800 case ViewHostMsg_ClosePage_ACK::ID: |
1846 case ViewHostMsg_ResourceLoaderDeleted::ID: | |
1847 case ViewHostMsg_DataReceived_ACK::ID: | 1801 case ViewHostMsg_DataReceived_ACK::ID: |
1848 case ViewHostMsg_DataDownloaded_ACK::ID: | 1802 case ViewHostMsg_DownloadProgress_ACK::ID: |
1849 case ViewHostMsg_UploadProgress_ACK::ID: | 1803 case ViewHostMsg_UploadProgress_ACK::ID: |
1850 case ViewHostMsg_SyncLoad::ID: | 1804 case ViewHostMsg_SyncLoad::ID: |
1851 return true; | 1805 return true; |
1852 | 1806 |
1853 default: | 1807 default: |
1854 break; | 1808 break; |
1855 } | 1809 } |
1856 | 1810 |
1857 return false; | 1811 return false; |
1858 } | 1812 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1927 return is_prefetch_enabled_; | 1881 return is_prefetch_enabled_; |
1928 } | 1882 } |
1929 | 1883 |
1930 // static | 1884 // static |
1931 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { | 1885 void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) { |
1932 is_prefetch_enabled_ = value; | 1886 is_prefetch_enabled_ = value; |
1933 } | 1887 } |
1934 | 1888 |
1935 // static | 1889 // static |
1936 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; | 1890 bool ResourceDispatcherHost::is_prefetch_enabled_ = false; |
OLD | NEW |