summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorsimonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-15 11:12:46 +0000
committersimonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-15 11:12:46 +0000
commita17df45d963ff3291fd59c80c328300c0c19e593 (patch)
treeaaa2725a0ac93f528848052aae32f7842f2f8610 /content
parented301980215de6e2e9f771c67a2611fc5df5b55c (diff)
downloadchromium_src-a17df45d963ff3291fd59c80c328300c0c19e593.zip
chromium_src-a17df45d963ff3291fd59c80c328300c0c19e593.tar.gz
chromium_src-a17df45d963ff3291fd59c80c328300c0c19e593.tar.bz2
Create a ResourceMessageDelegate interface to allow ResourceLoaders to directly
receive IPC messages. BUG=None Review URL: https://chromiumcodereview.appspot.com/12212059 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182668 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/loader/async_resource_handler.cc24
-rw-r--r--content/browser/loader/async_resource_handler.h16
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.cc79
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.h18
-rw-r--r--content/browser/loader/resource_message_delegate.cc24
-rw-r--r--content/browser/loader/resource_message_delegate.h42
-rw-r--r--content/browser/loader/resource_request_info_impl.cc12
-rw-r--r--content/browser/loader/resource_request_info_impl.h14
-rw-r--r--content/common/resource_messages.h2
-rw-r--r--content/content_browser.gypi2
10 files changed, 166 insertions, 67 deletions
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc
index 5fa77c0..da6fa8e 100644
--- a/content/browser/loader/async_resource_handler.cc
+++ b/content/browser/loader/async_resource_handler.cc
@@ -83,7 +83,8 @@ AsyncResourceHandler::AsyncResourceHandler(
int routing_id,
net::URLRequest* request,
ResourceDispatcherHostImpl* rdh)
- : filter_(filter),
+ : ResourceMessageDelegate(request),
+ filter_(filter),
routing_id_(routing_id),
request_(request),
rdh_(rdh),
@@ -92,20 +93,25 @@ AsyncResourceHandler::AsyncResourceHandler(
did_defer_(false),
sent_received_response_msg_(false),
sent_first_data_msg_(false) {
- // Set a back-pointer from ResourceRequestInfoImpl to |this|, so that the
- // ResourceDispatcherHostImpl can send us IPC messages.
- // TODO(darin): Implement an IPC message filter instead?
- ResourceRequestInfoImpl::ForRequest(request_)->set_async_handler(this);
-
InitializeResourceBufferConstants();
}
AsyncResourceHandler::~AsyncResourceHandler() {
- // Cleanup back-pointer stored on the request info.
- ResourceRequestInfoImpl::ForRequest(request_)->set_async_handler(NULL);
+}
+
+bool AsyncResourceHandler::OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(AsyncResourceHandler, message, *message_was_ok)
+ IPC_MESSAGE_HANDLER(ResourceHostMsg_FollowRedirect, OnFollowRedirect)
+ IPC_MESSAGE_HANDLER(ResourceHostMsg_DataReceived_ACK, OnDataReceivedACK)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+ return handled;
}
void AsyncResourceHandler::OnFollowRedirect(
+ int request_id,
bool has_new_first_party_for_cookies,
const GURL& new_first_party_for_cookies) {
if (!request_->status().is_success()) {
@@ -119,7 +125,7 @@ void AsyncResourceHandler::OnFollowRedirect(
ResumeIfDeferred();
}
-void AsyncResourceHandler::OnDataReceivedACK() {
+void AsyncResourceHandler::OnDataReceivedACK(int request_id) {
--pending_data_count_;
buffer_->RecycleLeastRecentlyAllocated();
diff --git a/content/browser/loader/async_resource_handler.h b/content/browser/loader/async_resource_handler.h
index fb4ffce..3ea9583 100644
--- a/content/browser/loader/async_resource_handler.h
+++ b/content/browser/loader/async_resource_handler.h
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted.h"
#include "content/browser/loader/resource_handler.h"
+#include "content/browser/loader/resource_message_delegate.h"
#include "googleurl/src/gurl.h"
namespace net {
@@ -23,7 +24,8 @@ class SharedIOBuffer;
// Used to complete an asynchronous resource request in response to resource
// load events from the resource dispatcher host.
-class AsyncResourceHandler : public ResourceHandler {
+class AsyncResourceHandler : public ResourceHandler,
+ public ResourceMessageDelegate {
public:
AsyncResourceHandler(ResourceMessageFilter* filter,
int routing_id,
@@ -31,10 +33,8 @@ class AsyncResourceHandler : public ResourceHandler {
ResourceDispatcherHostImpl* rdh);
virtual ~AsyncResourceHandler();
- // IPC message handlers:
- void OnFollowRedirect(bool has_new_first_party_for_cookies,
- const GURL& new_first_party_for_cookies);
- void OnDataReceivedACK();
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) OVERRIDE;
// ResourceHandler implementation:
virtual bool OnUploadProgress(int request_id,
@@ -64,6 +64,12 @@ class AsyncResourceHandler : public ResourceHandler {
int bytes_downloaded) OVERRIDE;
private:
+ // IPC message handlers:
+ void OnFollowRedirect(int request_id,
+ bool has_new_first_party_for_cookies,
+ const GURL& new_first_party_for_cookies);
+ void OnDataReceivedACK(int request_id);
+
bool EnsureResourceBufferIsInitialized();
void ResumeIfDeferred();
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index ab37db2..37891cb 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -59,6 +59,8 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "content/public/common/url_constants.h"
+#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_message_start.h"
#include "net/base/auth.h"
#include "net/base/cert_status_flags.h"
#include "net/base/load_flags.h"
@@ -788,17 +790,31 @@ bool ResourceDispatcherHostImpl::OnMessageReceived(
IPC_MESSAGE_HANDLER_DELAY_REPLY(ResourceHostMsg_SyncLoad, OnSyncLoad)
IPC_MESSAGE_HANDLER(ResourceHostMsg_ReleaseDownloadedFile,
OnReleaseDownloadedFile)
- IPC_MESSAGE_HANDLER(ResourceHostMsg_DataReceived_ACK, OnDataReceivedACK)
IPC_MESSAGE_HANDLER(ResourceHostMsg_DataDownloaded_ACK, OnDataDownloadedACK)
IPC_MESSAGE_HANDLER(ResourceHostMsg_UploadProgress_ACK, OnUploadProgressACK)
IPC_MESSAGE_HANDLER(ResourceHostMsg_CancelRequest, OnCancelRequest)
- IPC_MESSAGE_HANDLER(ResourceHostMsg_FollowRedirect, OnFollowRedirect)
IPC_MESSAGE_HANDLER(ViewHostMsg_SwapOut_ACK, OnSwapOutACK)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache,
OnDidLoadResourceFromMemoryCache)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
+ if (!handled && IPC_MESSAGE_ID_CLASS(message.type()) == ResourceMsgStart) {
+ PickleIterator iter(message);
+ int request_id = -1;
+ bool ok = iter.ReadInt(&request_id);
+ DCHECK(ok);
+ GlobalRequestID id(filter_->child_id(), request_id);
+ DelegateMap::iterator it = delegate_map_.find(id);
+ if (it != delegate_map_.end()) {
+ ObserverList<ResourceMessageDelegate>::Iterator del_it(*it->second);
+ ResourceMessageDelegate* delegate;
+ while (!handled && (delegate = del_it.GetNext()) != NULL) {
+ handled = delegate->OnMessageReceived(message, message_was_ok);
+ }
+ }
+ }
+
if (message.type() == ViewHostMsg_DidLoadResourceFromMemoryCache::ID) {
// We just needed to peek at this message. We still want it to reach its
// normal destination.
@@ -890,8 +906,9 @@ void ResourceDispatcherHostImpl::BeginRequest(
return;
}
+ bool is_sync_load = sync_result != NULL;
int load_flags =
- BuildLoadFlagsForRequest(request_data, child_id, sync_result != NULL);
+ BuildLoadFlagsForRequest(request_data, child_id, is_sync_load);
// Construct the request.
scoped_ptr<net::URLRequest> new_request;
@@ -955,7 +972,8 @@ void ResourceDispatcherHostImpl::BeginRequest(
allow_download,
request_data.has_user_gesture,
request_data.referrer_policy,
- resource_context);
+ resource_context,
+ !is_sync_load);
extra_info->AssociateWithRequest(request); // Request takes ownership.
if (request->url().SchemeIs(chrome::kBlobScheme)) {
@@ -1049,16 +1067,6 @@ void ResourceDispatcherHostImpl::OnReleaseDownloadedFile(int request_id) {
UnregisterDownloadedTempFile(filter_->child_id(), request_id);
}
-void ResourceDispatcherHostImpl::OnDataReceivedACK(int request_id) {
- ResourceLoader* loader = GetLoader(filter_->child_id(), request_id);
- if (!loader)
- return;
-
- ResourceRequestInfoImpl* info = loader->GetRequestInfo();
- if (info->async_handler())
- info->async_handler()->OnDataReceivedACK();
-}
-
void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) {
// TODO(michaeln): maybe throttle DataDownloaded messages
}
@@ -1110,24 +1118,6 @@ void ResourceDispatcherHostImpl::OnCancelRequest(int request_id) {
CancelRequest(filter_->child_id(), request_id, true);
}
-void ResourceDispatcherHostImpl::OnFollowRedirect(
- int request_id,
- bool has_new_first_party_for_cookies,
- const GURL& new_first_party_for_cookies) {
- ResourceLoader* loader = GetLoader(filter_->child_id(), request_id);
- if (!loader) {
- DVLOG(1) << "OnFollowRedirect for invalid request";
- return;
- }
-
- ResourceRequestInfoImpl* info = loader->GetRequestInfo();
- if (info->async_handler()) {
- info->async_handler()->OnFollowRedirect(
- has_new_first_party_for_cookies,
- new_first_party_for_cookies);
- }
-}
-
ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
int child_id,
int route_id,
@@ -1149,7 +1139,8 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
download, // allow_download
false, // has_user_gesture
WebKit::WebReferrerPolicyDefault,
- context);
+ context,
+ true); // is_async
}
@@ -1707,4 +1698,26 @@ ResourceLoader* ResourceDispatcherHostImpl::GetLoader(int child_id,
return GetLoader(GlobalRequestID(child_id, request_id));
}
+void ResourceDispatcherHostImpl::RegisterResourceMessageDelegate(
+ const GlobalRequestID& id, ResourceMessageDelegate* delegate) {
+ DelegateMap::iterator it = delegate_map_.find(id);
+ if (it == delegate_map_.end()) {
+ it = delegate_map_.insert(
+ std::make_pair(id, new ObserverList<ResourceMessageDelegate>)).first;
+ }
+ it->second->AddObserver(delegate);
+}
+
+void ResourceDispatcherHostImpl::UnregisterResourceMessageDelegate(
+ const GlobalRequestID& id, ResourceMessageDelegate* delegate) {
+ DCHECK(ContainsKey(delegate_map_, id));
+ DelegateMap::iterator it = delegate_map_.find(id);
+ DCHECK(it->second->HasObserver(delegate));
+ it->second->RemoveObserver(delegate);
+ if (it->second->size() == 0) {
+ delete it->second;
+ delegate_map_.erase(it);
+ }
+}
+
} // namespace content
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index 467745a..edffcf7 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -21,6 +21,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
#include "base/time.h"
#include "base/timer.h"
#include "content/browser/download/download_resource_handler.h"
@@ -51,6 +52,7 @@ class ShareableFileReference;
namespace content {
class ResourceContext;
class ResourceDispatcherHostDelegate;
+class ResourceMessageDelegate;
class ResourceMessageFilter;
class ResourceRequestInfoImpl;
class SaveFileManager;
@@ -226,6 +228,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
class ShutdownTask;
friend class ShutdownTask;
+ friend class ResourceMessageDelegate;
// ResourceLoaderDelegate implementation:
virtual ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
@@ -314,13 +317,9 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const ResourceHostMsg_Request& request_data,
IPC::Message* sync_result, // only valid for sync
int route_id); // only valid for async
- void OnDataReceivedACK(int request_id);
void OnDataDownloadedACK(int request_id);
void OnUploadProgressACK(int request_id);
void OnCancelRequest(int request_id);
- void OnFollowRedirect(int request_id,
- bool has_new_first_party_for_cookies,
- const GURL& new_first_party_for_cookies);
void OnReleaseDownloadedFile(int request_id);
// Creates ResourceRequestInfoImpl for a download or page save.
@@ -352,6 +351,13 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
ResourceLoader* GetLoader(const GlobalRequestID& id) const;
ResourceLoader* GetLoader(int child_id, int request_id) const;
+ // Registers |delegate| to receive resource IPC messages targeted to the
+ // specified |id|.
+ void RegisterResourceMessageDelegate(const GlobalRequestID& id,
+ ResourceMessageDelegate* delegate);
+ void UnregisterResourceMessageDelegate(const GlobalRequestID& id,
+ ResourceMessageDelegate* delegate);
+
LoaderMap pending_loaders_;
// Collection of temp files downloaded for child processes via
@@ -419,6 +425,10 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// shutdown.
std::set<const ResourceContext*> active_resource_contexts_;
+ typedef std::map<GlobalRequestID,
+ ObserverList<ResourceMessageDelegate>*> DelegateMap;
+ DelegateMap delegate_map_;
+
DISALLOW_COPY_AND_ASSIGN(ResourceDispatcherHostImpl);
};
diff --git a/content/browser/loader/resource_message_delegate.cc b/content/browser/loader/resource_message_delegate.cc
new file mode 100644
index 0000000..01d3595
--- /dev/null
+++ b/content/browser/loader/resource_message_delegate.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/resource_message_delegate.h"
+
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/loader/resource_request_info_impl.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+
+ResourceMessageDelegate::ResourceMessageDelegate(const net::URLRequest* request)
+ : id_(ResourceRequestInfoImpl::ForRequest(request)->GetGlobalRequestID()) {
+ ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
+ rdh->RegisterResourceMessageDelegate(id_, this);
+}
+
+ResourceMessageDelegate::~ResourceMessageDelegate() {
+ ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
+ rdh->UnregisterResourceMessageDelegate(id_, this);
+}
+
+} // namespace content
diff --git a/content/browser/loader/resource_message_delegate.h b/content/browser/loader/resource_message_delegate.h
new file mode 100644
index 0000000..d5716e3
--- /dev/null
+++ b/content/browser/loader/resource_message_delegate.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_RESOURCE_MESSAGE_DELEGATE_
+#define CONTENT_BROWSER_LOADER_RESOURCE_MESSAGE_DELEGATE_
+
+#include "base/basictypes.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/global_request_id.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace net {
+class URLRequest;
+}
+
+namespace content {
+
+// A ResourceMessageDelegate receives IPC ResourceMsg_* messages for a specified
+// URLRequest. The delegate should implement its own IPC handler. It will
+// receive the message _after_ the ResourceDispatcherHost has handled it.
+class CONTENT_EXPORT ResourceMessageDelegate {
+ public:
+ ResourceMessageDelegate(const net::URLRequest* request);
+ virtual ~ResourceMessageDelegate();
+
+ // Called when the ResourceDispatcherHostImpl receives a message specifically
+ // for this delegate.
+ virtual bool OnMessageReceived(const IPC::Message& message,
+ bool* message_was_ok) = 0;
+
+ private:
+ GlobalRequestID id_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ResourceMessageDelegate);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_RESOURCE_MESSAGE_DELEGATE_
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc
index 3c5fc49..9920545 100644
--- a/content/browser/loader/resource_request_info_impl.cc
+++ b/content/browser/loader/resource_request_info_impl.cc
@@ -45,7 +45,8 @@ void ResourceRequestInfo::AllocateForTesting(
true, // allow_download
false, // has_user_gesture
WebKit::WebReferrerPolicyDefault, // referrer_policy
- context); // context
+ context, // context
+ false); // is_async
info->AssociateWithRequest(request);
}
@@ -94,9 +95,9 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
bool allow_download,
bool has_user_gesture,
WebKit::WebReferrerPolicy referrer_policy,
- ResourceContext* context)
+ ResourceContext* context,
+ bool is_async)
: cross_site_handler_(NULL),
- async_handler_(NULL),
process_type_(process_type),
child_id_(child_id),
route_id_(route_id),
@@ -114,7 +115,8 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
transition_type_(transition_type),
memory_cost_(0),
referrer_policy_(referrer_policy),
- context_(context) {
+ context_(context),
+ is_async_(is_async) {
}
ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
@@ -198,7 +200,7 @@ bool ResourceRequestInfoImpl::GetAssociatedRenderView(
}
bool ResourceRequestInfoImpl::IsAsync() const {
- return async_handler_ != NULL;
+ return is_async_;
}
void ResourceRequestInfoImpl::AssociateWithRequest(net::URLRequest* request) {
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h
index b8e505f..30532bd 100644
--- a/content/browser/loader/resource_request_info_impl.h
+++ b/content/browser/loader/resource_request_info_impl.h
@@ -22,7 +22,6 @@ class BlobData;
}
namespace content {
-class AsyncResourceHandler;
class CrossSiteResourceHandler;
class ResourceContext;
struct GlobalRequestID;
@@ -56,7 +55,8 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
bool allow_download,
bool has_user_gesture,
WebKit::WebReferrerPolicy referrer_policy,
- ResourceContext* context);
+ ResourceContext* context,
+ bool is_async);
virtual ~ResourceRequestInfoImpl();
// ResourceRequestInfo implementation:
@@ -91,14 +91,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
cross_site_handler_ = h;
}
- // AsyncResourceHandler for this request. May be null.
- AsyncResourceHandler* async_handler() {
- return async_handler_;
- }
- void set_async_handler(AsyncResourceHandler* h) {
- async_handler_ = h;
- }
-
// Identifies the type of process (renderer, plugin, etc.) making the request.
ProcessType process_type() const {
return process_type_;
@@ -130,7 +122,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
private:
// Non-owning, may be NULL.
CrossSiteResourceHandler* cross_site_handler_;
- AsyncResourceHandler* async_handler_;
ProcessType process_type_;
int child_id_;
@@ -151,6 +142,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
scoped_refptr<webkit_blob::BlobData> requested_blob_data_;
WebKit::WebReferrerPolicy referrer_policy_;
ResourceContext* context_;
+ bool is_async_;
DISALLOW_COPY_AND_ASSIGN(ResourceRequestInfoImpl);
};
diff --git a/content/common/resource_messages.h b/content/common/resource_messages.h
index ed53ec7..e065419 100644
--- a/content/common/resource_messages.h
+++ b/content/common/resource_messages.h
@@ -3,6 +3,8 @@
// found in the LICENSE file.
// IPC messages for resource loading.
+//
+// NOTE: All messages must send an |int request_id| as their first parameter.
// Multiply-included message file, hence no include guard.
#include "base/process.h"
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 2893191..636b061 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -525,6 +525,8 @@
'browser/loader/resource_loader.cc',
'browser/loader/resource_loader_delegate.h',
'browser/loader/resource_loader.h',
+ 'browser/loader/resource_message_delegate.cc',
+ 'browser/loader/resource_message_delegate.h',
'browser/loader/resource_message_filter.cc',
'browser/loader/resource_message_filter.h',
'browser/loader/resource_request_info_impl.cc',