diff options
author | benjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 22:15:47 +0000 |
---|---|---|
committer | benjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 22:15:47 +0000 |
commit | 8e3ae68c947f9d8f83162b02bc1fcd3e99011fdf (patch) | |
tree | 37ab778c03f2abf9bd656988de70ef5b6035ae54 /content | |
parent | 120655dce0bc56e15d64bc0d075f05e703dcf2cd (diff) | |
download | chromium_src-8e3ae68c947f9d8f83162b02bc1fcd3e99011fdf.zip chromium_src-8e3ae68c947f9d8f83162b02bc1fcd3e99011fdf.tar.gz chromium_src-8e3ae68c947f9d8f83162b02bc1fcd3e99011fdf.tar.bz2 |
chrome.experimental.downloads.download() implementation
Ownership:
(Done) Asanka: content/browser/download/*
(Done) Brett: webkit/plugins/ppapi/ppb_url_request_info_impl.cc
(Done) Chris: net/*
(Done) John: content/browser/renderer_host/*
(Done) Mihai: extensions/*
Review URL: http://codereview.chromium.org/7647028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101583 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
7 files changed, 73 insertions, 25 deletions
diff --git a/content/browser/download/download_manager.cc b/content/browser/download/download_manager.cc index 06bf42f5..3a2a7ee 100644 --- a/content/browser/download/download_manager.cc +++ b/content/browser/download/download_manager.cc @@ -39,8 +39,15 @@ void BeginDownload( int render_process_id, int render_view_id, const content::ResourceContext* context) { + net::URLRequest* request = new net::URLRequest(url, resource_dispatcher_host); + request->set_referrer(referrer.spec()); resource_dispatcher_host->BeginDownload( - url, referrer, save_info, true, render_process_id, render_view_id, + request, + save_info, + true, + DownloadResourceHandler::OnStartedCallback(), + render_process_id, + render_view_id, *context); } diff --git a/content/browser/download/download_resource_handler.cc b/content/browser/download/download_resource_handler.cc index 09c0a97..d34615f 100644 --- a/content/browser/download/download_resource_handler.cc +++ b/content/browser/download/download_resource_handler.cc @@ -34,6 +34,7 @@ DownloadResourceHandler::DownloadResourceHandler( DownloadFileManager* download_file_manager, net::URLRequest* request, bool save_as, + const DownloadResourceHandler::OnStartedCallback& started_cb, const DownloadSaveInfo& save_info) : download_id_(-1), global_id_(render_process_host_id, request_id), @@ -42,6 +43,7 @@ DownloadResourceHandler::DownloadResourceHandler( download_file_manager_(download_file_manager), request_(request), save_as_(save_as), + started_cb_(started_cb), save_info_(save_info), buffer_(new DownloadBuffer), rdh_(rdh), @@ -97,6 +99,8 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, // TODO(ahendrickson) -- Get the last modified time and etag, so we can // resume downloading. + CallStartedCB(net::OK); + std::string content_type_header; if (!response->response_head.headers || !response->response_head.headers->GetMimeType(&content_type_header)) @@ -119,6 +123,14 @@ bool DownloadResourceHandler::OnResponseStarted(int request_id, return true; } +void DownloadResourceHandler::CallStartedCB(net::Error error) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (started_cb_.is_null()) + return; + started_cb_.Run(download_id_, error); + started_cb_.Reset(); +} + bool DownloadResourceHandler::OnWillStart(int request_id, const GURL& url, bool* defer) { @@ -177,6 +189,8 @@ bool DownloadResourceHandler::OnResponseCompleted( << " status.error() = " << status.error(); net::Error error_code = (status.status() == net::URLRequestStatus::FAILED) ? static_cast<net::Error>(status.error()) : net::OK; + if (download_id_ == -1) + CallStartedCB(error_code); // We transfer ownership to |DownloadFileManager| to delete |buffer_|, // so that any functions queued up on the FILE thread are executed // before deletion. diff --git a/content/browser/download/download_resource_handler.h b/content/browser/download/download_resource_handler.h index b4cdbd6..81d288d 100644 --- a/content/browser/download/download_resource_handler.h +++ b/content/browser/download/download_resource_handler.h @@ -8,6 +8,7 @@ #include <string> +#include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/timer.h" #include "content/browser/download/download_file.h" @@ -25,6 +26,10 @@ class URLRequest; // Forwards data to the download thread. class DownloadResourceHandler : public ResourceHandler { public: + typedef base::Callback<void(int/*download_id*/, net::Error)> + OnStartedCallback; + + // started_cb will be called exactly once. DownloadResourceHandler(ResourceDispatcherHost* rdh, int render_process_host_id, int render_view_id, @@ -33,6 +38,7 @@ class DownloadResourceHandler : public ResourceHandler { DownloadFileManager* download_file_manager, net::URLRequest* request, bool save_as, + const OnStartedCallback& started_cb, const DownloadSaveInfo& save_info); virtual bool OnUploadProgress(int request_id, uint64 position, uint64 size); @@ -74,6 +80,7 @@ class DownloadResourceHandler : public ResourceHandler { virtual ~DownloadResourceHandler(); void StartPauseTimer(); + void CallStartedCB(net::Error error); int download_id_; GlobalRequestID global_id_; @@ -84,6 +91,7 @@ class DownloadResourceHandler : public ResourceHandler { DownloadFileManager* download_file_manager_; net::URLRequest* request_; bool save_as_; // Request was initiated via "Save As" by the user. + OnStartedCallback started_cb_; DownloadSaveInfo save_info_; scoped_ptr<DownloadBuffer> buffer_; ResourceDispatcherHost* rdh_; diff --git a/content/browser/renderer_host/buffered_resource_handler.cc b/content/browser/renderer_host/buffered_resource_handler.cc index 026ce66..f40d626 100644 --- a/content/browser/renderer_host/buffered_resource_handler.cc +++ b/content/browser/renderer_host/buffered_resource_handler.cc @@ -318,6 +318,7 @@ bool BufferedResourceHandler::CompleteResponseStarted(int request_id, host_->download_file_manager(), request_, false, + DownloadResourceHandler::OnStartedCallback(), DownloadSaveInfo())); if (host_->delegate()) { diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 3540f2a..25eb0d2 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -583,13 +583,17 @@ void RenderMessageFilter::OnDownloadUrl(const IPC::Message& message, bool prompt_for_save_location = false; DownloadSaveInfo save_info; save_info.suggested_name = suggested_name; - resource_dispatcher_host_->BeginDownload(url, - referrer, - save_info, - prompt_for_save_location, - render_process_id_, - message.routing_id(), - resource_context_); + net::URLRequest* request = new net::URLRequest( + url, resource_dispatcher_host_); + request->set_referrer(referrer.spec()); + resource_dispatcher_host_->BeginDownload( + request, + save_info, + prompt_for_save_location, + DownloadResourceHandler::OnStartedCallback(), + render_process_id_, + message.routing_id(), + resource_context_); download_stats::RecordDownloadCount( download_stats::INITIATED_BY_RENDERER_COUNT); } diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc index 3de9faa..3813785 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.cc +++ b/content/browser/renderer_host/resource_dispatcher_host.cc @@ -794,26 +794,36 @@ void ResourceDispatcherHost::OnDidLoadResourceFromMemoryCache( // We are explicitly forcing the download of 'url'. void ResourceDispatcherHost::BeginDownload( - const GURL& url, - const GURL& referrer, + net::URLRequest* request, const DownloadSaveInfo& save_info, bool prompt_for_save_location, + const DownloadResourceHandler::OnStartedCallback& started_cb, int child_id, int route_id, const content::ResourceContext& context) { - if (is_shutdown_) + static const int kInvalidDownloadId = -1; + scoped_ptr<net::URLRequest> delete_request(request); + // If DownloadResourceHandler is not begun, then started_cb must be called + // here in order to satisfy its semantics. + if (is_shutdown_) { + if (!started_cb.is_null()) + started_cb.Run(kInvalidDownloadId, net::ERR_INSUFFICIENT_RESOURCES); + // Time and RDH are resources that are running out. return; + } + const GURL& url = request->original_url(); + request->set_referrer(MaybeStripReferrer(GURL(request->referrer())).spec()); // Check if the renderer is permitted to request the requested URL. if (!ChildProcessSecurityPolicy::GetInstance()-> CanRequestURL(child_id, url)) { VLOG(1) << "Denied unauthorized download request for " << url.possibly_invalid_spec(); + if (!started_cb.is_null()) + started_cb.Run(kInvalidDownloadId, net::ERR_ACCESS_DENIED); return; } - net::URLRequest* request = new net::URLRequest(url, this); - request_id_--; scoped_refptr<ResourceHandler> handler( @@ -825,6 +835,7 @@ void ResourceDispatcherHost::BeginDownload( download_file_manager_.get(), request, prompt_for_save_location, + started_cb, save_info)); if (delegate_) { @@ -834,15 +845,14 @@ void ResourceDispatcherHost::BeginDownload( } const net::URLRequestContext* request_context = context.request_context(); - if (!request_context->job_factory()->IsHandledURL(url)) { VLOG(1) << "Download request for unsupported protocol: " << url.possibly_invalid_spec(); + if (!started_cb.is_null()) + started_cb.Run(kInvalidDownloadId, net::ERR_ACCESS_DENIED); return; } - request->set_method("GET"); - request->set_referrer(MaybeStripReferrer(referrer).spec()); request->set_context(context.request_context()); request->set_load_flags(request->load_flags() | net::LOAD_IS_DOWNLOAD); @@ -851,7 +861,7 @@ void ResourceDispatcherHost::BeginDownload( CreateRequestInfo(handler, child_id, route_id, true, context); SetRequestInfo(request, extra_info); // Request takes ownership. - BeginRequestInternal(request); + BeginRequestInternal(delete_request.release()); } // This function is only used for saving feature. diff --git a/content/browser/renderer_host/resource_dispatcher_host.h b/content/browser/renderer_host/resource_dispatcher_host.h index 2bbde89..4626674 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.h +++ b/content/browser/renderer_host/resource_dispatcher_host.h @@ -22,6 +22,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "base/timer.h" +#include "content/browser/download/download_resource_handler.h" #include "content/browser/renderer_host/resource_queue.h" #include "content/common/child_process_info.h" #include "content/common/content_export.h" @@ -79,14 +80,17 @@ class CONTENT_EXPORT ResourceDispatcherHost : public net::URLRequest::Delegate { bool* message_was_ok); // Initiates a download by explicit request of the renderer, e.g. due to - // alt-clicking a link. - void BeginDownload(const GURL& url, - const GURL& referrer, - const DownloadSaveInfo& save_info, - bool prompt_for_save_location, - int process_unique_id, - int route_id, - const content::ResourceContext& context); + // alt-clicking a link. If |request| is malformed or not permitted or the RDH + // is shutting down, then |started_cb| will be called immediately. There is no + // situation in which |started_cb| will never be called. + void BeginDownload( + net::URLRequest* request, // ownership is taken + const DownloadSaveInfo& save_info, + bool prompt_for_save_location, + const DownloadResourceHandler::OnStartedCallback& started_cb, + int child_id, + int route_id, + const content::ResourceContext& context); // Initiates a save file from the browser process (as opposed to a resource // request from the renderer or another child process). |