Index: content/child/resource_dispatcher.cc |
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc |
index 424902fb0411288794a78d12f8710e7034edd9d5..e4bb16ad1659df8837f5787deddd963c68e4b8c2 100644 |
--- a/content/child/resource_dispatcher.cc |
+++ b/content/child/resource_dispatcher.cc |
@@ -16,6 +16,7 @@ |
#include "base/metrics/histogram.h" |
#include "base/strings/string_util.h" |
#include "content/child/request_extra_data.h" |
+#include "content/child/site_isolation_policy.h" |
#include "content/common/inter_process_time_ticks_converter.h" |
#include "content/common/resource_messages.h" |
#include "content/public/child/resource_dispatcher_delegate.h" |
@@ -80,7 +81,9 @@ class IPCResourceLoaderBridge : public ResourceLoaderBridge { |
virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; |
private: |
- ResourceLoaderBridge::Peer* peer_; |
+ |
+ scoped_refptr<SiteIsolationPolicy> site_isolation_policy_peer_; |
+ ResourceLoaderBridge::Peer* original_peer_; |
// The resource dispatcher for this loader. The bridge doesn't own it, but |
// it's guaranteed to outlive the bridge. |
@@ -96,13 +99,16 @@ class IPCResourceLoaderBridge : public ResourceLoaderBridge { |
// The routing id used when sending IPC messages. |
int routing_id_; |
+ // The security origin of the frame that initiates this request. |
+ GURL frame_origin_; |
+ |
bool is_synchronous_request_; |
}; |
IPCResourceLoaderBridge::IPCResourceLoaderBridge( |
ResourceDispatcher* dispatcher, |
const ResourceLoaderBridge::RequestInfo& request_info) |
- : peer_(NULL), |
+ : original_peer_(NULL), |
dispatcher_(dispatcher), |
request_id_(-1), |
routing_id_(request_info.routing_id), |
@@ -135,6 +141,7 @@ IPCResourceLoaderBridge::IPCResourceLoaderBridge( |
extra_data->transferred_request_child_id(); |
request_.transferred_request_request_id = |
extra_data->transferred_request_request_id(); |
+ frame_origin_ = extra_data->frame_origin(); |
} else { |
request_.is_main_frame = false; |
request_.frame_id = -1; |
@@ -175,11 +182,26 @@ bool IPCResourceLoaderBridge::Start(Peer* peer) { |
return false; |
} |
- peer_ = peer; |
- |
+ original_peer_ = peer; |
+ |
+ // frame_origin_ is not available when frame_id_ is -1, and this happens in |
+ // RenderFrameImpl::willRequestAfterPreconnect() which is a callback to a |
+ // request request to a preconnected site. We can ignore that situation since |
+ // it is going to go through the same sequence of callbacks that reaches |
+ // IPCResourceLaoderBridge::Start() with a proper frame_origin_ again. When |
+ // frame_origin is not available, SiteIsolationPolicy doesn't apply any |
+ // security policy to a request when frame_origin_ is not a valid URL. See |
+ // SiteIsolationPolicy::IsSameSite(). |
+ site_isolation_policy_peer_ = |
+ new SiteIsolationPolicy(original_peer_, |
+ request_.frame_id == -1 ? false : true, |
+ frame_origin_, |
+ request_.url, |
+ request_id_, |
+ request_.resource_type); |
// generate the request ID, and append it to the message |
request_id_ = dispatcher_->AddPendingRequest( |
- peer_, request_.resource_type, request_.url); |
+ site_isolation_policy_peer_.get(), request_.resource_type, request_.url); |
return dispatcher_->message_sender()->Send( |
new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); |
@@ -338,10 +360,11 @@ void ResourceDispatcher::OnReceivedResponse( |
if (delegate_) { |
ResourceLoaderBridge::Peer* new_peer = |
- delegate_->OnReceivedResponse( |
- request_info->peer, response_head.mime_type, request_info->url); |
+ delegate_->OnReceivedResponse(request_info->peer->get_wrapped_peer(), |
+ response_head.mime_type, |
+ request_info->url); |
if (new_peer) |
- request_info->peer = new_peer; |
+ request_info->peer->set_wrapped_peer(new_peer); |
} |
ResourceResponseInfo renderer_response_info; |
@@ -495,14 +518,15 @@ void ResourceDispatcher::OnRequestComplete( |
request_info->buffer.reset(); |
request_info->buffer_size = 0; |
- ResourceLoaderBridge::Peer* peer = request_info->peer; |
+ ResourceLoaderBridge::Peer* peer = request_info->peer->get_wrapped_peer(); |
if (delegate_) { |
ResourceLoaderBridge::Peer* new_peer = |
- delegate_->OnRequestComplete( |
- request_info->peer, request_info->resource_type, error_code); |
+ delegate_->OnRequestComplete(request_info->peer->get_wrapped_peer(), |
+ request_info->resource_type, |
+ error_code); |
if (new_peer) |
- request_info->peer = new_peer; |
+ request_info->peer->set_wrapped_peer(new_peer); |
} |
base::TimeTicks renderer_completion_time = ToRendererCompletionTime( |
@@ -515,13 +539,13 @@ void ResourceDispatcher::OnRequestComplete( |
} |
int ResourceDispatcher::AddPendingRequest( |
- ResourceLoaderBridge::Peer* callback, |
+ SiteIsolationPolicy* site_isolation_policy_peer, |
ResourceType::Type resource_type, |
const GURL& request_url) { |
// Compute a unique request_id for this renderer process. |
int id = MakeRequestID(); |
- pending_requests_[id] = |
- PendingRequestInfo(callback, resource_type, request_url); |
+ pending_requests_[id] = PendingRequestInfo( |
+ site_isolation_policy_peer, resource_type, request_url); |
return id; |
} |
@@ -590,7 +614,7 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo() |
} |
ResourceDispatcher::PendingRequestInfo::PendingRequestInfo( |
- webkit_glue::ResourceLoaderBridge::Peer* peer, |
+ SiteIsolationPolicy* peer, |
ResourceType::Type resource_type, |
const GURL& request_url) |
: peer(peer), |