diff options
author | jam <jam@chromium.org> | 2015-02-19 12:29:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-19 20:30:08 +0000 |
commit | 4a1511ef45627b827c47a34a65aee06028d71d3a (patch) | |
tree | 6275b4ab73944c411a306039dc73342ce5556d5b /content/child | |
parent | ac1a3823f82e90136e7800d6f77a08534f9afbd1 (diff) | |
download | chromium_src-4a1511ef45627b827c47a34a65aee06028d71d3a.zip chromium_src-4a1511ef45627b827c47a34a65aee06028d71d3a.tar.gz chromium_src-4a1511ef45627b827c47a34a65aee06028d71d3a.tar.bz2 |
Remove ResourceLoaderBridge interface.
We don't need it anymore since WebURLLoaderImpl is in content.
This is based on https://codereview.chromium.org/226273005.
BUG=338338
Review URL: https://codereview.chromium.org/938933002
Cr-Commit-Position: refs/heads/master@{#317126}
Diffstat (limited to 'content/child')
-rw-r--r-- | content/child/npapi/plugin_url_fetcher.cc | 30 | ||||
-rw-r--r-- | content/child/npapi/plugin_url_fetcher.h | 4 | ||||
-rw-r--r-- | content/child/resource_dispatcher.cc | 369 | ||||
-rw-r--r-- | content/child/resource_dispatcher.h | 50 | ||||
-rw-r--r-- | content/child/resource_dispatcher_unittest.cc | 167 | ||||
-rw-r--r-- | content/child/resource_loader_bridge.cc | 13 | ||||
-rw-r--r-- | content/child/resource_loader_bridge.h | 92 | ||||
-rw-r--r-- | content/child/web_url_loader_impl.cc | 64 | ||||
-rw-r--r-- | content/child/web_url_loader_impl_unittest.cc | 103 |
9 files changed, 305 insertions, 587 deletions
diff --git a/content/child/npapi/plugin_url_fetcher.cc b/content/child/npapi/plugin_url_fetcher.cc index 15bd602..a99f2e1 100644 --- a/content/child/npapi/plugin_url_fetcher.cc +++ b/content/child/npapi/plugin_url_fetcher.cc @@ -16,7 +16,6 @@ #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/child/resource_dispatcher.h" -#include "content/child/resource_loader_bridge.h" #include "content/child/web_url_loader_impl.h" #include "content/common/resource_request_body.h" #include "content/common/service_worker/service_worker_types.h" @@ -104,7 +103,8 @@ PluginURLFetcher::PluginURLFetcher(PluginStreamUrl* plugin_stream, resource_id_(resource_id), copy_stream_data_(copy_stream_data), data_offset_(0), - pending_failure_notification_(false) { + pending_failure_notification_(false), + request_id_(-1) { RequestInfo request_info; request_info.method = method; request_info.url = url; @@ -146,25 +146,25 @@ PluginURLFetcher::PluginURLFetcher(PluginStreamUrl* plugin_stream, request_info.headers = std::string("Range: ") + range; } - bridge_.reset(ChildThreadImpl::current()->resource_dispatcher()->CreateBridge( - request_info)); - if (!body.empty()) { - scoped_refptr<ResourceRequestBody> request_body = - new ResourceRequestBody; + scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; + if (!body.empty()) request_body->AppendBytes(&body[0], body.size()); - bridge_->SetRequestBody(request_body.get()); - } - bridge_->Start(this); + request_id_ = ChildThreadImpl::current()->resource_dispatcher()->StartAsync( + request_info, request_body.get(), this); // TODO(jam): range requests } PluginURLFetcher::~PluginURLFetcher() { + if (request_id_ >= 0) { + ChildThreadImpl::current()->resource_dispatcher()->RemovePendingRequest( + request_id_); + } } void PluginURLFetcher::Cancel() { - bridge_->Cancel(); + ChildThreadImpl::current()->resource_dispatcher()->Cancel(request_id_); // Due to races and nested event loops, PluginURLFetcher may still receive // events from the bridge before being destroyed. Do not forward additional @@ -181,9 +181,10 @@ void PluginURLFetcher::URLRedirectResponse(bool allow) { return; if (allow) { - bridge_->SetDefersLoading(false); + ChildThreadImpl::current()->resource_dispatcher()->SetDefersLoading( + request_id_, false); } else { - bridge_->Cancel(); + ChildThreadImpl::current()->resource_dispatcher()->Cancel(request_id_); plugin_stream_->DidFail(resource_id_); // That will delete |this|. } } @@ -226,7 +227,8 @@ bool PluginURLFetcher::OnReceivedRedirect( } } else { // Pause the request while we ask the plugin what to do about the redirect. - bridge_->SetDefersLoading(true); + ChildThreadImpl::current()->resource_dispatcher()->SetDefersLoading( + request_id_, true); plugin_stream_->WillSendRequest(url_, redirect_info.status_code); } diff --git a/content/child/npapi/plugin_url_fetcher.h b/content/child/npapi/plugin_url_fetcher.h index ace77ff..e16a4ac 100644 --- a/content/child/npapi/plugin_url_fetcher.h +++ b/content/child/npapi/plugin_url_fetcher.h @@ -15,7 +15,6 @@ namespace content { class MultipartResponseDelegate; class PluginStreamUrl; -class ResourceLoaderBridge; // Fetches URLS for a plugin using ResourceDispatcher. class PluginURLFetcher : public RequestPeer { @@ -83,11 +82,10 @@ class PluginURLFetcher : public RequestPeer { bool copy_stream_data_; int64 data_offset_; bool pending_failure_notification_; + int request_id_; scoped_ptr<MultipartResponseDelegate> multipart_delegate_; - scoped_ptr<ResourceLoaderBridge> bridge_; - DISALLOW_COPY_AND_ASSIGN(PluginURLFetcher); }; diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index 1a1c88a4..cf56a77 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc @@ -18,7 +18,6 @@ #include "base/strings/string_util.h" #include "content/child/request_extra_data.h" #include "content/child/request_info.h" -#include "content/child/resource_loader_bridge.h" #include "content/child/site_isolation_policy.h" #include "content/child/sync_load_response.h" #include "content/child/threaded_data_provider.h" @@ -65,227 +64,6 @@ int MakeRequestID() { } // namespace -// ResourceLoaderBridge implementation ---------------------------------------- - -class IPCResourceLoaderBridge : public ResourceLoaderBridge { - public: - IPCResourceLoaderBridge(ResourceDispatcher* dispatcher, - const RequestInfo& request_info); - ~IPCResourceLoaderBridge() override; - - // ResourceLoaderBridge - void SetRequestBody(ResourceRequestBody* request_body) override; - bool Start(RequestPeer* peer) override; - void Cancel() override; - void SetDefersLoading(bool value) override; - void DidChangePriority(net::RequestPriority new_priority, - int intra_priority_value) override; - bool AttachThreadedDataReceiver( - blink::WebThreadedDataReceiver* threaded_data_receiver) override; - void SyncLoad(SyncLoadResponse* response) override; - - private: - // 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) - : 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.url; - 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; - request_.skip_service_worker = request_info.skip_service_worker; - request_.should_reset_appcache = request_info.should_reset_appcache; - request_.fetch_request_mode = request_info.fetch_request_mode; - request_.fetch_credentials_mode = request_info.fetch_credentials_mode; - request_.fetch_request_context_type = request_info.fetch_request_context_type; - request_.fetch_frame_type = request_info.fetch_frame_type; - request_.enable_load_timing = request_info.enable_load_timing; - request_.enable_upload_progress = request_info.enable_upload_progress; - request_.do_not_prompt_for_login = request_info.do_not_prompt_for_login; - - if ((request_info.referrer.policy == blink::WebReferrerPolicyDefault || - request_info.referrer.policy == - blink::WebReferrerPolicyNoReferrerWhenDowngrade) && - request_info.referrer.url.SchemeIsSecure() && - !request_info.url.SchemeIsSecure()) { - LOG(FATAL) << "Trying to send secure referrer for insecure request " - << "without an appropriate referrer policy.\n" - << "URL = " << request_info.url << "\n" - << "Referrer = " << request_info.referrer.url; - } - - 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_); - } -} - -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; - } - - // 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, - request_.download_to_file); - - 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_) { - // This also removes the the request from the dispatcher. - dispatcher_->CancelPendingRequest(request_id_); - } -} - -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( - request_id_, new_priority, intra_priority_value); -} - -bool IPCResourceLoaderBridge::AttachThreadedDataReceiver( - blink::WebThreadedDataReceiver* threaded_data_receiver) { - if (request_id_ < 0) { - NOTREACHED() << "Trying to attach threaded receiver on unstarted request"; - return false; - } - - return dispatcher_->AttachThreadedDataReceiver(request_id_, - threaded_data_receiver); -} - -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, scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) @@ -299,8 +77,6 @@ ResourceDispatcher::ResourceDispatcher( ResourceDispatcher::~ResourceDispatcher() { } -// ResourceDispatcher implementation ------------------------------------------ - bool ResourceDispatcher::OnMessageReceived(const IPC::Message& message) { if (!IsResourceDispatcherMessage(message)) { return false; @@ -445,8 +221,7 @@ void ResourceDispatcher::OnReceivedData(int request_id, 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 CancelPendingRequest() to be called before we exit - // this scope. + // It is possible for Cancel() to be called before we exit this scope. linked_ptr<base::SharedMemory> retain_buffer(request_info->buffer); base::TimeTicks time_start = base::TimeTicks::Now(); @@ -539,7 +314,7 @@ void ResourceDispatcher::OnReceivedRedirect( FollowPendingRedirect(request_id, *request_info); } } else { - CancelPendingRequest(request_id); + Cancel(request_id); } } @@ -615,23 +390,6 @@ void ResourceDispatcher::CompletedRequestAfterBackgroundThreadFlush( request_complete_data.encoded_data_length); } -int ResourceDispatcher::AddPendingRequest(RequestPeer* callback, - ResourceType resource_type, - int origin_pid, - const GURL& frame_origin, - const GURL& request_url, - bool download_to_file) { - // 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, - download_to_file); - return id; -} - bool ResourceDispatcher::RemovePendingRequest(int request_id) { PendingRequestList::iterator it = pending_requests_.find(request_id); if (it == pending_requests_.end()) @@ -652,7 +410,7 @@ bool ResourceDispatcher::RemovePendingRequest(int request_id) { return true; } -void ResourceDispatcher::CancelPendingRequest(int request_id) { +void ResourceDispatcher::Cancel(int request_id) { PendingRequestList::iterator it = pending_requests_.find(request_id); if (it == pending_requests_.end()) { DVLOG(1) << "unknown request"; @@ -788,9 +546,57 @@ void ResourceDispatcher::FlushDeferredMessages(int request_id) { } } -ResourceLoaderBridge* ResourceDispatcher::CreateBridge( - const RequestInfo& request_info) { - return new IPCResourceLoaderBridge(this, request_info); +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; } void ResourceDispatcher::ToResourceResponseInfo( @@ -928,4 +734,71 @@ void ResourceDispatcher::ReleaseResourcesInMessageQueue(MessageQueue* queue) { } } +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.url; + 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; + request->skip_service_worker = request_info.skip_service_worker; + request->should_reset_appcache = request_info.should_reset_appcache; + request->fetch_request_mode = request_info.fetch_request_mode; + request->fetch_credentials_mode = request_info.fetch_credentials_mode; + request->fetch_request_context_type = request_info.fetch_request_context_type; + request->fetch_frame_type = request_info.fetch_frame_type; + request->enable_load_timing = request_info.enable_load_timing; + request->enable_upload_progress = request_info.enable_upload_progress; + request->do_not_prompt_for_login = request_info.do_not_prompt_for_login; + + if ((request_info.referrer.policy == blink::WebReferrerPolicyDefault || + request_info.referrer.policy == + blink::WebReferrerPolicyNoReferrerWhenDowngrade) && + request_info.referrer.url.SchemeIsSecure() && + !request_info.url.SchemeIsSecure()) { + LOG(FATAL) << "Trying to send secure referrer for insecure request " + << "without an appropriate referrer policy.\n" + << "URL = " << request_info.url << "\n" + << "Referrer = " << request_info.referrer.url; + } + + 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 diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index ce21c3b..769eae2 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h @@ -12,6 +12,7 @@ #include "base/containers/hash_tables.h" #include "base/memory/linked_ptr.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/shared_memory.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" @@ -23,6 +24,7 @@ #include "net/base/request_priority.h" #include "url/gurl.h" +struct ResourceHostMsg_Request; struct ResourceMsg_RequestCompleteData; namespace blink { @@ -36,16 +38,17 @@ struct RedirectInfo; namespace content { class RequestPeer; class ResourceDispatcherDelegate; -class ResourceLoaderBridge; +class ResourceRequestBody; class ThreadedDataProvider; struct ResourceResponseInfo; struct RequestInfo; struct ResourceResponseHead; struct SiteIsolationResponseMetaData; +struct SyncLoadResponse; -// This class serves as a communication interface between the -// ResourceDispatcherHost in the browser process and the ResourceLoaderBridge in -// the child process. It can be used from any child process. +// This class serves as a communication interface to the ResourceDispatcherHost +// in the browser process. It can be used from any child process. +// Virtual methods are for tests. class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener { public: ResourceDispatcher( @@ -56,19 +59,23 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener { // IPC::Listener implementation. bool OnMessageReceived(const IPC::Message& message) override; - // Creates a ResourceLoaderBridge for this type of dispatcher, this is so - // this can be tested regardless of the ResourceLoaderBridge::Create - // implementation. Virtual for tests. - virtual ResourceLoaderBridge* CreateBridge(const RequestInfo& request_info); - - // Adds a request from the |pending_requests_| list, returning the new - // requests' ID. - int AddPendingRequest(RequestPeer* callback, - ResourceType resource_type, - int origin_pid, - const GURL& frame_origin, - const GURL& request_url, - bool download_to_file); + // Call this method to load the resource synchronously (i.e., in one shot). + // This is an alternative to the StartAsync method. Be warned that this method + // will block the calling thread until the resource is fully downloaded or an + // error occurs. It could block the calling thread for a long time, so only + // use this if you really need it! There is also no way for the caller to + // interrupt this method. Errors are reported via the status field of the + // response parameter. + void StartSync(const RequestInfo& request_info, + ResourceRequestBody* request_body, + SyncLoadResponse* response); + + // Call this method to initiate the request. If this method succeeds, then + // the peer's methods will be called asynchronously to report various events. + // Returns the request id. + virtual int StartAsync(const RequestInfo& request_info, + ResourceRequestBody* request_body, + RequestPeer* peer); // Removes a request from the |pending_requests_| list, returning true if the // request was found and removed. @@ -76,7 +83,7 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener { // Cancels a request in the |pending_requests_| list. The request will be // removed from the dispatcher as well. - void CancelPendingRequest(int request_id); + virtual void Cancel(int request_id); // Toggles the is_deferred attribute for the specified request. void SetDefersLoading(int request_id, bool value); @@ -105,8 +112,6 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener { message_sender_ = sender; } - IPC::Sender* message_sender() const { return message_sender_; } - // This does not take ownership of the delegate. It is expected that the // delegate have a longer lifetime than the ResourceDispatcher. void set_delegate(ResourceDispatcherDelegate* delegate) { @@ -227,6 +232,11 @@ class CONTENT_EXPORT ResourceDispatcher : public IPC::Listener { // for use on deferred message queues that are no longer needed. static void ReleaseResourcesInMessageQueue(MessageQueue* queue); + scoped_ptr<ResourceHostMsg_Request> CreateRequest( + const RequestInfo& request_info, + ResourceRequestBody* request_body, + GURL* frame_origin); + IPC::Sender* message_sender_; // All pending requests issued to the host diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc index 46ce695..e0938d1 100644 --- a/content/child/resource_dispatcher_unittest.cc +++ b/content/child/resource_dispatcher_unittest.cc @@ -15,7 +15,6 @@ #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/child/resource_dispatcher.h" -#include "content/child/resource_loader_bridge.h" #include "content/common/appcache_interfaces.h" #include "content/common/resource_messages.h" #include "content/common/service_worker/service_worker_types.h" @@ -41,7 +40,7 @@ static const char kTestRedirectHeaders[] = // to the reference data. class TestRequestPeer : public RequestPeer { public: - TestRequestPeer(ResourceLoaderBridge* bridge) + TestRequestPeer(ResourceDispatcher* dispatcher) : follow_redirects_(true), defer_on_redirect_(false), seen_redirects_(0), @@ -50,16 +49,19 @@ class TestRequestPeer : public RequestPeer { total_encoded_data_length_(0), total_downloaded_data_length_(0), complete_(false), - bridge_(bridge) { + dispatcher_(dispatcher), + request_id_(0) { } + void set_request_id(int request_id) { request_id_ = request_id; } + void OnUploadProgress(uint64 position, uint64 size) override {} bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, const ResourceResponseInfo& info) override { ++seen_redirects_; if (defer_on_redirect_) - bridge_->SetDefersLoading(true); + dispatcher_->SetDefersLoading(request_id_, true); return follow_redirects_; } @@ -67,7 +69,7 @@ class TestRequestPeer : public RequestPeer { EXPECT_FALSE(received_response_); received_response_ = true; if (cancel_on_receive_response_) - bridge_->Cancel(); + dispatcher_->Cancel(request_id_); } void OnDownloadedData(int len, int encoded_data_length) override { @@ -144,7 +146,8 @@ class TestRequestPeer : public RequestPeer { bool complete_; - ResourceLoaderBridge* bridge_; + ResourceDispatcher* dispatcher_; + int request_id_; DISALLOW_COPY_AND_ASSIGN(TestRequestPeer); }; @@ -306,37 +309,28 @@ class ResourceDispatcherTest : public testing::Test, public IPC::Sender { ResourceMsg_RequestComplete(request_id, request_complete_data))); } - ResourceLoaderBridge* CreateBridge() { - return CreateBridgeInternal(false); - } + RequestInfo* CreateRequestInfo(bool download_to_file) { + RequestInfo* request_info = new RequestInfo(); + request_info->method = "GET"; + request_info->url = GURL(kTestPageUrl); + request_info->first_party_for_cookies = GURL(kTestPageUrl); + request_info->referrer = Referrer(); + request_info->headers = std::string(); + request_info->load_flags = 0; + request_info->requestor_pid = 0; + request_info->request_type = RESOURCE_TYPE_SUB_RESOURCE; + request_info->appcache_host_id = kAppCacheNoHostId; + request_info->should_reset_appcache = false; + request_info->routing_id = 0; + request_info->download_to_file = download_to_file; + RequestExtraData extra_data; - ResourceLoaderBridge* CreateBridgeForDownloadToFile() { - return CreateBridgeInternal(true); + return request_info; } ResourceDispatcher* dispatcher() { return &dispatcher_; } private: - ResourceLoaderBridge* CreateBridgeInternal(bool download_to_file) { - RequestInfo request_info; - request_info.method = "GET"; - request_info.url = GURL(kTestPageUrl); - request_info.first_party_for_cookies = GURL(kTestPageUrl); - request_info.referrer = Referrer(); - request_info.headers = std::string(); - request_info.load_flags = 0; - request_info.requestor_pid = 0; - request_info.request_type = RESOURCE_TYPE_SUB_RESOURCE; - request_info.appcache_host_id = kAppCacheNoHostId; - request_info.should_reset_appcache = false; - request_info.routing_id = 0; - request_info.download_to_file = download_to_file; - RequestExtraData extra_data; - request_info.extra_data = &extra_data; - - return dispatcher_.CreateBridge(request_info); - } - // Map of request IDs to shared memory. std::map<int, base::SharedMemory*> shared_memory_map_; @@ -352,10 +346,11 @@ TEST_F(ResourceDispatcherTest, RoundTrip) { const size_t kFirstReceiveSize = 2; ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents)); - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -383,14 +378,18 @@ TEST_F(ResourceDispatcherTest, RoundTrip) { TEST_F(ResourceDispatcherTest, MultipleRequests) { const char kTestPageContents2[] = "Not kTestPageContents"; - scoped_ptr<ResourceLoaderBridge> bridge1(CreateBridge()); - TestRequestPeer peer1(bridge1.get()); - scoped_ptr<ResourceLoaderBridge> bridge2(CreateBridge()); - TestRequestPeer peer2(bridge2.get()); + scoped_ptr<RequestInfo> request_info1(CreateRequestInfo(false)); + TestRequestPeer peer1(dispatcher()); + int request_id1 = dispatcher()->StartAsync( + *request_info1.get(), NULL, &peer1); + peer1.set_request_id(request_id1); + scoped_ptr<RequestInfo> request_info2(CreateRequestInfo(false)); + TestRequestPeer peer2(dispatcher()); + int request_id2 = dispatcher()->StartAsync( + *request_info1.get(), NULL, &peer2); + peer2.set_request_id(request_id2); - EXPECT_TRUE(bridge1->Start(&peer1)); int id1 = ConsumeRequestResource(); - EXPECT_TRUE(bridge2->Start(&peer2)); int id2 = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -423,15 +422,16 @@ TEST_F(ResourceDispatcherTest, MultipleRequests) { // Tests that the cancel method prevents other messages from being received. TEST_F(ResourceDispatcherTest, Cancel) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); // Cancel the request. - bridge->Cancel(); + dispatcher()->Cancel(request_id); ConsumeCancelRequest(id); // Any future messages related to the request should be ignored. @@ -448,11 +448,12 @@ TEST_F(ResourceDispatcherTest, Cancel) { // Tests that calling cancel during a callback works as expected. TEST_F(ResourceDispatcherTest, CancelDuringCallback) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); peer.set_cancel_on_receive_response(true); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -473,10 +474,11 @@ TEST_F(ResourceDispatcherTest, CancelDuringCallback) { // Checks that redirects work as expected. TEST_F(ResourceDispatcherTest, Redirect) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); NotifyReceivedRedirect(id); @@ -504,11 +506,12 @@ TEST_F(ResourceDispatcherTest, Redirect) { // Tests that that cancelling during a redirect method prevents other messages // from being received. TEST_F(ResourceDispatcherTest, CancelDuringRedirect) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); peer.set_follow_redirects(false); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -534,14 +537,15 @@ TEST_F(ResourceDispatcherTest, CancelDuringRedirect) { // Checks that deferring a request delays messages until it's resumed. TEST_F(ResourceDispatcherTest, Defer) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); - bridge->SetDefersLoading(true); + dispatcher()->SetDefersLoading(request_id, true); NotifyReceivedResponse(id); NotifySetDataBuffer(id, strlen(kTestPageContents)); NotifyDataReceived(id, kTestPageContents); @@ -555,7 +559,7 @@ TEST_F(ResourceDispatcherTest, Defer) { EXPECT_EQ(0, peer.seen_redirects()); // Resuming the request should asynchronously unleash the deferred messages. - bridge->SetDefersLoading(false); + dispatcher()->SetDefersLoading(request_id, false); base::RunLoop().RunUntilIdle(); ConsumeDataReceived_ACK(id); @@ -568,11 +572,12 @@ TEST_F(ResourceDispatcherTest, Defer) { // Checks that deferring a request during a redirect delays messages until it's // resumed. TEST_F(ResourceDispatcherTest, DeferOnRedirect) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); peer.set_defer_on_redirect(true); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -592,7 +597,7 @@ TEST_F(ResourceDispatcherTest, DeferOnRedirect) { EXPECT_EQ(1, peer.seen_redirects()); // Resuming the request should asynchronously unleash the deferred messages. - bridge->SetDefersLoading(false); + dispatcher()->SetDefersLoading(request_id, false); base::RunLoop().RunUntilIdle(); ConsumeFollowRedirect(id); @@ -607,16 +612,17 @@ TEST_F(ResourceDispatcherTest, DeferOnRedirect) { // Checks that a deferred request that's cancelled doesn't receive any messages. TEST_F(ResourceDispatcherTest, CancelDeferredRequest) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); - bridge->SetDefersLoading(true); + dispatcher()->SetDefersLoading(request_id, true); NotifyReceivedRedirect(id); - bridge->Cancel(); + dispatcher()->Cancel(request_id); ConsumeCancelRequest(id); NotifyRequestComplete(id, 0); @@ -630,12 +636,13 @@ TEST_F(ResourceDispatcherTest, CancelDeferredRequest) { } TEST_F(ResourceDispatcherTest, DownloadToFile) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridgeForDownloadToFile()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(true)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); const int kDownloadedIncrement = 100; const int kEncodedIncrement = 50; - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -660,7 +667,7 @@ TEST_F(ResourceDispatcherTest, DownloadToFile) { EXPECT_TRUE(peer.complete()); EXPECT_EQ(0u, queued_messages()); - bridge.reset(); + dispatcher()->RemovePendingRequest(request_id); ConsumeReleaseDownloadedFile(id); EXPECT_EQ(0u, queued_messages()); EXPECT_EQ(expected_total_downloaded_length, @@ -670,10 +677,11 @@ TEST_F(ResourceDispatcherTest, DownloadToFile) { // Make sure that when a download to file is cancelled, the file is destroyed. TEST_F(ResourceDispatcherTest, CancelDownloadToFile) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridgeForDownloadToFile()); - TestRequestPeer peer(bridge.get()); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(true)); + TestRequestPeer peer(dispatcher()); + int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer); + peer.set_request_id(request_id); - EXPECT_TRUE(bridge->Start(&peer)); int id = ConsumeRequestResource(); EXPECT_EQ(0u, queued_messages()); @@ -682,13 +690,9 @@ TEST_F(ResourceDispatcherTest, CancelDownloadToFile) { EXPECT_TRUE(peer.received_response()); // Cancelling the request deletes the file. - bridge->Cancel(); + dispatcher()->Cancel(request_id); ConsumeCancelRequest(id); ConsumeReleaseDownloadedFile(id); - - // Deleting the bridge shouldn't send another message to delete the file. - bridge.reset(); - EXPECT_EQ(0u, queued_messages()); } TEST_F(ResourceDispatcherTest, Cookies) { @@ -708,8 +712,9 @@ class TimeConversionTest : public ResourceDispatcherTest, } void PerformTest(const ResourceResponseHead& response_head) { - scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge()); - bridge->Start(this); + scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false)); + TestRequestPeer peer(dispatcher()); + dispatcher()->StartAsync(*request_info.get(), NULL, &peer); dispatcher()->OnMessageReceived( ResourceMsg_ReceivedResponse(0, response_head)); diff --git a/content/child/resource_loader_bridge.cc b/content/child/resource_loader_bridge.cc deleted file mode 100644 index dd68ccb..0000000 --- a/content/child/resource_loader_bridge.cc +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2014 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/child/resource_loader_bridge.h" - -namespace content { - -ResourceLoaderBridge::ResourceLoaderBridge() {} - -ResourceLoaderBridge::~ResourceLoaderBridge() {} - -} // namespace content diff --git a/content/child/resource_loader_bridge.h b/content/child/resource_loader_bridge.h deleted file mode 100644 index 759f832..0000000 --- a/content/child/resource_loader_bridge.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2014 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. -// -// The intent of this file is to provide a type-neutral abstraction between -// Chrome and WebKit for resource loading. This pure-virtual interface is -// implemented by the embedder. -// -// One of these objects will be created by WebKit for each request. WebKit -// will own the pointer to the bridge, and will delete it when the request is -// no longer needed. -// -// In turn, the bridge's owner on the WebKit end will implement the -// RequestPeer interface, which we will use to communicate notifications -// back. - -#ifndef CONTENT_CHILD_RESOURCE_LOADER_BRIDGE_H_ -#define CONTENT_CHILD_RESOURCE_LOADER_BRIDGE_H_ - -#include "base/macros.h" -#include "content/common/content_export.h" -#include "net/base/request_priority.h" - -namespace blink { -class WebThreadedDataReceiver; -} - -namespace content { - -class RequestPeer; -class ResourceRequestBody; -struct SyncLoadResponse; - -// TODO(tfarina): Refactor code that uses this class. This shouldn't be needed -// now that it lives in content/. -class CONTENT_EXPORT ResourceLoaderBridge { - public: - // use BlinkPlatformImpl::CreateResourceLoader() for construction, but - // anybody can delete at any time, INCLUDING during processing of callbacks. - virtual ~ResourceLoaderBridge(); - - // Call this method before calling Start() to set the request body. - // May only be used with HTTP(S) POST requests. - virtual void SetRequestBody(ResourceRequestBody* request_body) = 0; - - // Call this method to initiate the request. If this method succeeds, then - // the peer's methods will be called asynchronously to report various events. - virtual bool Start(RequestPeer* peer) = 0; - - // Call this method to cancel a request that is in progress. This method - // causes the request to immediately transition into the 'done' state. The - // OnCompletedRequest method will be called asynchronously; this assumes - // the peer is still valid. - virtual void Cancel() = 0; - - // Call this method to suspend or resume a load that is in progress. This - // method may only be called after a successful call to the Start method. - virtual void SetDefersLoading(bool value) = 0; - - // Call this method when the priority of the requested resource changes after - // Start() has been called. This method may only be called after a successful - // call to the Start method. - virtual void DidChangePriority(net::RequestPriority new_priority, - int intra_priority_value) = 0; - - // Call this method to attach a data receiver which will receive resource data - // on its own thread. - virtual bool AttachThreadedDataReceiver( - blink::WebThreadedDataReceiver* threaded_data_receiver) = 0; - - // Call this method to load the resource synchronously (i.e., in one shot). - // This is an alternative to the Start method. Be warned that this method - // will block the calling thread until the resource is fully downloaded or an - // error occurs. It could block the calling thread for a long time, so only - // use this if you really need it! There is also no way for the caller to - // interrupt this method. Errors are reported via the status field of the - // response parameter. - virtual void SyncLoad(SyncLoadResponse* response) = 0; - - protected: - // Construction must go through BlinkPlatformImpl::CreateResourceLoader(). - // For HTTP(S) POST requests, the AppendDataToUpload and AppendFileToUpload - // methods may be called to construct the body of the request. - ResourceLoaderBridge(); - - private: - DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBridge); -}; - -} // namespace content - -#endif // CONTENT_CHILD_RESOURCE_LOADER_BRIDGE_H_ diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index adca0da..3274fb4 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// An implementation of WebURLLoader in terms of ResourceLoaderBridge. - #include "content/child/web_url_loader_impl.h" #include <algorithm> @@ -18,16 +16,17 @@ #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" #include "base/time/time.h" +#include "content/child/child_thread_impl.h" #include "content/child/ftp_directory_listing_response_delegate.h" #include "content/child/multipart_response_delegate.h" #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/child/resource_dispatcher.h" -#include "content/child/resource_loader_bridge.h" #include "content/child/sync_load_response.h" #include "content/child/web_data_consumer_handle_impl.h" #include "content/child/web_url_request_util.h" #include "content/child/weburlresponse_extradata_impl.h" +#include "content/common/resource_messages.h" #include "content/common/resource_request_body.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/child/request_peer.h" @@ -331,7 +330,7 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, private: friend class base::RefCounted<Context>; - ~Context() override {} + ~Context() override; // We can optimize the handling of data URLs in most cases. bool CanHandleDataURLRequestLocally() const; @@ -345,10 +344,8 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, ResourceDispatcher* resource_dispatcher_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; WebReferrerPolicy referrer_policy_; - scoped_ptr<ResourceLoaderBridge> bridge_; scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; scoped_ptr<MultipartResponseDelegate> multipart_delegate_; - scoped_ptr<ResourceLoaderBridge> completed_bridge_; scoped_ptr<StreamOverrideParameters> stream_override_; mojo::ScopedDataPipeProducerHandle body_stream_writer_; mojo::common::HandleWatcher body_stream_writer_watcher_; @@ -358,6 +355,7 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, bool got_all_stream_body_data_; enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA}; DeferState defers_loading_; + int request_id_; }; WebURLLoaderImpl::Context::Context( @@ -370,14 +368,13 @@ WebURLLoaderImpl::Context::Context( task_runner_(task_runner), referrer_policy_(blink::WebReferrerPolicyDefault), got_all_stream_body_data_(false), - defers_loading_(NOT_DEFERRING) { + defers_loading_(NOT_DEFERRING), + request_id_(-1) { } void WebURLLoaderImpl::Context::Cancel() { - if (bridge_) { - bridge_->Cancel(); - bridge_.reset(); - } + if (resource_dispatcher_) // NULL in unittest. + resource_dispatcher_->Cancel(request_id_); // Ensure that we do not notify the multipart delegate anymore as it has // its own pointer to the client. @@ -393,8 +390,7 @@ void WebURLLoaderImpl::Context::Cancel() { } void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { - if (bridge_) - bridge_->SetDefersLoading(value); + resource_dispatcher_->SetDefersLoading(request_id_, value); if (value && defers_loading_ == NOT_DEFERRING) { defers_loading_ = SHOULD_DEFER; } else if (!value && defers_loading_ != NOT_DEFERRING) { @@ -408,23 +404,22 @@ void WebURLLoaderImpl::Context::SetDefersLoading(bool value) { void WebURLLoaderImpl::Context::DidChangePriority( WebURLRequest::Priority new_priority, int intra_priority_value) { - if (bridge_) - bridge_->DidChangePriority( - ConvertWebKitPriorityToNetPriority(new_priority), intra_priority_value); + resource_dispatcher_->DidChangePriority( + request_id_, + ConvertWebKitPriorityToNetPriority(new_priority), + intra_priority_value); } bool WebURLLoaderImpl::Context::AttachThreadedDataReceiver( blink::WebThreadedDataReceiver* threaded_data_receiver) { - if (bridge_) - return bridge_->AttachThreadedDataReceiver(threaded_data_receiver); + resource_dispatcher_->AttachThreadedDataReceiver( + request_id_, threaded_data_receiver); return false; } void WebURLLoaderImpl::Context::Start(const WebURLRequest& request, SyncLoadResponse* sync_load_response) { - DCHECK(!bridge_.get()); - request_ = request; // Save the request. if (request.extraData()) { RequestExtraData* extra_data = @@ -509,19 +504,18 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request, request_info.fetch_request_context_type = GetRequestContextType(request); request_info.fetch_frame_type = GetRequestContextFrameType(request); request_info.extra_data = request.extraData(); - bridge_.reset(resource_dispatcher_->CreateBridge(request_info)); - bridge_->SetRequestBody(GetRequestBodyForWebURLRequest(request).get()); + + scoped_refptr<ResourceRequestBody> request_body = + GetRequestBodyForWebURLRequest(request).get(); if (sync_load_response) { - bridge_->SyncLoad(sync_load_response); + resource_dispatcher_->StartSync( + request_info, request_body.get(), sync_load_response); return; } - // TODO(mmenke): This case probably never happens, anyways. Probably should - // not handle this case at all. If it's worth handling, this code currently - // results in the request just hanging, which should be fixed. - if (!bridge_->Start(this)) - bridge_.reset(); + request_id_ = resource_dispatcher_->StartAsync( + request_info, request_body.get(), this); } void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { @@ -739,11 +733,6 @@ void WebURLLoaderImpl::Context::OnCompletedRequest( multipart_delegate_.reset(NULL); } - // Prevent any further IPC to the browser now that we're complete, but - // don't delete it to keep any downloaded temp files alive. - DCHECK(!completed_bridge_.get()); - completed_bridge_.swap(bridge_); - if (client_) { if (error_code != net::OK) { client_->didFail(loader_, CreateError(request_.url(), @@ -768,6 +757,12 @@ void WebURLLoaderImpl::Context::OnCompletedRequest( } } +WebURLLoaderImpl::Context::~Context() { + if (request_id_ >= 0) { + resource_dispatcher_->RemovePendingRequest(request_id_); + } +} + bool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally() const { GURL url = request_.url(); if (!url.SchemeIs(url::kDataScheme)) @@ -783,8 +778,7 @@ bool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally() const { // download. // // NOTE: We special case MIME types we can render both for performance - // reasons as well as to support unit tests, which do not have an underlying - // ResourceLoaderBridge implementation. + // reasons as well as to support unit tests. #if defined(OS_ANDROID) // For compatibility reasons on Android we need to expose top-level data:// diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc index ab4c645..f132169 100644 --- a/content/child/web_url_loader_impl_unittest.cc +++ b/content/child/web_url_loader_impl_unittest.cc @@ -15,7 +15,6 @@ #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/child/resource_dispatcher.h" -#include "content/child/resource_loader_bridge.h" #include "content/public/child/request_peer.h" #include "content/public/common/content_switches.h" #include "content/public/common/resource_response_info.h" @@ -60,44 +59,32 @@ const char kMultipartResponse[] = "Content-type: text/html\n\n" "ah!"; -class TestBridge : public ResourceLoaderBridge, - public base::SupportsWeakPtr<TestBridge> { +class TestResourceDispatcher : public ResourceDispatcher { public: - TestBridge(const RequestInfo& info) : - peer_(NULL), - canceled_(false), - url_(info.url) { + TestResourceDispatcher() : + ResourceDispatcher(nullptr, nullptr), + peer_(NULL), + canceled_(false) { } - ~TestBridge() override {} + ~TestResourceDispatcher() override {} - // ResourceLoaderBridge implementation: - void SetRequestBody(ResourceRequestBody* request_body) override {} + // TestDispatcher implementation: - bool Start(RequestPeer* peer) override { + int StartAsync(const RequestInfo& request_info, + ResourceRequestBody* request_body, + RequestPeer* peer) override { EXPECT_FALSE(peer_); peer_ = peer; - return true; + url_ = request_info.url; + return 1; } - void Cancel() override { + void Cancel(int request_id) override { EXPECT_FALSE(canceled_); canceled_ = true; } - void SetDefersLoading(bool value) override {} - - void DidChangePriority(net::RequestPriority new_priority, - int intra_priority_value) override {} - - bool AttachThreadedDataReceiver( - blink::WebThreadedDataReceiver* threaded_data_receiver) override { - NOTREACHED(); - return false; - } - - void SyncLoad(SyncLoadResponse* response) override {} - RequestPeer* peer() { return peer_; } bool canceled() { return canceled_; } @@ -109,27 +96,6 @@ class TestBridge : public ResourceLoaderBridge, bool canceled_; GURL url_; - DISALLOW_COPY_AND_ASSIGN(TestBridge); -}; - -class TestResourceDispatcher : public ResourceDispatcher { - public: - TestResourceDispatcher() : ResourceDispatcher(nullptr, nullptr) {} - ~TestResourceDispatcher() override {} - - // ResourceDispatcher implementation: - ResourceLoaderBridge* CreateBridge(const RequestInfo& request_info) override { - EXPECT_FALSE(bridge_.get()); - TestBridge* bridge = new TestBridge(request_info); - bridge_ = bridge->AsWeakPtr(); - return bridge; - } - - TestBridge* bridge() { return bridge_.get(); } - - private: - base::WeakPtr<TestBridge> bridge_; - DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcher); }; @@ -295,7 +261,6 @@ class WebURLLoaderImplTest : public testing::Test { request.initialize(); request.setURL(GURL(kTestURL)); client()->loader()->loadAsynchronously(request, client()); - ASSERT_TRUE(bridge()); ASSERT_TRUE(peer()); } @@ -377,8 +342,8 @@ class WebURLLoaderImplTest : public testing::Test { } TestWebURLLoaderClient* client() { return &client_; } - TestBridge* bridge() { return dispatcher_.bridge(); } - RequestPeer* peer() { return bridge()->peer(); } + TestResourceDispatcher* dispatcher() { return &dispatcher_; } + RequestPeer* peer() { return dispatcher()->peer(); } base::MessageLoop* message_loop() { return &message_loop_; } private: @@ -392,7 +357,7 @@ TEST_F(WebURLLoaderImplTest, Success) { DoReceiveResponse(); DoReceiveData(); DoCompleteRequest(); - EXPECT_FALSE(bridge()->canceled()); + EXPECT_FALSE(dispatcher()->canceled()); EXPECT_EQ(kTestData, client()->received_data()); } @@ -402,7 +367,7 @@ TEST_F(WebURLLoaderImplTest, Redirect) { DoReceiveResponse(); DoReceiveData(); DoCompleteRequest(); - EXPECT_FALSE(bridge()->canceled()); + EXPECT_FALSE(dispatcher()->canceled()); EXPECT_EQ(kTestData, client()->received_data()); } @@ -411,7 +376,7 @@ TEST_F(WebURLLoaderImplTest, Failure) { DoReceiveResponse(); DoReceiveData(); DoFailRequest(); - EXPECT_FALSE(bridge()->canceled()); + EXPECT_FALSE(dispatcher()->canceled()); } // The client may delete the WebURLLoader during any callback from the loader. @@ -420,14 +385,12 @@ TEST_F(WebURLLoaderImplTest, DeleteOnReceiveRedirect) { client()->set_delete_on_receive_redirect(); DoStartAsyncRequest(); DoReceiveRedirect(); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DeleteOnReceiveResponse) { client()->set_delete_on_receive_response(); DoStartAsyncRequest(); DoReceiveResponse(); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DeleteOnReceiveData) { @@ -435,7 +398,6 @@ TEST_F(WebURLLoaderImplTest, DeleteOnReceiveData) { DoStartAsyncRequest(); DoReceiveResponse(); DoReceiveData(); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DeleteOnFinish) { @@ -444,7 +406,6 @@ TEST_F(WebURLLoaderImplTest, DeleteOnFinish) { DoReceiveResponse(); DoReceiveData(); DoCompleteRequest(); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DeleteOnFail) { @@ -453,7 +414,6 @@ TEST_F(WebURLLoaderImplTest, DeleteOnFail) { DoReceiveResponse(); DoReceiveData(); DoFailRequest(); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DeleteBeforeResponseDataURL) { @@ -464,7 +424,6 @@ TEST_F(WebURLLoaderImplTest, DeleteBeforeResponseDataURL) { client()->DeleteLoader(); message_loop()->RunUntilIdle(); EXPECT_FALSE(client()->did_receive_response()); - EXPECT_FALSE(bridge()); } // Data URL tests. @@ -491,7 +450,6 @@ TEST_F(WebURLLoaderImplTest, DataURLDeleteOnReceiveResponse) { EXPECT_TRUE(client()->did_receive_response()); EXPECT_EQ("", client()->received_data()); EXPECT_FALSE(client()->did_finish()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DataURLDeleteOnReceiveData) { @@ -504,7 +462,6 @@ TEST_F(WebURLLoaderImplTest, DataURLDeleteOnReceiveData) { EXPECT_TRUE(client()->did_receive_response()); EXPECT_EQ("blah!", client()->received_data()); EXPECT_FALSE(client()->did_finish()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DataURLDeleteOnFinish) { @@ -517,7 +474,6 @@ TEST_F(WebURLLoaderImplTest, DataURLDeleteOnFinish) { EXPECT_TRUE(client()->did_receive_response()); EXPECT_EQ("blah!", client()->received_data()); EXPECT_TRUE(client()->did_finish()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, DataURLDefersLoading) { @@ -566,7 +522,7 @@ TEST_F(WebURLLoaderImplTest, Ftp) { DoReceiveResponseFtp(); DoReceiveDataFtp(); DoCompleteRequest(); - EXPECT_FALSE(bridge()->canceled()); + EXPECT_FALSE(dispatcher()->canceled()); } TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveResponse) { @@ -576,18 +532,14 @@ TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveResponse) { // No data should have been received. EXPECT_EQ("", client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveFirstData) { client()->set_delete_on_receive_data(); DoStartAsyncRequest(); - // Some data is sent in ReceiveResponse for FTP requests, so the bridge should - // be deleted here. DoReceiveResponseFtp(); EXPECT_NE("", client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveMoreData) { @@ -601,8 +553,6 @@ TEST_F(WebURLLoaderImplTest, FtpDeleteOnReceiveMoreData) { peer()->OnCompletedRequest(net::OK, false, false, "", base::TimeTicks(), strlen(kTestData)); EXPECT_FALSE(client()->did_finish()); - - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, FtpDeleteOnFinish) { @@ -611,7 +561,6 @@ TEST_F(WebURLLoaderImplTest, FtpDeleteOnFinish) { DoReceiveResponseFtp(); DoReceiveDataFtp(); DoCompleteRequest(); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, FtpDeleteOnFail) { @@ -620,7 +569,6 @@ TEST_F(WebURLLoaderImplTest, FtpDeleteOnFail) { DoReceiveResponseFtp(); DoReceiveDataFtp(); DoFailRequest(); - EXPECT_FALSE(bridge()); } // Multipart integration tests. These are focused more on safe deletion than @@ -633,7 +581,7 @@ TEST_F(WebURLLoaderImplTest, Multipart) { DoReceiveDataMultipart(); DoCompleteRequest(); EXPECT_EQ(kTestData, client()->received_data()); - EXPECT_FALSE(bridge()->canceled()); + EXPECT_FALSE(dispatcher()->canceled()); } TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstResponse) { @@ -642,7 +590,6 @@ TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstResponse) { DoStartAsyncRequest(); DoReceiveResponseMultipart(); EXPECT_EQ("", client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveSecondResponse) { @@ -652,7 +599,6 @@ TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveSecondResponse) { client()->set_delete_on_receive_response(); DoReceiveDataMultipart(); EXPECT_EQ("", client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstData) { @@ -662,7 +608,6 @@ TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveFirstData) { DoReceiveResponseMultipart(); DoReceiveDataMultipart(); EXPECT_EQ("bl", client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveMoreData) { @@ -677,7 +622,6 @@ TEST_F(WebURLLoaderImplTest, MultipartDeleteOnReceiveMoreData) { strlen(kTestData)); EXPECT_FALSE(client()->did_finish()); EXPECT_EQ(kTestData, client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, MultipartDeleteFinish) { @@ -688,7 +632,6 @@ TEST_F(WebURLLoaderImplTest, MultipartDeleteFinish) { DoReceiveDataMultipart(); DoCompleteRequest(); EXPECT_EQ(kTestData, client()->received_data()); - EXPECT_FALSE(bridge()); } TEST_F(WebURLLoaderImplTest, MultipartDeleteFail) { @@ -698,7 +641,6 @@ TEST_F(WebURLLoaderImplTest, MultipartDeleteFail) { DoReceiveResponseMultipart(); DoReceiveDataMultipart(); DoFailRequest(); - EXPECT_FALSE(bridge()); } // PlzNavigate: checks that the stream override parameters provided on @@ -725,9 +667,8 @@ TEST_F(WebURLLoaderImplTest, BrowserSideNavigationCommit) { client()->loader()->loadAsynchronously(request, client()); // The stream url should have been requestead instead of the request url. - ASSERT_TRUE(bridge()); ASSERT_TRUE(peer()); - EXPECT_EQ(kStreamURL, bridge()->url()); + EXPECT_EQ(kStreamURL, dispatcher()->url()); EXPECT_FALSE(client()->did_receive_response()); peer()->OnReceivedResponse(content::ResourceResponseInfo()); @@ -739,7 +680,7 @@ TEST_F(WebURLLoaderImplTest, BrowserSideNavigationCommit) { DoReceiveData(); DoCompleteRequest(); - EXPECT_FALSE(bridge()->canceled()); + EXPECT_FALSE(dispatcher()->canceled()); EXPECT_EQ(kTestData, client()->received_data()); } |