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/site_isolation_policy.h" |
19 #include "content/common/inter_process_time_ticks_converter.h" | 20 #include "content/common/inter_process_time_ticks_converter.h" |
20 #include "content/common/resource_messages.h" | 21 #include "content/common/resource_messages.h" |
21 #include "content/public/child/resource_dispatcher_delegate.h" | 22 #include "content/public/child/resource_dispatcher_delegate.h" |
22 #include "content/public/common/resource_response.h" | 23 #include "content/public/common/resource_response.h" |
23 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
24 #include "net/base/net_util.h" | 25 #include "net/base/net_util.h" |
25 #include "net/base/request_priority.h" | 26 #include "net/base/request_priority.h" |
26 #include "net/http/http_response_headers.h" | 27 #include "net/http/http_response_headers.h" |
27 #include "webkit/common/resource_type.h" | 28 #include "webkit/common/resource_type.h" |
28 | 29 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 74 |
74 // ResourceLoaderBridge | 75 // ResourceLoaderBridge |
75 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; | 76 virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; |
76 virtual bool Start(Peer* peer) OVERRIDE; | 77 virtual bool Start(Peer* peer) OVERRIDE; |
77 virtual void Cancel() OVERRIDE; | 78 virtual void Cancel() OVERRIDE; |
78 virtual void SetDefersLoading(bool value) OVERRIDE; | 79 virtual void SetDefersLoading(bool value) OVERRIDE; |
79 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; | 80 virtual void DidChangePriority(net::RequestPriority new_priority) OVERRIDE; |
80 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; | 81 virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; |
81 | 82 |
82 private: | 83 private: |
83 ResourceLoaderBridge::Peer* peer_; | 84 |
| 85 scoped_refptr<SiteIsolationPolicy> site_isolation_policy_peer_; |
| 86 ResourceLoaderBridge::Peer* original_peer_; |
84 | 87 |
85 // The resource dispatcher for this loader. The bridge doesn't own it, but | 88 // The resource dispatcher for this loader. The bridge doesn't own it, but |
86 // it's guaranteed to outlive the bridge. | 89 // it's guaranteed to outlive the bridge. |
87 ResourceDispatcher* dispatcher_; | 90 ResourceDispatcher* dispatcher_; |
88 | 91 |
89 // The request to send, created on initialization for modification and | 92 // The request to send, created on initialization for modification and |
90 // appending data. | 93 // appending data. |
91 ResourceHostMsg_Request request_; | 94 ResourceHostMsg_Request request_; |
92 | 95 |
93 // ID for the request, valid once Start()ed, -1 if not valid yet. | 96 // ID for the request, valid once Start()ed, -1 if not valid yet. |
94 int request_id_; | 97 int request_id_; |
95 | 98 |
96 // The routing id used when sending IPC messages. | 99 // The routing id used when sending IPC messages. |
97 int routing_id_; | 100 int routing_id_; |
98 | 101 |
| 102 // The security origin of the frame that initiates this request. |
| 103 GURL frame_origin_; |
| 104 |
99 bool is_synchronous_request_; | 105 bool is_synchronous_request_; |
100 }; | 106 }; |
101 | 107 |
102 IPCResourceLoaderBridge::IPCResourceLoaderBridge( | 108 IPCResourceLoaderBridge::IPCResourceLoaderBridge( |
103 ResourceDispatcher* dispatcher, | 109 ResourceDispatcher* dispatcher, |
104 const ResourceLoaderBridge::RequestInfo& request_info) | 110 const ResourceLoaderBridge::RequestInfo& request_info) |
105 : peer_(NULL), | 111 : original_peer_(NULL), |
106 dispatcher_(dispatcher), | 112 dispatcher_(dispatcher), |
107 request_id_(-1), | 113 request_id_(-1), |
108 routing_id_(request_info.routing_id), | 114 routing_id_(request_info.routing_id), |
109 is_synchronous_request_(false) { | 115 is_synchronous_request_(false) { |
110 DCHECK(dispatcher_) << "no resource dispatcher"; | 116 DCHECK(dispatcher_) << "no resource dispatcher"; |
111 request_.method = request_info.method; | 117 request_.method = request_info.method; |
112 request_.url = request_info.url; | 118 request_.url = request_info.url; |
113 request_.first_party_for_cookies = request_info.first_party_for_cookies; | 119 request_.first_party_for_cookies = request_info.first_party_for_cookies; |
114 request_.referrer = request_info.referrer; | 120 request_.referrer = request_info.referrer; |
115 request_.referrer_policy = request_info.referrer_policy; | 121 request_.referrer_policy = request_info.referrer_policy; |
(...skipping 12 matching lines...) Expand all Loading... |
128 request_.is_main_frame = extra_data->is_main_frame(); | 134 request_.is_main_frame = extra_data->is_main_frame(); |
129 request_.frame_id = extra_data->frame_id(); | 135 request_.frame_id = extra_data->frame_id(); |
130 request_.parent_is_main_frame = extra_data->parent_is_main_frame(); | 136 request_.parent_is_main_frame = extra_data->parent_is_main_frame(); |
131 request_.parent_frame_id = extra_data->parent_frame_id(); | 137 request_.parent_frame_id = extra_data->parent_frame_id(); |
132 request_.allow_download = extra_data->allow_download(); | 138 request_.allow_download = extra_data->allow_download(); |
133 request_.transition_type = extra_data->transition_type(); | 139 request_.transition_type = extra_data->transition_type(); |
134 request_.transferred_request_child_id = | 140 request_.transferred_request_child_id = |
135 extra_data->transferred_request_child_id(); | 141 extra_data->transferred_request_child_id(); |
136 request_.transferred_request_request_id = | 142 request_.transferred_request_request_id = |
137 extra_data->transferred_request_request_id(); | 143 extra_data->transferred_request_request_id(); |
| 144 frame_origin_ = extra_data->frame_origin(); |
138 } else { | 145 } else { |
139 request_.is_main_frame = false; | 146 request_.is_main_frame = false; |
140 request_.frame_id = -1; | 147 request_.frame_id = -1; |
141 request_.parent_is_main_frame = false; | 148 request_.parent_is_main_frame = false; |
142 request_.parent_frame_id = -1; | 149 request_.parent_frame_id = -1; |
143 request_.allow_download = true; | 150 request_.allow_download = true; |
144 request_.transition_type = PAGE_TRANSITION_LINK; | 151 request_.transition_type = PAGE_TRANSITION_LINK; |
145 request_.transferred_request_child_id = -1; | 152 request_.transferred_request_child_id = -1; |
146 request_.transferred_request_request_id = -1; | 153 request_.transferred_request_request_id = -1; |
147 } | 154 } |
(...skipping 20 matching lines...) Expand all Loading... |
168 request_.request_body = request_body; | 175 request_.request_body = request_body; |
169 } | 176 } |
170 | 177 |
171 // Writes a footer on the message and sends it | 178 // Writes a footer on the message and sends it |
172 bool IPCResourceLoaderBridge::Start(Peer* peer) { | 179 bool IPCResourceLoaderBridge::Start(Peer* peer) { |
173 if (request_id_ != -1) { | 180 if (request_id_ != -1) { |
174 NOTREACHED() << "Starting a request twice"; | 181 NOTREACHED() << "Starting a request twice"; |
175 return false; | 182 return false; |
176 } | 183 } |
177 | 184 |
178 peer_ = peer; | 185 original_peer_ = peer; |
179 | 186 |
| 187 // frame_origin_ is not available when frame_id_ is -1, and this happens in |
| 188 // RenderFrameImpl::willRequestAfterPreconnect() which is a callback to a |
| 189 // request request to a preconnected site. We can ignore that situation since |
| 190 // it is going to go through the same sequence of callbacks that reaches |
| 191 // IPCResourceLaoderBridge::Start() with a proper frame_origin_ again. When |
| 192 // frame_origin is not available, SiteIsolationPolicy doesn't apply any |
| 193 // security policy to a request when frame_origin_ is not a valid URL. See |
| 194 // SiteIsolationPolicy::IsSameSite(). |
| 195 site_isolation_policy_peer_ = |
| 196 new SiteIsolationPolicy(original_peer_, |
| 197 request_.frame_id == -1 ? false : true, |
| 198 frame_origin_, |
| 199 request_.url, |
| 200 request_id_, |
| 201 request_.resource_type); |
180 // generate the request ID, and append it to the message | 202 // generate the request ID, and append it to the message |
181 request_id_ = dispatcher_->AddPendingRequest( | 203 request_id_ = dispatcher_->AddPendingRequest( |
182 peer_, request_.resource_type, request_.url); | 204 site_isolation_policy_peer_.get(), request_.resource_type, request_.url); |
183 | 205 |
184 return dispatcher_->message_sender()->Send( | 206 return dispatcher_->message_sender()->Send( |
185 new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); | 207 new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); |
186 } | 208 } |
187 | 209 |
188 void IPCResourceLoaderBridge::Cancel() { | 210 void IPCResourceLoaderBridge::Cancel() { |
189 if (request_id_ < 0) { | 211 if (request_id_ < 0) { |
190 NOTREACHED() << "Trying to cancel an unstarted request"; | 212 NOTREACHED() << "Trying to cancel an unstarted request"; |
191 return; | 213 return; |
192 } | 214 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 353 |
332 void ResourceDispatcher::OnReceivedResponse( | 354 void ResourceDispatcher::OnReceivedResponse( |
333 int request_id, const ResourceResponseHead& response_head) { | 355 int request_id, const ResourceResponseHead& response_head) { |
334 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 356 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
335 if (!request_info) | 357 if (!request_info) |
336 return; | 358 return; |
337 request_info->response_start = ConsumeIOTimestamp(); | 359 request_info->response_start = ConsumeIOTimestamp(); |
338 | 360 |
339 if (delegate_) { | 361 if (delegate_) { |
340 ResourceLoaderBridge::Peer* new_peer = | 362 ResourceLoaderBridge::Peer* new_peer = |
341 delegate_->OnReceivedResponse( | 363 delegate_->OnReceivedResponse(request_info->peer->get_wrapped_peer(), |
342 request_info->peer, response_head.mime_type, request_info->url); | 364 response_head.mime_type, |
| 365 request_info->url); |
343 if (new_peer) | 366 if (new_peer) |
344 request_info->peer = new_peer; | 367 request_info->peer->set_wrapped_peer(new_peer); |
345 } | 368 } |
346 | 369 |
347 ResourceResponseInfo renderer_response_info; | 370 ResourceResponseInfo renderer_response_info; |
348 ToResourceResponseInfo(*request_info, response_head, &renderer_response_info); | 371 ToResourceResponseInfo(*request_info, response_head, &renderer_response_info); |
349 request_info->peer->OnReceivedResponse(renderer_response_info); | 372 request_info->peer->OnReceivedResponse(renderer_response_info); |
350 } | 373 } |
351 | 374 |
352 void ResourceDispatcher::OnReceivedCachedMetadata( | 375 void ResourceDispatcher::OnReceivedCachedMetadata( |
353 int request_id, const std::vector<char>& data) { | 376 int request_id, const std::vector<char>& data) { |
354 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 377 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 bool was_ignored_by_handler, | 511 bool was_ignored_by_handler, |
489 const std::string& security_info, | 512 const std::string& security_info, |
490 const base::TimeTicks& browser_completion_time) { | 513 const base::TimeTicks& browser_completion_time) { |
491 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); | 514 PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
492 if (!request_info) | 515 if (!request_info) |
493 return; | 516 return; |
494 request_info->completion_time = ConsumeIOTimestamp(); | 517 request_info->completion_time = ConsumeIOTimestamp(); |
495 request_info->buffer.reset(); | 518 request_info->buffer.reset(); |
496 request_info->buffer_size = 0; | 519 request_info->buffer_size = 0; |
497 | 520 |
498 ResourceLoaderBridge::Peer* peer = request_info->peer; | 521 ResourceLoaderBridge::Peer* peer = request_info->peer->get_wrapped_peer(); |
499 | 522 |
500 if (delegate_) { | 523 if (delegate_) { |
501 ResourceLoaderBridge::Peer* new_peer = | 524 ResourceLoaderBridge::Peer* new_peer = |
502 delegate_->OnRequestComplete( | 525 delegate_->OnRequestComplete(request_info->peer->get_wrapped_peer(), |
503 request_info->peer, request_info->resource_type, error_code); | 526 request_info->resource_type, |
| 527 error_code); |
504 if (new_peer) | 528 if (new_peer) |
505 request_info->peer = new_peer; | 529 request_info->peer->set_wrapped_peer(new_peer); |
506 } | 530 } |
507 | 531 |
508 base::TimeTicks renderer_completion_time = ToRendererCompletionTime( | 532 base::TimeTicks renderer_completion_time = ToRendererCompletionTime( |
509 *request_info, browser_completion_time); | 533 *request_info, browser_completion_time); |
510 // The request ID will be removed from our pending list in the destructor. | 534 // The request ID will be removed from our pending list in the destructor. |
511 // Normally, dispatching this message causes the reference-counted request to | 535 // Normally, dispatching this message causes the reference-counted request to |
512 // die immediately. | 536 // die immediately. |
513 peer->OnCompletedRequest(error_code, was_ignored_by_handler, security_info, | 537 peer->OnCompletedRequest(error_code, was_ignored_by_handler, security_info, |
514 renderer_completion_time); | 538 renderer_completion_time); |
515 } | 539 } |
516 | 540 |
517 int ResourceDispatcher::AddPendingRequest( | 541 int ResourceDispatcher::AddPendingRequest( |
518 ResourceLoaderBridge::Peer* callback, | 542 SiteIsolationPolicy* site_isolation_policy_peer, |
519 ResourceType::Type resource_type, | 543 ResourceType::Type resource_type, |
520 const GURL& request_url) { | 544 const GURL& request_url) { |
521 // Compute a unique request_id for this renderer process. | 545 // Compute a unique request_id for this renderer process. |
522 int id = MakeRequestID(); | 546 int id = MakeRequestID(); |
523 pending_requests_[id] = | 547 pending_requests_[id] = PendingRequestInfo( |
524 PendingRequestInfo(callback, resource_type, request_url); | 548 site_isolation_policy_peer, resource_type, request_url); |
525 return id; | 549 return id; |
526 } | 550 } |
527 | 551 |
528 bool ResourceDispatcher::RemovePendingRequest(int request_id) { | 552 bool ResourceDispatcher::RemovePendingRequest(int request_id) { |
529 PendingRequestList::iterator it = pending_requests_.find(request_id); | 553 PendingRequestList::iterator it = pending_requests_.find(request_id); |
530 if (it == pending_requests_.end()) | 554 if (it == pending_requests_.end()) |
531 return false; | 555 return false; |
532 | 556 |
533 PendingRequestInfo& request_info = it->second; | 557 PendingRequestInfo& request_info = it->second; |
534 ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); | 558 ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 } | 607 } |
584 | 608 |
585 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() | 609 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
586 : peer(NULL), | 610 : peer(NULL), |
587 resource_type(ResourceType::SUB_RESOURCE), | 611 resource_type(ResourceType::SUB_RESOURCE), |
588 is_deferred(false), | 612 is_deferred(false), |
589 buffer_size(0) { | 613 buffer_size(0) { |
590 } | 614 } |
591 | 615 |
592 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( | 616 ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
593 webkit_glue::ResourceLoaderBridge::Peer* peer, | 617 SiteIsolationPolicy* peer, |
594 ResourceType::Type resource_type, | 618 ResourceType::Type resource_type, |
595 const GURL& request_url) | 619 const GURL& request_url) |
596 : peer(peer), | 620 : peer(peer), |
597 resource_type(resource_type), | 621 resource_type(resource_type), |
598 is_deferred(false), | 622 is_deferred(false), |
599 url(request_url), | 623 url(request_url), |
600 request_start(base::TimeTicks::Now()) { | 624 request_start(base::TimeTicks::Now()) { |
601 } | 625 } |
602 | 626 |
603 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} | 627 ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {} |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { | 782 void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { |
759 while (!queue->empty()) { | 783 while (!queue->empty()) { |
760 IPC::Message* message = queue->front(); | 784 IPC::Message* message = queue->front(); |
761 ReleaseResourcesInDataMessage(*message); | 785 ReleaseResourcesInDataMessage(*message); |
762 queue->pop_front(); | 786 queue->pop_front(); |
763 delete message; | 787 delete message; |
764 } | 788 } |
765 } | 789 } |
766 | 790 |
767 } // namespace content | 791 } // namespace content |
OLD | NEW |