diff options
author | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-18 17:43:45 +0000 |
---|---|---|
committer | rdsmith@chromium.org <rdsmith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-18 17:43:45 +0000 |
commit | 19420cc7453b524ec75a7f5e66141651cd7f7b76 (patch) | |
tree | aeae9b2d15642aa6df04340194e2fee625f877e0 /content | |
parent | 31770c077072c1d29f74ab105ba4246eee6c8993 (diff) | |
download | chromium_src-19420cc7453b524ec75a7f5e66141651cd7f7b76.zip chromium_src-19420cc7453b524ec75a7f5e66141651cd7f7b76.tar.gz chromium_src-19420cc7453b524ec75a7f5e66141651cd7f7b76.tar.bz2 |
Modified cancel and interrupt processing to avoid race with history.
Avoid racing with the history callback by unilaterally removing
DownloadItem from queues on cancel/interrupt. This keeps the
state<->queue correspondence cleaner, and avoids leaving things on
queues during shutdown. It might also fix 85408; we'll see :-}.
BUG=85408
TEST=
Review URL: http://codereview.chromium.org/7294013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92870 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/download/save_package.cc | 2 | ||||
-rw-r--r-- | content/browser/net/url_request_slow_download_job.cc | 51 | ||||
-rw-r--r-- | content/browser/net/url_request_slow_download_job.h | 17 |
3 files changed, 49 insertions, 21 deletions
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc index 6420268..0f05d9d 100644 --- a/content/browser/download/save_package.cc +++ b/content/browser/download/save_package.cc @@ -643,7 +643,7 @@ void SavePackage::Stop() { wait_state_ = FAILED; // Inform the DownloadItem we have canceled whole save page job. - download_->Cancel(false); + download_->Cancel(); } void SavePackage::CheckFinish() { diff --git a/content/browser/net/url_request_slow_download_job.cc b/content/browser/net/url_request_slow_download_job.cc index ef1370f..4cb152c 100644 --- a/content/browser/net/url_request_slow_download_job.cc +++ b/content/browser/net/url_request_slow_download_job.cc @@ -10,9 +10,11 @@ #include "base/string_util.h" #include "googleurl/src/gurl.h" #include "net/base/io_buffer.h" +#include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_status.h" const int kFirstDownloadSize = 1024 * 35; const int kSecondDownloadSize = 1024 * 10; @@ -23,9 +25,18 @@ const char URLRequestSlowDownloadJob::kKnownSizeUrl[] = "http://url.handled.by.slow.download/download-known-size"; const char URLRequestSlowDownloadJob::kFinishDownloadUrl[] = "http://url.handled.by.slow.download/download-finish"; +const char URLRequestSlowDownloadJob::kErrorFinishDownloadUrl[] = + "http://url.handled.by.slow.download/download-error"; std::vector<URLRequestSlowDownloadJob*> - URLRequestSlowDownloadJob::kPendingRequests; + URLRequestSlowDownloadJob::pending_requests_; + +// Return whether this is the finish or error URL. +static bool IsCompletionUrl(const GURL& url) { + if (url.spec() == URLRequestSlowDownloadJob::kFinishDownloadUrl) + return true; + return (url.spec() == URLRequestSlowDownloadJob::kErrorFinishDownloadUrl); +} void URLRequestSlowDownloadJob::Start() { MessageLoop::current()->PostTask( @@ -43,6 +54,8 @@ void URLRequestSlowDownloadJob::AddUrlHandler() { &URLRequestSlowDownloadJob::Factory); filter->AddUrlHandler(GURL(kFinishDownloadUrl), &URLRequestSlowDownloadJob::Factory); + filter->AddUrlHandler(GURL(kErrorFinishDownloadUrl), + &URLRequestSlowDownloadJob::Factory); } /*static */ @@ -50,19 +63,23 @@ net::URLRequestJob* URLRequestSlowDownloadJob::Factory( net::URLRequest* request, const std::string& scheme) { URLRequestSlowDownloadJob* job = new URLRequestSlowDownloadJob(request); - if (request->url().spec() != kFinishDownloadUrl) - URLRequestSlowDownloadJob::kPendingRequests.push_back(job); + if (!IsCompletionUrl(request->url())) + URLRequestSlowDownloadJob::pending_requests_.push_back(job); return job; } /* static */ -void URLRequestSlowDownloadJob::FinishPendingRequests() { +void URLRequestSlowDownloadJob::FinishPendingRequests(bool error) { typedef std::vector<URLRequestSlowDownloadJob*> JobList; - for (JobList::iterator it = kPendingRequests.begin(); it != - kPendingRequests.end(); ++it) { - (*it)->set_should_finish_download(); + for (JobList::iterator it = pending_requests_.begin(); it != + pending_requests_.end(); ++it) { + if (error) { + (*it)->set_should_error_download(); + } else { + (*it)->set_should_finish_download(); + } } - kPendingRequests.clear(); + pending_requests_.clear(); } URLRequestSlowDownloadJob::URLRequestSlowDownloadJob(net::URLRequest* request) @@ -70,19 +87,21 @@ URLRequestSlowDownloadJob::URLRequestSlowDownloadJob(net::URLRequest* request) first_download_size_remaining_(kFirstDownloadSize), should_finish_download_(false), should_send_second_chunk_(false), + should_error_download_(false), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} void URLRequestSlowDownloadJob::StartAsync() { - if (LowerCaseEqualsASCII(kFinishDownloadUrl, request_->url().spec().c_str())) - URLRequestSlowDownloadJob::FinishPendingRequests(); + if (IsCompletionUrl(request_->url())) { + URLRequestSlowDownloadJob::FinishPendingRequests( + request_->url().spec() == kErrorFinishDownloadUrl); + } NotifyHeadersComplete(); } bool URLRequestSlowDownloadJob::ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read) { - if (LowerCaseEqualsASCII(kFinishDownloadUrl, - request_->url().spec().c_str())) { + if (IsCompletionUrl(request_->url())) { *bytes_read = 0; return true; } @@ -132,6 +151,9 @@ void URLRequestSlowDownloadJob::CheckDoneStatus() { should_send_second_chunk_ = true; SetStatus(net::URLRequestStatus()); NotifyReadComplete(kSecondDownloadSize); + } else if (should_error_download_) { + NotifyDone( + net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); } else { MessageLoop::current()->PostDelayedTask( FROM_HERE, @@ -154,8 +176,7 @@ void URLRequestSlowDownloadJob::GetResponseInfoConst( net::HttpResponseInfo* info) const { // Send back mock headers. std::string raw_headers; - if (LowerCaseEqualsASCII(kFinishDownloadUrl, - request_->url().spec().c_str())) { + if (IsCompletionUrl(request_->url())) { raw_headers.append( "HTTP/1.1 200 OK\n" "Content-type: text/plain\n"); @@ -165,7 +186,7 @@ void URLRequestSlowDownloadJob::GetResponseInfoConst( "Content-type: application/octet-stream\n" "Cache-Control: max-age=0\n"); - if (LowerCaseEqualsASCII(kKnownSizeUrl, request_->url().spec().c_str())) { + if (request_->url().spec() == kKnownSizeUrl) { raw_headers.append(base::StringPrintf( "Content-Length: %d\n", kFirstDownloadSize + kSecondDownloadSize)); diff --git a/content/browser/net/url_request_slow_download_job.h b/content/browser/net/url_request_slow_download_job.h index cef2adc..0104213 100644 --- a/content/browser/net/url_request_slow_download_job.h +++ b/content/browser/net/url_request_slow_download_job.h @@ -1,9 +1,13 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. // This class simulates a slow download. This used in a UI test to test the // download manager. Requests to |kUnknownSizeUrl| and |kKnownSizeUrl| start -// downloads that pause after the first +// downloads that pause after the first chunk of data is delivered. +// A later request to |kFinishDownloadUrl| will finish these downloads. +// A later request to |kErrorFinishDownloadUrl| will cause these +// downloads to error with |net::ERR_FAILED|. +// TODO(rdsmith): Update to allow control of returned error. #ifndef CONTENT_BROWSER_NET_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_ #define CONTENT_BROWSER_NET_URL_REQUEST_SLOW_DOWNLOAD_JOB_H_ @@ -36,6 +40,7 @@ class URLRequestSlowDownloadJob : public net::URLRequestJob { static const char kUnknownSizeUrl[]; static const char kKnownSizeUrl[]; static const char kFinishDownloadUrl[]; + static const char kErrorFinishDownloadUrl[]; // Adds the testing URLs to the net::URLRequestFilter. static void AddUrlHandler(); @@ -46,17 +51,19 @@ class URLRequestSlowDownloadJob : public net::URLRequestJob { void GetResponseInfoConst(net::HttpResponseInfo* info) const; // Mark all pending requests to be finished. We keep track of pending - // requests in |kPendingRequests|. - static void FinishPendingRequests(); - static std::vector<URLRequestSlowDownloadJob*> kPendingRequests; + // requests in |pending_requests_|. + static void FinishPendingRequests(bool error); + static std::vector<URLRequestSlowDownloadJob*> pending_requests_; void StartAsync(); void set_should_finish_download() { should_finish_download_ = true; } + void set_should_error_download() { should_error_download_ = true; } int first_download_size_remaining_; bool should_finish_download_; bool should_send_second_chunk_; + bool should_error_download_; ScopedRunnableMethodFactory<URLRequestSlowDownloadJob> method_factory_; }; |