Index: content/browser/download/download_request_core.cc |
diff --git a/content/browser/download/download_resource_handler.cc b/content/browser/download/download_request_core.cc |
similarity index 65% |
copy from content/browser/download/download_resource_handler.cc |
copy to content/browser/download/download_request_core.cc |
index 2b6ac35783780818dc028d2abf139151c68607a5..d28a63ff0bb5663af76c83b1fd2817dffa0621cf 100644 |
--- a/content/browser/download/download_resource_handler.cc |
+++ b/content/browser/download/download_request_core.cc |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "content/browser/download/download_resource_handler.h" |
+#include "content/browser/download/download_request_core.h" |
#include <string> |
@@ -18,10 +18,7 @@ |
#include "content/browser/download/download_create_info.h" |
#include "content/browser/download/download_interrupt_reasons_impl.h" |
#include "content/browser/download/download_manager_impl.h" |
-#include "content/browser/download/download_request_handle.h" |
#include "content/browser/download/download_stats.h" |
-#include "content/browser/loader/resource_dispatcher_host_impl.h" |
-#include "content/browser/loader/resource_request_info_impl.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/download_interrupt_reasons.h" |
#include "content/public/browser/download_item.h" |
@@ -29,7 +26,6 @@ |
#include "content/public/browser/navigation_entry.h" |
#include "content/public/browser/power_save_blocker.h" |
#include "content/public/browser/web_contents.h" |
-#include "content/public/common/resource_response.h" |
#include "net/base/io_buffer.h" |
#include "net/base/net_errors.h" |
#include "net/http/http_response_headers.h" |
@@ -38,11 +34,6 @@ |
namespace content { |
-struct DownloadResourceHandler::DownloadTabInfo { |
- GURL tab_url; |
- GURL tab_referrer_url; |
-}; |
- |
namespace { |
void CallStartedCBOnUIThread( |
@@ -57,20 +48,19 @@ void CallStartedCBOnUIThread( |
} |
// Static function in order to prevent any accidental accesses to |
-// DownloadResourceHandler members from the UI thread. |
+// DownloadRequestCore members from the UI thread. |
static void StartOnUIThread( |
scoped_ptr<DownloadCreateInfo> info, |
- scoped_ptr<DownloadResourceHandler::DownloadTabInfo> tab_info, |
scoped_ptr<ByteStreamReader> stream, |
+ base::WeakPtr<DownloadManager> download_manager, |
const DownloadUrlParameters::OnStartedCallback& started_cb) { |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- DownloadManager* download_manager = info->request_handle.GetDownloadManager(); |
if (!download_manager) { |
- // NULL in unittests or if the page closed right after starting the |
+ // nullptr in unittests or if the page closed right after starting the |
// download. |
if (!started_cb.is_null()) |
- started_cb.Run(NULL, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
+ started_cb.Run(nullptr, DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |
// |stream| gets deleted on non-FILE thread, but it's ok since |
// we're not using stream_writer_ yet. |
@@ -78,81 +68,54 @@ static void StartOnUIThread( |
return; |
} |
- info->tab_url = tab_info->tab_url; |
- info->tab_referrer_url = tab_info->tab_referrer_url; |
- |
download_manager->StartDownload(info.Pass(), stream.Pass(), started_cb); |
} |
-void InitializeDownloadTabInfoOnUIThread( |
- const DownloadRequestHandle& request_handle, |
- DownloadResourceHandler::DownloadTabInfo* tab_info) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- |
- WebContents* web_contents = request_handle.GetWebContents(); |
- if (web_contents) { |
- NavigationEntry* entry = web_contents->GetController().GetVisibleEntry(); |
- if (entry) { |
- tab_info->tab_url = entry->GetURL(); |
- tab_info->tab_referrer_url = entry->GetReferrer().url; |
- } |
- } |
-} |
- |
-void DeleteOnUIThread( |
- scoped_ptr<DownloadResourceHandler::DownloadTabInfo> tab_info) {} |
- |
} // namespace |
-const int DownloadResourceHandler::kDownloadByteStreamSize = 100 * 1024; |
+const int DownloadRequestCore::kDownloadByteStreamSize = 100 * 1024; |
-DownloadResourceHandler::DownloadResourceHandler( |
+DownloadRequestCore::DownloadRequestCore( |
uint32 id, |
net::URLRequest* request, |
const DownloadUrlParameters::OnStartedCallback& started_cb, |
- scoped_ptr<DownloadSaveInfo> save_info) |
- : ResourceHandler(request), |
+ scoped_ptr<DownloadSaveInfo> save_info, |
+ base::WeakPtr<DownloadManagerImpl> download_manager) |
+ : request_(request), |
download_id_(id), |
started_cb_(started_cb), |
save_info_(save_info.Pass()), |
- tab_info_(new DownloadTabInfo()), |
last_buffer_size_(0), |
bytes_read_(0), |
pause_count_(0), |
was_deferred_(false), |
- on_response_started_called_(false) { |
+ on_response_started_called_(false), |
+ download_manager_(download_manager) { |
RecordDownloadCount(UNTHROTTLED_COUNT); |
- // Do UI thread initialization for tab_info_ asap after |
- // DownloadResourceHandler creation since the tab could be navigated |
- // before StartOnUIThread gets called. This is safe because deletion |
- // will occur via PostTask() as well, which will serialized behind this |
- // PostTask() |
- const ResourceRequestInfoImpl* request_info = GetRequestInfo(); |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&InitializeDownloadTabInfoOnUIThread, |
- DownloadRequestHandle(AsWeakPtr(), request_info->GetChildID(), |
- request_info->GetRouteID(), |
- request_info->GetRequestID(), |
- request_info->frame_tree_node_id()), |
- tab_info_.get())); |
power_save_blocker_ = PowerSaveBlocker::Create( |
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, |
PowerSaveBlocker::kReasonOther, "Download in progress"); |
} |
-bool DownloadResourceHandler::OnRequestRedirected( |
- const net::RedirectInfo& redirect_info, |
- ResourceResponse* response, |
- bool* defer) { |
- return true; |
+DownloadRequestCore::~DownloadRequestCore() { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ // This won't do anything if the callback was called before. |
+ // If it goes through, it will likely be because OnWillStart() returned |
+ // false somewhere in the chain of resource handlers. |
+ CallStartedCB(nullptr, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
+ |
+ // Remove output stream callback if a stream exists. |
+ if (stream_writer_) |
+ stream_writer_->RegisterCallback(base::Closure()); |
+ |
+ UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", |
+ base::TimeTicks::Now() - download_start_time_); |
} |
// Send the download creation information to the download thread. |
-bool DownloadResourceHandler::OnResponseStarted( |
- ResourceResponse* response, |
- bool* defer) { |
+bool DownloadRequestCore::OnResponseStarted() { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
// There can be only one (call) |
DCHECK(!on_response_started_called_); |
@@ -171,19 +134,14 @@ bool DownloadResourceHandler::OnResponseStarted( |
// If the content-length header is not present (or contains something other |
// than numbers), the incoming content_length is -1 (unknown size). |
// Set the content length to 0 to indicate unknown size to DownloadManager. |
- int64 content_length = |
- response->head.content_length > 0 ? response->head.content_length : 0; |
- |
- const ResourceRequestInfoImpl* request_info = GetRequestInfo(); |
+ int64 content_length = request()->GetExpectedContentSize() > 0 |
+ ? request()->GetExpectedContentSize() |
+ : 0; |
// Deleted in DownloadManager. |
- scoped_ptr<DownloadCreateInfo> info( |
- new DownloadCreateInfo(base::Time::Now(), |
- content_length, |
- request()->net_log(), |
- request_info->HasUserGesture(), |
- request_info->GetPageTransition(), |
- save_info_.Pass())); |
+ scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo( |
+ base::Time::Now(), content_length, request()->net_log(), false, |
+ ui::PAGE_TRANSITION_LINK, save_info_.Pass())); |
// Create the ByteStream for sending data to the download sink. |
scoped_ptr<ByteStreamReader> stream_reader; |
@@ -192,12 +150,14 @@ bool DownloadResourceHandler::OnResponseStarted( |
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), |
kDownloadByteStreamSize, &stream_writer_, &stream_reader); |
stream_writer_->RegisterCallback( |
- base::Bind(&DownloadResourceHandler::ResumeRequest, AsWeakPtr())); |
+ base::Bind(&DownloadRequestCore::ResumeRequest, AsWeakPtr())); |
info->download_id = download_id_; |
info->url_chain = request()->url_chain(); |
info->referrer_url = GURL(request()->referrer()); |
- info->mime_type = response->head.mime_type; |
+ string mime_type; |
+ request()->GetMimeType(&mime_type); |
+ info->mime_type = mime_type; |
info->remote_address = request()->GetSocketAddress().host(); |
if (request()->response_headers()) { |
// Grab the first content-disposition header. There may be more than one, |
@@ -209,25 +169,21 @@ bool DownloadResourceHandler::OnResponseStarted( |
RecordDownloadMimeType(info->mime_type); |
RecordDownloadContentDisposition(info->content_disposition); |
- info->request_handle = DownloadRequestHandle( |
- AsWeakPtr(), request_info->GetChildID(), request_info->GetRouteID(), |
- request_info->GetRequestID(), request_info->frame_tree_node_id()); |
- |
// Get the last modified time and etag. |
const net::HttpResponseHeaders* headers = request()->response_headers(); |
if (headers) { |
if (headers->HasStrongValidators()) { |
// If we don't have strong validators as per RFC 2616 section 13.3.3, then |
// we neither store nor use them for range requests. |
- if (!headers->EnumerateHeader(NULL, "Last-Modified", |
+ if (!headers->EnumerateHeader(nullptr, "Last-Modified", |
&info->last_modified)) |
info->last_modified.clear(); |
- if (!headers->EnumerateHeader(NULL, "ETag", &info->etag)) |
+ if (!headers->EnumerateHeader(nullptr, "ETag", &info->etag)) |
info->etag.clear(); |
} |
int status = headers->response_code(); |
- if (2 == status / 100 && status != net::HTTP_PARTIAL_CONTENT) { |
+ if (2 == status / 100 && status != net::HTTP_PARTIAL_CONTENT) { |
// Success & not range response; if we asked for a range, we didn't |
// get it--reset the file pointers to reflect that. |
info->save_info->offset = 0; |
@@ -248,10 +204,8 @@ bool DownloadResourceHandler::OnResponseStarted( |
BrowserThread::PostTask( |
BrowserThread::UI, FROM_HERE, |
- base::Bind(&StartOnUIThread, |
- base::Passed(&info), |
- base::Passed(&tab_info_), |
- base::Passed(&stream_reader), |
+ base::Bind(&StartOnUIThread, base::Passed(&info), |
+ base::Passed(&stream_reader), download_manager_, |
// Pass to StartOnUIThread so that variable |
// access is always on IO thread but function |
// is called on UI thread. |
@@ -262,34 +216,23 @@ bool DownloadResourceHandler::OnResponseStarted( |
return true; |
} |
-void DownloadResourceHandler::CallStartedCB( |
+void DownloadRequestCore::CallStartedCB( |
DownloadItem* item, |
DownloadInterruptReason interrupt_reason) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
if (started_cb_.is_null()) |
return; |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- base::Bind( |
- &CallStartedCBOnUIThread, started_cb_, item, interrupt_reason)); |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(&CallStartedCBOnUIThread, started_cb_, |
+ item, interrupt_reason)); |
started_cb_.Reset(); |
} |
-bool DownloadResourceHandler::OnWillStart(const GURL& url, bool* defer) { |
- return true; |
-} |
- |
-bool DownloadResourceHandler::OnBeforeNetworkStart(const GURL& url, |
- bool* defer) { |
- return true; |
-} |
- |
// Create a new buffer, which will be handed to the download thread for file |
// writing and deletion. |
-bool DownloadResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
- int* buf_size, |
- int min_size) { |
+bool DownloadRequestCore::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
+ int* buf_size, |
+ int min_size) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
DCHECK(buf && buf_size); |
DCHECK(!read_buffer_.get()); |
@@ -302,7 +245,7 @@ bool DownloadResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
} |
// Pass the buffer to the download file writer. |
-bool DownloadResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
+bool DownloadRequestCore::OnReadCompleted(int bytes_read, bool* defer) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
DCHECK(read_buffer_.get()); |
@@ -314,8 +257,8 @@ bool DownloadResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
// divide-by-zero error and still record a very high potential bandwidth. |
seconds_since_last_read = 0.00001; |
- double actual_bandwidth = (bytes_read)/seconds_since_last_read; |
- double potential_bandwidth = last_buffer_size_/seconds_since_last_read; |
+ double actual_bandwidth = (bytes_read) / seconds_since_last_read; |
+ double potential_bandwidth = last_buffer_size_ / seconds_since_last_read; |
RecordBandwidth(actual_bandwidth, potential_bandwidth); |
} |
last_read_time_ = now; |
@@ -341,10 +284,8 @@ bool DownloadResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { |
return true; |
} |
-void DownloadResourceHandler::OnResponseCompleted( |
- const net::URLRequestStatus& status, |
- const std::string& security_info, |
- bool* defer) { |
+void DownloadRequestCore::OnResponseCompleted( |
+ const net::URLRequestStatus& status) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
int response_code = status.is_success() ? request()->GetResponseCode() : 0; |
DVLOG(20) << __FUNCTION__ << "()" << DebugString() |
@@ -370,9 +311,8 @@ void DownloadResourceHandler::OnResponseCompleted( |
error_code == net::ERR_INCOMPLETE_CHUNKED_ENCODING) { |
error_code = net::OK; |
} |
- DownloadInterruptReason reason = |
- ConvertNetErrorToInterruptReason( |
- error_code, DOWNLOAD_INTERRUPT_FROM_NETWORK); |
+ DownloadInterruptReason reason = ConvertNetErrorToInterruptReason( |
+ error_code, DOWNLOAD_INTERRUPT_FROM_NETWORK); |
if (status.status() == net::URLRequestStatus::CANCELED && |
status.error() == net::ERR_ABORTED) { |
@@ -390,12 +330,11 @@ void DownloadResourceHandler::OnResponseCompleted( |
reason = DOWNLOAD_INTERRUPT_REASON_USER_CANCELED; |
} |
- if (status.is_success() && |
- reason == DOWNLOAD_INTERRUPT_REASON_NONE && |
+ if (status.is_success() && reason == DOWNLOAD_INTERRUPT_REASON_NONE && |
request()->response_headers()) { |
// Handle server's response codes. |
- switch(response_code) { |
- case -1: // Non-HTTP request. |
+ switch (response_code) { |
+ case -1: // Non-HTTP request. |
case net::HTTP_OK: |
case net::HTTP_CREATED: |
case net::HTTP_ACCEPTED: |
@@ -426,7 +365,7 @@ void DownloadResourceHandler::OnResponseCompleted( |
// Server forbids access to this resource. |
reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN; |
break; |
- default: // All other errors. |
+ default: // All other errors. |
// Redirection and informational codes should have been handled earlier |
// in the stack. |
DCHECK_NE(3, response_code / 100); |
@@ -439,8 +378,8 @@ void DownloadResourceHandler::OnResponseCompleted( |
std::string accept_ranges; |
bool has_strong_validators = false; |
if (request()->response_headers()) { |
- request()->response_headers()->EnumerateHeader( |
- NULL, "Accept-Ranges", &accept_ranges); |
+ request()->response_headers()->EnumerateHeader(nullptr, "Accept-Ranges", |
+ &accept_ranges); |
has_strong_validators = |
request()->response_headers()->HasStrongValidators(); |
} |
@@ -448,7 +387,7 @@ void DownloadResourceHandler::OnResponseCompleted( |
RecordNetworkBlockage(base::TimeTicks::Now() - download_start_time_, |
total_pause_time_); |
- CallStartedCB(NULL, reason); |
+ CallStartedCB(nullptr, reason); |
// Send the info down the stream. Conditional is in case we get |
// OnResponseCompleted without OnResponseStarted. |
@@ -463,20 +402,16 @@ void DownloadResourceHandler::OnResponseCompleted( |
} |
stream_writer_.reset(); // We no longer need the stream. |
- read_buffer_ = NULL; |
-} |
- |
-void DownloadResourceHandler::OnDataDownloaded(int bytes_downloaded) { |
- NOTREACHED(); |
+ read_buffer_ = nullptr; |
} |
-void DownloadResourceHandler::PauseRequest() { |
+void DownloadRequestCore::PauseRequest() { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
++pause_count_; |
} |
-void DownloadResourceHandler::ResumeRequest() { |
+void DownloadRequestCore::ResumeRequest() { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
DCHECK_LT(0, pause_count_); |
@@ -493,59 +428,16 @@ void DownloadResourceHandler::ResumeRequest() { |
last_stream_pause_time_ = base::TimeTicks(); |
} |
- controller()->Resume(); |
-} |
- |
-void DownloadResourceHandler::CancelRequest() { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- const ResourceRequestInfoImpl* info = GetRequestInfo(); |
- ResourceDispatcherHostImpl::Get()->CancelRequest( |
- info->GetChildID(), |
- info->GetRequestID()); |
- // This object has been deleted. |
-} |
- |
-std::string DownloadResourceHandler::DebugString() const { |
- const ResourceRequestInfoImpl* info = GetRequestInfo(); |
- return base::StringPrintf("{" |
- " url_ = " "\"%s\"" |
- " info = {" |
- " child_id = " "%d" |
- " request_id = " "%d" |
- " route_id = " "%d" |
- " }" |
- " }", |
- request() ? |
- request()->url().spec().c_str() : |
- "<NULL request>", |
- info->GetChildID(), |
- info->GetRequestID(), |
- info->GetRouteID()); |
+ downloader_->ResumeReading(); |
} |
-DownloadResourceHandler::~DownloadResourceHandler() { |
- DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- |
- // This won't do anything if the callback was called before. |
- // If it goes through, it will likely be because OnWillStart() returned |
- // false somewhere in the chain of resource handlers. |
- CallStartedCB(NULL, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
- |
- // Remove output stream callback if a stream exists. |
- if (stream_writer_) |
- stream_writer_->RegisterCallback(base::Closure()); |
- |
- // tab_info_ must be destroyed on UI thread, since |
- // InitializeDownloadTabInfoOnUIThread might still be using it. |
- if (tab_info_.get()) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&DeleteOnUIThread, base::Passed(&tab_info_))); |
- } |
- |
- UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", |
- base::TimeTicks::Now() - download_start_time_); |
+std::string DownloadRequestCore::DebugString() const { |
+ return base::StringPrintf( |
+ "{" |
+ " url_ = " |
+ "\"%s\"" |
+ " }", |
+ request() ? request()->url().spec().c_str() : "<NULL request>"); |
} |
} // namespace content |