Index: content/child/resource_dispatcher.cc |
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc |
index 6034ca9701e2ea0431acb4eef749b3210f5e58b2..b6a877fa65d5f8b9b91658ac2d14d5e01bb74680 100644 |
--- a/content/child/resource_dispatcher.cc |
+++ b/content/child/resource_dispatcher.cc |
@@ -28,6 +28,7 @@ |
#include "net/base/net_util.h" |
#include "net/base/request_priority.h" |
#include "net/http/http_response_headers.h" |
+#include "webkit/child/resource_loader_bridge.h" |
#include "webkit/common/resource_type.h" |
using webkit_glue::ResourceLoaderBridge; |
@@ -46,7 +47,10 @@ |
*time = converter.ToLocalTimeTicks(remote_time).ToTimeTicks(); |
} |
-void CrashOnMapFailure() { |
+ |
+} // namespace |
+ |
+static void CrashOnMapFailure() { |
#if defined(OS_WIN) |
DWORD last_err = GetLastError(); |
base::debug::Alias(&last_err); |
@@ -55,7 +59,7 @@ |
} |
// Each resource request is assigned an ID scoped to this process. |
-int MakeRequestID() { |
+static int MakeRequestID() { |
// NOTE: The resource_dispatcher_host also needs probably unique |
// request_ids, so they count down from -2 (-1 is a special we're |
// screwed value), while the renderer process counts up. |
@@ -63,7 +67,203 @@ |
return next_request_id++; |
} |
-} // namespace |
+// ResourceLoaderBridge implementation ---------------------------------------- |
+ |
+class IPCResourceLoaderBridge : public ResourceLoaderBridge { |
+ public: |
+ IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, |
+ const RequestInfo& request_info); |
+ virtual ~IPCResourceLoaderBridge(); |
+ |
+ // ResourceLoaderBridge |
+ virtual void SetRequestBody(ResourceRequestBody* request_body) OVERRIDE; |
+ virtual bool Start(RequestPeer* peer) OVERRIDE; |
+ virtual void Cancel() OVERRIDE; |
+ virtual void SetDefersLoading(bool value) OVERRIDE; |
+ virtual void DidChangePriority(net::RequestPriority new_priority, |
+ int intra_priority_value) OVERRIDE; |
+ virtual void SyncLoad(SyncLoadResponse* response) OVERRIDE; |
+ |
+ private: |
+ RequestPeer* peer_; |
+ |
+ // The resource dispatcher for this loader. The bridge doesn't own it, but |
+ // it's guaranteed to outlive the bridge. |
+ ResourceDispatcher* dispatcher_; |
+ |
+ // The request to send, created on initialization for modification and |
+ // appending data. |
+ ResourceHostMsg_Request request_; |
+ |
+ // ID for the request, valid once Start()ed, -1 if not valid yet. |
+ int request_id_; |
+ |
+ // 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 RequestInfo& request_info) |
+ : peer_(NULL), |
+ dispatcher_(dispatcher), |
+ request_id_(-1), |
+ routing_id_(request_info.routing_id), |
+ is_synchronous_request_(false) { |
+ DCHECK(dispatcher_) << "no resource dispatcher"; |
+ request_.method = request_info.method; |
+ request_.url = request_info.url; |
+ request_.first_party_for_cookies = request_info.first_party_for_cookies; |
+ request_.referrer = request_info.referrer; |
+ request_.referrer_policy = request_info.referrer_policy; |
+ request_.headers = request_info.headers; |
+ request_.load_flags = request_info.load_flags; |
+ request_.origin_pid = request_info.requestor_pid; |
+ request_.resource_type = request_info.request_type; |
+ request_.priority = request_info.priority; |
+ request_.request_context = request_info.request_context; |
+ request_.appcache_host_id = request_info.appcache_host_id; |
+ request_.download_to_file = request_info.download_to_file; |
+ request_.has_user_gesture = request_info.has_user_gesture; |
+ |
+ const RequestExtraData kEmptyData; |
+ const RequestExtraData* extra_data; |
+ if (request_info.extra_data) |
+ extra_data = static_cast<RequestExtraData*>(request_info.extra_data); |
+ else |
+ extra_data = &kEmptyData; |
+ request_.visiblity_state = extra_data->visibility_state(); |
+ request_.render_frame_id = extra_data->render_frame_id(); |
+ request_.is_main_frame = extra_data->is_main_frame(); |
+ request_.parent_is_main_frame = extra_data->parent_is_main_frame(); |
+ request_.parent_render_frame_id = extra_data->parent_render_frame_id(); |
+ request_.allow_download = extra_data->allow_download(); |
+ request_.transition_type = extra_data->transition_type(); |
+ request_.should_replace_current_entry = |
+ extra_data->should_replace_current_entry(); |
+ request_.transferred_request_child_id = |
+ extra_data->transferred_request_child_id(); |
+ request_.transferred_request_request_id = |
+ extra_data->transferred_request_request_id(); |
+ request_.service_worker_provider_id = |
+ extra_data->service_worker_provider_id(); |
+ frame_origin_ = extra_data->frame_origin(); |
+} |
+ |
+IPCResourceLoaderBridge::~IPCResourceLoaderBridge() { |
+ // we remove our hook for the resource dispatcher only when going away, since |
+ // it doesn't keep track of whether we've force terminated the request |
+ if (request_id_ >= 0) { |
+ // this operation may fail, as the dispatcher will have preemptively |
+ // removed us when the renderer sends the ReceivedAllData message. |
+ dispatcher_->RemovePendingRequest(request_id_); |
+ |
+ if (request_.download_to_file) { |
+ dispatcher_->message_sender()->Send( |
+ new ResourceHostMsg_ReleaseDownloadedFile(request_id_)); |
+ } |
+ } |
+} |
+ |
+void IPCResourceLoaderBridge::SetRequestBody( |
+ ResourceRequestBody* request_body) { |
+ DCHECK(request_id_ == -1) << "request already started"; |
+ request_.request_body = request_body; |
+} |
+ |
+// Writes a footer on the message and sends it |
+bool IPCResourceLoaderBridge::Start(RequestPeer* peer) { |
+ if (request_id_ != -1) { |
+ NOTREACHED() << "Starting a request twice"; |
+ return false; |
+ } |
+ |
+ peer_ = peer; |
+ |
+ // generate the request ID, and append it to the message |
+ request_id_ = dispatcher_->AddPendingRequest(peer_, |
+ request_.resource_type, |
+ request_.origin_pid, |
+ frame_origin_, |
+ request_.url); |
+ |
+ return dispatcher_->message_sender()->Send( |
+ new ResourceHostMsg_RequestResource(routing_id_, request_id_, request_)); |
+} |
+ |
+void IPCResourceLoaderBridge::Cancel() { |
+ if (request_id_ < 0) { |
+ NOTREACHED() << "Trying to cancel an unstarted request"; |
+ return; |
+ } |
+ |
+ if (!is_synchronous_request_) |
+ dispatcher_->CancelPendingRequest(request_id_); |
+ |
+ // We can't remove the request ID from the resource dispatcher because more |
+ // data might be pending. Sending the cancel message may cause more data |
+ // to be flushed, and will then cause a complete message to be sent. |
+} |
+ |
+void IPCResourceLoaderBridge::SetDefersLoading(bool value) { |
+ if (request_id_ < 0) { |
+ NOTREACHED() << "Trying to (un)defer an unstarted request"; |
+ return; |
+ } |
+ |
+ dispatcher_->SetDefersLoading(request_id_, value); |
+} |
+ |
+void IPCResourceLoaderBridge::DidChangePriority( |
+ net::RequestPriority new_priority, int intra_priority_value) { |
+ if (request_id_ < 0) { |
+ NOTREACHED() << "Trying to change priority of an unstarted request"; |
+ return; |
+ } |
+ |
+ dispatcher_->DidChangePriority(routing_id_, request_id_, new_priority, |
+ intra_priority_value); |
+} |
+ |
+void IPCResourceLoaderBridge::SyncLoad(SyncLoadResponse* response) { |
+ if (request_id_ != -1) { |
+ NOTREACHED() << "Starting a request twice"; |
+ response->error_code = net::ERR_FAILED; |
+ return; |
+ } |
+ |
+ request_id_ = MakeRequestID(); |
+ is_synchronous_request_ = true; |
+ |
+ SyncLoadResult result; |
+ IPC::SyncMessage* msg = new ResourceHostMsg_SyncLoad(routing_id_, request_id_, |
+ request_, &result); |
+ // NOTE: This may pump events (see RenderThread::Send). |
+ if (!dispatcher_->message_sender()->Send(msg)) { |
+ response->error_code = net::ERR_FAILED; |
+ return; |
+ } |
+ |
+ response->error_code = result.error_code; |
+ response->url = result.final_url; |
+ response->headers = result.headers; |
+ response->mime_type = result.mime_type; |
+ response->charset = result.charset; |
+ response->request_time = result.request_time; |
+ response->response_time = result.response_time; |
+ response->encoded_data_length = result.encoded_data_length; |
+ response->load_timing = result.load_timing; |
+ response->devtools_info = result.devtools_info; |
+ response->data.swap(result.data); |
+ response->download_file_path = result.download_file_path; |
+} |
+ |
+// ResourceDispatcher --------------------------------------------------------- |
ResourceDispatcher::ResourceDispatcher(IPC::Sender* sender) |
: message_sender_(sender), |
@@ -74,6 +274,8 @@ |
ResourceDispatcher::~ResourceDispatcher() { |
} |
+ |
+// ResourceDispatcher implementation ------------------------------------------ |
bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) { |
if (!IsResourceDispatcherMessage(message)) { |
@@ -135,12 +337,11 @@ |
request_info->peer->OnUploadProgress(position, size); |
// Acknowledge receipt |
- message_sender_->Send(new ResourceHostMsg_UploadProgress_ACK(request_id)); |
+ message_sender()->Send(new ResourceHostMsg_UploadProgress_ACK(request_id)); |
} |
void ResourceDispatcher::OnReceivedResponse( |
- int request_id, |
- const ResourceResponseHead& response_head) { |
+ int request_id, const ResourceResponseHead& response_head) { |
TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedResponse"); |
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
if (!request_info) |
@@ -167,8 +368,7 @@ |
} |
void ResourceDispatcher::OnReceivedCachedMetadata( |
- int request_id, |
- const std::vector<char>& data) { |
+ int request_id, const std::vector<char>& data) { |
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
if (!request_info) |
return; |
@@ -220,7 +420,8 @@ |
CHECK_GE(request_info->buffer_size, data_offset + data_length); |
// Ensure that the SHM buffer remains valid for the duration of this scope. |
- // It is possible for Cancel() to be called before we exit this scope. |
+ // It is possible for CancelPendingRequest() to be called before we exit |
+ // this scope. |
linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer); |
base::TimeTicks time_start = base::TimeTicks::Now(); |
@@ -258,14 +459,14 @@ |
} |
// Acknowledge the reception of this data. |
- message_sender_->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); |
+ message_sender()->Send(new ResourceHostMsg_DataReceived_ACK(request_id)); |
} |
void ResourceDispatcher::OnDownloadedData(int request_id, |
int data_len, |
int encoded_data_length) { |
// Acknowledge the reception of this message. |
- message_sender_->Send( |
+ message_sender()->Send( |
new ResourceHostMsg_DataDownloaded_ACK(request_id)); |
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id); |
@@ -308,7 +509,7 @@ |
FollowPendingRedirect(request_id, *request_info); |
} |
} else { |
- Cancel(request_id); |
+ CancelPendingRequest(request_id); |
} |
} |
@@ -317,7 +518,7 @@ |
PendingRequestInfo& request_info) { |
IPC::Message* msg = request_info.pending_redirect_message.release(); |
if (msg) |
- message_sender_->Send(msg); |
+ message_sender()->Send(msg); |
} |
void ResourceDispatcher::OnRequestComplete( |
@@ -356,6 +557,18 @@ |
request_complete_data.encoded_data_length); |
} |
+int ResourceDispatcher::AddPendingRequest(RequestPeer* callback, |
+ ResourceType::Type resource_type, |
+ int origin_pid, |
+ const GURL& frame_origin, |
+ const GURL& request_url) { |
+ // Compute a unique request_id for this renderer process. |
+ int id = MakeRequestID(); |
+ pending_requests_[id] = PendingRequestInfo( |
+ callback, resource_type, origin_pid, frame_origin, request_url); |
+ return id; |
+} |
+ |
bool ResourceDispatcher::RemovePendingRequest(int request_id) { |
PendingRequestList::iterator it = pending_requests_.find(request_id); |
if (it == pending_requests_.end()) |
@@ -363,18 +576,12 @@ |
PendingRequestInfo& request_info = it->second; |
ReleaseResourcesInMessageQueue(&request_info.deferred_message_queue); |
- |
- if (request_info.download_to_file) { |
- message_sender_->Send( |
- new ResourceHostMsg_ReleaseDownloadedFile(request_id)); |
- } |
- |
pending_requests_.erase(it); |
return true; |
} |
-void ResourceDispatcher::Cancel(int request_id) { |
+void ResourceDispatcher::CancelPendingRequest(int request_id) { |
PendingRequestList::iterator it = pending_requests_.find(request_id); |
if (it == pending_requests_.end()) { |
DVLOG(1) << "unknown request"; |
@@ -383,7 +590,7 @@ |
// |request_id| will be removed from |pending_requests_| when |
// OnRequestComplete returns with ERR_ABORTED. |
- message_sender_->Send(new ResourceHostMsg_CancelRequest(request_id)); |
+ message_sender()->Send(new ResourceHostMsg_CancelRequest(request_id)); |
} |
void ResourceDispatcher::SetDefersLoading(int request_id, bool value) { |
@@ -408,11 +615,11 @@ |
} |
} |
-void ResourceDispatcher::DidChangePriority(int request_id, |
- net::RequestPriority new_priority, |
- int intra_priority_value) { |
+void ResourceDispatcher::DidChangePriority( |
+ int routing_id, int request_id, net::RequestPriority new_priority, |
+ int intra_priority_value) { |
DCHECK(ContainsKey(pending_requests_, request_id)); |
- message_sender_->Send(new ResourceHostMsg_DidChangePriority( |
+ message_sender()->Send(new ResourceHostMsg_DidChangePriority( |
request_id, new_priority, intra_priority_value)); |
} |
@@ -420,7 +627,6 @@ |
: peer(NULL), |
resource_type(ResourceType::SUB_RESOURCE), |
is_deferred(false), |
- download_to_file(false), |
blocked_response(false), |
buffer_size(0) { |
} |
@@ -430,8 +636,7 @@ |
ResourceType::Type resource_type, |
int origin_pid, |
const GURL& frame_origin, |
- const GURL& request_url, |
- bool download_to_file) |
+ const GURL& request_url) |
: peer(peer), |
resource_type(resource_type), |
origin_pid(origin_pid), |
@@ -439,7 +644,6 @@ |
url(request_url), |
frame_origin(frame_origin), |
response_url(request_url), |
- download_to_file(download_to_file), |
request_start(base::TimeTicks::Now()), |
blocked_response(false) {} |
@@ -490,57 +694,9 @@ |
} |
} |
-void ResourceDispatcher::StartSync(const RequestInfo& request_info, |
- ResourceRequestBody* request_body, |
- SyncLoadResponse* response) { |
- scoped_ptr<ResourceHostMsg_Request> request = |
- CreateRequest(request_info, request_body, NULL); |
- |
- SyncLoadResult result; |
- IPC::SyncMessage* msg = new ResourceHostMsg_SyncLoad( |
- request_info.routing_id, MakeRequestID(), *request, &result); |
- |
- // NOTE: This may pump events (see RenderThread::Send). |
- if (!message_sender_->Send(msg)) { |
- response->error_code = net::ERR_FAILED; |
- return; |
- } |
- |
- response->error_code = result.error_code; |
- response->url = result.final_url; |
- response->headers = result.headers; |
- response->mime_type = result.mime_type; |
- response->charset = result.charset; |
- response->request_time = result.request_time; |
- response->response_time = result.response_time; |
- response->encoded_data_length = result.encoded_data_length; |
- response->load_timing = result.load_timing; |
- response->devtools_info = result.devtools_info; |
- response->data.swap(result.data); |
- response->download_file_path = result.download_file_path; |
-} |
- |
-int ResourceDispatcher::StartAsync(const RequestInfo& request_info, |
- ResourceRequestBody* request_body, |
- RequestPeer* peer) { |
- GURL frame_origin; |
- scoped_ptr<ResourceHostMsg_Request> request = |
- CreateRequest(request_info, request_body, &frame_origin); |
- |
- // Compute a unique request_id for this renderer process. |
- int request_id = MakeRequestID(); |
- pending_requests_[request_id] = |
- PendingRequestInfo(peer, |
- request->resource_type, |
- request->origin_pid, |
- frame_origin, |
- request->url, |
- request_info.download_to_file); |
- |
- message_sender_->Send(new ResourceHostMsg_RequestResource( |
- request_info.routing_id, request_id, *request)); |
- |
- return request_id; |
+ResourceLoaderBridge* ResourceDispatcher::CreateBridge( |
+ const RequestInfo& request_info) { |
+ return new IPCResourceLoaderBridge(this, request_info); |
} |
void ResourceDispatcher::ToResourceResponseInfo( |
@@ -655,51 +811,4 @@ |
} |
} |
-scoped_ptr<ResourceHostMsg_Request> ResourceDispatcher::CreateRequest( |
- const RequestInfo& request_info, |
- ResourceRequestBody* request_body, |
- GURL* frame_origin) { |
- scoped_ptr<ResourceHostMsg_Request> request(new ResourceHostMsg_Request); |
- request->method = request_info.method; |
- request->url = request_info.url; |
- request->first_party_for_cookies = request_info.first_party_for_cookies; |
- request->referrer = request_info.referrer; |
- request->referrer_policy = request_info.referrer_policy; |
- request->headers = request_info.headers; |
- request->load_flags = request_info.load_flags; |
- request->origin_pid = request_info.requestor_pid; |
- request->resource_type = request_info.request_type; |
- request->priority = request_info.priority; |
- request->request_context = request_info.request_context; |
- request->appcache_host_id = request_info.appcache_host_id; |
- request->download_to_file = request_info.download_to_file; |
- request->has_user_gesture = request_info.has_user_gesture; |
- |
- const RequestExtraData kEmptyData; |
- const RequestExtraData* extra_data; |
- if (request_info.extra_data) |
- extra_data = static_cast<RequestExtraData*>(request_info.extra_data); |
- else |
- extra_data = &kEmptyData; |
- request->visiblity_state = extra_data->visibility_state(); |
- request->render_frame_id = extra_data->render_frame_id(); |
- request->is_main_frame = extra_data->is_main_frame(); |
- request->parent_is_main_frame = extra_data->parent_is_main_frame(); |
- request->parent_render_frame_id = extra_data->parent_render_frame_id(); |
- request->allow_download = extra_data->allow_download(); |
- request->transition_type = extra_data->transition_type(); |
- request->should_replace_current_entry = |
- extra_data->should_replace_current_entry(); |
- request->transferred_request_child_id = |
- extra_data->transferred_request_child_id(); |
- request->transferred_request_request_id = |
- extra_data->transferred_request_request_id(); |
- request->service_worker_provider_id = |
- extra_data->service_worker_provider_id(); |
- request->request_body = request_body; |
- if (frame_origin) |
- *frame_origin = extra_data->frame_origin(); |
- return request.Pass(); |
-} |
- |
} // namespace content |