OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc
e-loading |
6 | 6 |
7 #include "content/child/resource_dispatcher.h" | 7 #include "content/child/resource_dispatcher.h" |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/debug/alias.h" | 12 #include "base/debug/alias.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/memory/shared_memory.h" | 14 #include "base/memory/shared_memory.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
18 #include "content/child/request_extra_data.h" | 18 #include "content/child/request_extra_data.h" |
19 #include "content/child/request_info.h" | 19 #include "content/child/request_info.h" |
20 #include "content/child/site_isolation_policy.h" | 20 #include "content/child/site_isolation_policy.h" |
21 #include "content/child/sync_load_response.h" | 21 #include "content/child/sync_load_response.h" |
22 #include "content/common/inter_process_time_ticks_converter.h" | 22 #include "content/common/inter_process_time_ticks_converter.h" |
23 #include "content/common/resource_messages.h" | 23 #include "content/common/resource_messages.h" |
| 24 #include "content/public/child/request_peer.h" |
24 #include "content/public/child/resource_dispatcher_delegate.h" | 25 #include "content/public/child/resource_dispatcher_delegate.h" |
25 #include "content/public/common/resource_response.h" | 26 #include "content/public/common/resource_response.h" |
26 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" |
27 #include "net/base/net_util.h" | 28 #include "net/base/net_util.h" |
28 #include "net/base/request_priority.h" | 29 #include "net/base/request_priority.h" |
29 #include "net/http/http_response_headers.h" | 30 #include "net/http/http_response_headers.h" |
| 31 #include "webkit/child/resource_loader_bridge.h" |
30 #include "webkit/common/resource_type.h" | 32 #include "webkit/common/resource_type.h" |
31 | 33 |
32 using webkit_glue::ResourceLoaderBridge; | 34 using webkit_glue::ResourceLoaderBridge; |
33 using webkit_glue::ResourceResponseInfo; | 35 using webkit_glue::ResourceResponseInfo; |
34 | 36 |
35 namespace content { | 37 namespace content { |
36 | 38 |
37 namespace { | 39 namespace { |
38 | 40 |
39 // Converts |time| from a remote to local TimeTicks, overwriting the original | 41 // Converts |time| from a remote to local TimeTicks, overwriting the original |
(...skipping 28 matching lines...) Expand all Loading... |
68 // ResourceLoaderBridge implementation ---------------------------------------- | 70 // ResourceLoaderBridge implementation ---------------------------------------- |
69 | 71 |
70 class IPCResourceLoaderBridge : public ResourceLoaderBridge { | 72 class IPCResourceLoaderBridge : public ResourceLoaderBridge { |
71 public: | 73 public: |
72 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, | 74 IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, |
73 const RequestInfo& request_info); | 75 const RequestInfo& request_info); |
74 virtual ~IPCResourceLoaderBridge(); | 76 virtual ~IPCResourceLoaderBridge(); |
75 | 77 |
76 // ResourceLoaderBridge | 78 // ResourceLoaderBridge |
77 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; | 79 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; |
78 virtual bool Start(Peer* peer) OVERRIDE; | 80 virtual bool Start(RequestPeer* peer) OVERRIDE; |
79 virtual void Cancel() OVERRIDE; | 81 virtual void Cancel() OVERRIDE; |
80 virtual void SetDefersLoading(bool value) OVERRIDE; | 82 virtual void SetDefersLoading(bool value) OVERRIDE; |
81 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; | 83 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; |
82 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; | 84 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; |
83 | 85 |
84 private: | 86 private: |
85 ResourceLoaderBridge::Peer* peer_; | 87 RequestPeer* peer_; |
86 | 88 |
87 // The resource dispatcher for this loader. The bridge doesn't own it, but | 89 // The resource dispatcher for this loader. The bridge doesn't own it, but |
88 // it's guaranteed to outlive the bridge. | 90 // it's guaranteed to outlive the bridge. |
89 ResourceDispatcher* dispatcher_; | 91 ResourceDispatcher* dispatcher_; |
90 | 92 |
91 // The request to send, created on initialization for modification and | 93 // The request to send, created on initialization for modification and |
92 // appending data. | 94 // appending data. |
93 ResourceHostMsg_Request request_; | 95 ResourceHostMsg_Request request_; |
94 | 96 |
95 // ID for the request, valid once Start()ed, -1 if not valid yet. | 97 // ID for the request, valid once Start()ed, -1 if not valid yet. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 169 } |
168 } | 170 } |
169 | 171 |
170 void IPCResourceLoaderBridge::SetRequestBody( | 172 void IPCResourceLoaderBridge::SetRequestBody( |
171 ResourceRequestBody* request_body) { | 173 ResourceRequestBody* request_body) { |
172 DCHECK(request_id_ == -1) << "request already started"; | 174 DCHECK(request_id_ == -1) << "request already started"; |
173 request_.request_body = request_body; | 175 request_.request_body = request_body; |
174 } | 176 } |
175 | 177 |
176 // Writes a footer on the message and sends it | 178 // Writes a footer on the message and sends it |
177 bool IPCResourceLoaderBridge::Start(Peer* peer) { | 179 bool IPCResourceLoaderBridge::Start(RequestPeer* peer) { |
178 if (request_id_ != -1) { | 180 if (request_id_ != -1) { |
179 NOTREACHED() << "Starting a request twice"; | 181 NOTREACHED() << "Starting a request twice"; |
180 return false; | 182 return false; |
181 } | 183 } |
182 | 184 |
183 peer_ = peer; | 185 peer_ = peer; |
184 | 186 |
185 // generate the request ID, and append it to the message | 187 // generate the request ID, and append it to the message |
186 request_id_ = dispatcher_->AddPendingRequest(peer_, | 188 request_id_ = dispatcher_->AddPendingRequest(peer_, |
187 request_.resource_type, | 189 request_.resource_type, |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 | 340 |
339 void ResourceDispatcher::OnReceivedResponse( | 341 void ResourceDispatcher::OnReceivedResponse( |
340 int request_id, const ResourceResponseHead& response_head) { | 342 int request_id, const ResourceResponseHead& response_head) { |
341 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedResponse"); | 343 TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedResponse"); |
342 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 344 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
343 if (!request_info) | 345 if (!request_info) |
344 return; | 346 return; |
345 request_info->response_start = ConsumeIOTimestamp(); | 347 request_info->response_start = ConsumeIOTimestamp(); |
346 | 348 |
347 if (delegate_) { | 349 if (delegate_) { |
348 ResourceLoaderBridge::Peer* new_peer = | 350 RequestPeer* new_peer = |
349 delegate_->OnReceivedResponse( | 351 delegate_->OnReceivedResponse( |
350 request_info->peer, response_head.mime_type, request_info->url); | 352 request_info->peer, response_head.mime_type, request_info->url); |
351 if (new_peer) | 353 if (new_peer) |
352 request_info->peer = new_peer; | 354 request_info->peer = new_peer; |
353 } | 355 } |
354 | 356 |
355 ResourceResponseInfo renderer_response_info; | 357 ResourceResponseInfo renderer_response_info; |
356 ToResourceResponseInfo(*request_info, response_head, &renderer_response_info); | 358 ToResourceResponseInfo(*request_info, response_head, &renderer_response_info); |
357 request_info->site_isolation_metadata = | 359 request_info->site_isolation_metadata = |
358 SiteIsolationPolicy::OnReceivedResponse(request_info->frame_origin, | 360 SiteIsolationPolicy::OnReceivedResponse(request_info->frame_origin, |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 const ResourceMsg_RequestCompleteData& request_complete_data) { | 524 const ResourceMsg_RequestCompleteData& request_complete_data) { |
523 TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete"); | 525 TRACE_EVENT0("loader", "ResourceDispatcher::OnRequestComplete"); |
524 | 526 |
525 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 527 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
526 if (!request_info) | 528 if (!request_info) |
527 return; | 529 return; |
528 request_info->completion_time = ConsumeIOTimestamp(); | 530 request_info->completion_time = ConsumeIOTimestamp(); |
529 request_info->buffer.reset(); | 531 request_info->buffer.reset(); |
530 request_info->buffer_size = 0; | 532 request_info->buffer_size = 0; |
531 | 533 |
532 ResourceLoaderBridge::Peer* peer = request_info->peer; | 534 RequestPeer* peer = request_info->peer; |
533 | 535 |
534 if (delegate_) { | 536 if (delegate_) { |
535 ResourceLoaderBridge::Peer* new_peer = | 537 RequestPeer* new_peer = |
536 delegate_->OnRequestComplete( | 538 delegate_->OnRequestComplete( |
537 request_info->peer, request_info->resource_type, | 539 request_info->peer, request_info->resource_type, |
538 request_complete_data.error_code); | 540 request_complete_data.error_code); |
539 if (new_peer) | 541 if (new_peer) |
540 request_info->peer = new_peer; | 542 request_info->peer = new_peer; |
541 } | 543 } |
542 | 544 |
543 base::TimeTicks renderer_completion_time = ToRendererCompletionTime( | 545 base::TimeTicks renderer_completion_time = ToRendererCompletionTime( |
544 *request_info, request_complete_data.completion_time); | 546 *request_info, request_complete_data.completion_time); |
545 // The request ID will be removed from our pending list in the destructor. | 547 // The request ID will be removed from our pending list in the destructor. |
546 // Normally, dispatching this message causes the reference-counted request to | 548 // Normally, dispatching this message causes the reference-counted request to |
547 // die immediately. | 549 // die immediately. |
548 peer->OnCompletedRequest(request_complete_data.error_code, | 550 peer->OnCompletedRequest(request_complete_data.error_code, |
549 request_complete_data.was_ignored_by_handler, | 551 request_complete_data.was_ignored_by_handler, |
550 request_complete_data.exists_in_cache, | 552 request_complete_data.exists_in_cache, |
551 request_complete_data.security_info, | 553 request_complete_data.security_info, |
552 renderer_completion_time, | 554 renderer_completion_time, |
553 request_complete_data.encoded_data_length); | 555 request_complete_data.encoded_data_length); |
554 } | 556 } |
555 | 557 |
556 int ResourceDispatcher::AddPendingRequest( | 558 int ResourceDispatcher::AddPendingRequest(RequestPeer* callback, |
557 ResourceLoaderBridge::Peer* callback, | 559 ResourceType::Type resource_type, |
558 ResourceType::Type resource_type, | 560 int origin_pid, |
559 int origin_pid, | 561 const GURL& frame_origin, |
560 const GURL& frame_origin, | 562 const GURL& request_url) { |
561 const GURL& request_url) { | |
562 // Compute a unique request_id for this renderer process. | 563 // Compute a unique request_id for this renderer process. |
563 int id = MakeRequestID(); | 564 int id = MakeRequestID(); |
564 pending_requests_[id] = PendingRequestInfo( | 565 pending_requests_[id] = PendingRequestInfo( |
565 callback, resource_type, origin_pid, frame_origin, request_url); | 566 callback, resource_type, origin_pid, frame_origin, request_url); |
566 return id; | 567 return id; |
567 } | 568 } |
568 | 569 |
569 bool ResourceDispatcher::RemovePendingRequest(int request_id) { | 570 bool ResourceDispatcher::RemovePendingRequest(int request_id) { |
570 PendingRequestList::iterator it = pending_requests_.find(request_id); | 571 PendingRequestList::iterator it = pending_requests_.find(request_id); |
571 if (it == pending_requests_.end()) | 572 if (it == pending_requests_.end()) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 | 622 |
622 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() | 623 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
623 : peer(NULL), | 624 : peer(NULL), |
624 resource_type(ResourceType::SUB_RESOURCE), | 625 resource_type(ResourceType::SUB_RESOURCE), |
625 is_deferred(false), | 626 is_deferred(false), |
626 blocked_response(false), | 627 blocked_response(false), |
627 buffer_size(0) { | 628 buffer_size(0) { |
628 } | 629 } |
629 | 630 |
630 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( | 631 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
631 webkit_glue::ResourceLoaderBridge::Peer* peer, | 632 RequestPeer* peer, |
632 ResourceType::Type resource_type, | 633 ResourceType::Type resource_type, |
633 int origin_pid, | 634 int origin_pid, |
634 const GURL& frame_origin, | 635 const GURL& frame_origin, |
635 const GURL& request_url) | 636 const GURL& request_url) |
636 : peer(peer), | 637 : peer(peer), |
637 resource_type(resource_type), | 638 resource_type(resource_type), |
638 origin_pid(origin_pid), | 639 origin_pid(origin_pid), |
639 is_deferred(false), | 640 is_deferred(false), |
640 url(request_url), | 641 url(request_url), |
641 frame_origin(frame_origin), | 642 frame_origin(frame_origin), |
642 response_url(request_url), | 643 response_url(request_url), |
643 request_start(base::TimeTicks::Now()), | 644 request_start(base::TimeTicks::Now()), |
644 blocked_response(false) { | 645 blocked_response(false) {} |
645 } | |
646 | 646 |
647 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} | 647 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} |
648 | 648 |
649 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { | 649 void ResourceDispatcher::DispatchMessage(const IPC::Message& message) { |
650 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) | 650 IPC_BEGIN_MESSAGE_MAP(ResourceDispatcher, message) |
651 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) | 651 IPC_MESSAGE_HANDLER(ResourceMsg_UploadProgress, OnUploadProgress) |
652 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) | 652 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedResponse, OnReceivedResponse) |
653 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, | 653 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedCachedMetadata, |
654 OnReceivedCachedMetadata) | 654 OnReceivedCachedMetadata) |
655 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect) | 655 IPC_MESSAGE_HANDLER(ResourceMsg_ReceivedRedirect, OnReceivedRedirect) |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { | 802 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { |
803 while (!queue->empty()) { | 803 while (!queue->empty()) { |
804 IPC::Message* message = queue->front(); | 804 IPC::Message* message = queue->front(); |
805 ReleaseResourcesInDataMessage(*message); | 805 ReleaseResourcesInDataMessage(*message); |
806 queue->pop_front(); | 806 queue->pop_front(); |
807 delete message; | 807 delete message; |
808 } | 808 } |
809 } | 809 } |
810 | 810 |
811 } // namespace content | 811 } // namespace content |
OLD | NEW |