summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorbenjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-16 22:15:47 +0000
committerbenjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-16 22:15:47 +0000
commit8e3ae68c947f9d8f83162b02bc1fcd3e99011fdf (patch)
tree37ab778c03f2abf9bd656988de70ef5b6035ae54 /content
parent120655dce0bc56e15d64bc0d075f05e703dcf2cd (diff)
downloadchromium_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')
-rw-r--r--content/browser/download/download_manager.cc9
-rw-r--r--content/browser/download/download_resource_handler.cc14
-rw-r--r--content/browser/download/download_resource_handler.h8
-rw-r--r--content/browser/renderer_host/buffered_resource_handler.cc1
-rw-r--r--content/browser/renderer_host/render_message_filter.cc18
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host.cc28
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host.h20
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).