Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: content/browser/download/url_downloader.cc

Issue 1533583002: [Downloads] Factor out request handling logic between DRH and UD. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments and change .Pass() -> std::move(...) per PRESUBMIT check Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/download/url_downloader.h ('k') | content/test/data/download/gzip-content.gz » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/url_downloader.h" 5 #include "content/browser/download/url_downloader.h"
6 6
7 #include "base/callback_helpers.h"
7 #include "base/location.h" 8 #include "base/location.h"
8 #include "base/thread_task_runner_handle.h" 9 #include "base/macros.h"
9 #include "content/browser/appcache/appcache_interceptor.h" 10 #include "base/threading/sequenced_task_runner_handle.h"
11 #include "content/browser/byte_stream.h"
12 #include "content/browser/download/download_create_info.h"
10 #include "content/browser/download/download_manager_impl.h" 13 #include "content/browser/download/download_manager_impl.h"
11 #include "content/browser/service_worker/service_worker_request_handler.h" 14 #include "content/browser/download/download_request_handle.h"
12 #include "content/browser/ssl/ssl_policy.h" 15 #include "content/public/browser/browser_thread.h"
13 #include "content/common/ssl_status_serialization.h" 16 #include "content/public/browser/download_interrupt_reasons.h"
14 #include "content/public/browser/cert_store.h"
15 #include "content/public/browser/download_save_info.h" 17 #include "content/public/browser/download_save_info.h"
16 #include "content/public/browser/signed_certificate_timestamp_store.h"
17 #include "content/public/common/process_type.h"
18 #include "content/public/common/security_style.h"
19 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
20 #include "net/base/load_flags.h" 19 #include "net/base/load_flags.h"
21 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
22 #include "net/http/http_response_headers.h" 21 #include "net/http/http_response_headers.h"
23 #include "net/http/http_status_code.h" 22 #include "net/http/http_status_code.h"
24 #include "ui/base/page_transition_types.h" 23 #include "ui/base/page_transition_types.h"
25 24
26 namespace content { 25 namespace content {
27 26
27 class UrlDownloader::RequestHandle : public DownloadRequestHandleInterface {
28 public:
29 RequestHandle(base::WeakPtr<UrlDownloader> downloader,
30 base::WeakPtr<DownloadManagerImpl> download_manager_impl,
31 scoped_refptr<base::SequencedTaskRunner> downloader_task_runner)
32 : downloader_(downloader),
33 download_manager_impl_(download_manager_impl),
34 downloader_task_runner_(downloader_task_runner) {}
35 RequestHandle(RequestHandle&& other)
36 : downloader_(std::move(other.downloader_)),
37 download_manager_impl_(std::move(other.download_manager_impl_)),
38 downloader_task_runner_(std::move(other.downloader_task_runner_)) {}
39 RequestHandle& operator=(RequestHandle&& other) {
40 downloader_ = std::move(other.downloader_);
41 download_manager_impl_ = std::move(other.download_manager_impl_);
42 downloader_task_runner_ = std::move(other.downloader_task_runner_);
43 return *this;
44 }
45
46 // DownloadRequestHandleInterface
47 WebContents* GetWebContents() const override { return nullptr; }
48 DownloadManager* GetDownloadManager() const override {
49 return download_manager_impl_ ? download_manager_impl_.get() : nullptr;
50 }
51 void PauseRequest() const override {
52 downloader_task_runner_->PostTask(
53 FROM_HERE, base::Bind(&UrlDownloader::PauseRequest, downloader_));
54 }
55 void ResumeRequest() const override {
56 downloader_task_runner_->PostTask(
57 FROM_HERE, base::Bind(&UrlDownloader::ResumeRequest, downloader_));
58 }
59 void CancelRequest() const override {
60 downloader_task_runner_->PostTask(
61 FROM_HERE, base::Bind(&UrlDownloader::CancelRequest, downloader_));
62 }
63 std::string DebugString() const override { return std::string(); }
64
65 private:
66 base::WeakPtr<UrlDownloader> downloader_;
67 base::WeakPtr<DownloadManagerImpl> download_manager_impl_;
68 scoped_refptr<base::SequencedTaskRunner> downloader_task_runner_;
69
70 DISALLOW_COPY_AND_ASSIGN(RequestHandle);
71 };
72
28 // static 73 // static
29 scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload( 74 scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload(
30 base::WeakPtr<DownloadManagerImpl> download_manager, 75 base::WeakPtr<DownloadManagerImpl> download_manager,
31 scoped_ptr<net::URLRequest> request, 76 scoped_ptr<net::URLRequest> request,
32 const Referrer& referrer, 77 const Referrer& referrer,
33 bool is_content_initiated,
34 bool prefer_cache, 78 bool prefer_cache,
35 bool do_not_prompt_for_login,
36 scoped_ptr<DownloadSaveInfo> save_info, 79 scoped_ptr<DownloadSaveInfo> save_info,
37 uint32 download_id, 80 uint32 download_id,
38 const DownloadUrlParameters::OnStartedCallback& started_callback) { 81 const DownloadUrlParameters::OnStartedCallback& started_callback) {
39 if (!referrer.url.is_valid()) 82 if (!referrer.url.is_valid())
40 request->SetReferrer(std::string()); 83 request->SetReferrer(std::string());
41 else 84 else
42 request->SetReferrer(referrer.url.spec()); 85 request->SetReferrer(referrer.url.spec());
43 86
44 int extra_load_flags = net::LOAD_NORMAL; 87 int extra_load_flags = net::LOAD_NORMAL;
45 if (prefer_cache) { 88 if (prefer_cache) {
46 // If there is upload data attached, only retrieve from cache because there 89 // If there is upload data attached, only retrieve from cache because there
47 // is no current mechanism to prompt the user for their consent for a 90 // is no current mechanism to prompt the user for their consent for a
48 // re-post. For GETs, try to retrieve data from the cache and skip 91 // re-post. For GETs, try to retrieve data from the cache and skip
49 // validating the entry if present. 92 // validating the entry if present.
50 if (request->get_upload() != NULL) 93 if (request->get_upload() != NULL)
51 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE; 94 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE;
52 else 95 else
53 extra_load_flags |= net::LOAD_PREFERRING_CACHE; 96 extra_load_flags |= net::LOAD_PREFERRING_CACHE;
54 } else { 97 } else {
55 extra_load_flags |= net::LOAD_DISABLE_CACHE; 98 extra_load_flags |= net::LOAD_DISABLE_CACHE;
56 } 99 }
57 request->SetLoadFlags(request->load_flags() | extra_load_flags); 100 request->SetLoadFlags(request->load_flags() | extra_load_flags);
58 101
59 if (request->url().SchemeIs(url::kBlobScheme)) 102 if (request->url().SchemeIs(url::kBlobScheme))
60 return nullptr; 103 return nullptr;
61 104
62 scoped_ptr<DownloadRequestCore> handler(
63 new DownloadRequestCore(download_id, request.get(), started_callback,
64 save_info.Pass(), download_manager));
65
66 // From this point forward, the |UrlDownloader| is responsible for 105 // From this point forward, the |UrlDownloader| is responsible for
67 // |started_callback|. 106 // |started_callback|.
68 scoped_ptr<UrlDownloader> downloader( 107 scoped_ptr<UrlDownloader> downloader(
69 new UrlDownloader(request.Pass(), handler.Pass(), download_manager)); 108 new UrlDownloader(std::move(request), download_manager,
70 109 std::move(save_info), download_id, started_callback));
71 downloader->Start(); 110 downloader->Start();
72 111
73 return downloader; 112 return downloader;
74 } 113 }
75 114
76 UrlDownloader::UrlDownloader(scoped_ptr<net::URLRequest> request, 115 UrlDownloader::UrlDownloader(
77 scoped_ptr<DownloadRequestCore> handler, 116 scoped_ptr<net::URLRequest> request,
78 base::WeakPtr<DownloadManagerImpl> manager) 117 base::WeakPtr<DownloadManagerImpl> manager,
79 : request_(request.Pass()), 118 scoped_ptr<DownloadSaveInfo> save_info,
80 handler_(handler.Pass()), 119 uint32 download_id,
120 const DownloadUrlParameters::OnStartedCallback& on_started_callback)
121 : request_(std::move(request)),
81 manager_(manager), 122 manager_(manager),
82 weak_ptr_factory_(this) { 123 download_id_(download_id),
83 handler_->set_downloader(this); 124 on_started_callback_(on_started_callback),
84 } 125 handler_(
126 request_.get(),
127 std::move(save_info),
128 base::Bind(&UrlDownloader::ResumeReading, base::Unretained(this))),
129 weak_ptr_factory_(this) {}
85 130
86 UrlDownloader::~UrlDownloader() { 131 UrlDownloader::~UrlDownloader() {
87 handler_.reset(); 132 CallStartedCallbackOnFailure(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
88 } 133 }
89 134
90 void UrlDownloader::Start() { 135 void UrlDownloader::Start() {
91 DCHECK(!request_->is_pending()); 136 DCHECK(!request_->is_pending());
92 137
93 if (!request_->status().is_success()) 138 if (!request_->status().is_success())
94 return; 139 return;
95 140
96 request_->set_delegate(this); 141 request_->set_delegate(this);
97 request_->Start(); 142 request_->Start();
98 } 143 }
99 144
100 void UrlDownloader::OnReceivedRedirect(net::URLRequest* request, 145 void UrlDownloader::OnReceivedRedirect(net::URLRequest* request,
101 const net::RedirectInfo& redirect_info, 146 const net::RedirectInfo& redirect_info,
102 bool* defer_redirect) { 147 bool* defer_redirect) {
103 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); 148 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
104 request_->CancelWithError(net::ERR_ABORTED); 149 request_->CancelWithError(net::ERR_ABORTED);
105 } 150 }
106 151
107 void UrlDownloader::OnResponseStarted(net::URLRequest* request) { 152 void UrlDownloader::OnResponseStarted(net::URLRequest* request) {
108 DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); 153 DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
109 154
110 if (!request_->status().is_success()) { 155 if (!request_->status().is_success()) {
111 ResponseCompleted(); 156 ResponseCompleted();
112 return; 157 return;
113 } 158 }
114 159
115 handler_->OnResponseStarted(); 160 scoped_ptr<DownloadCreateInfo> create_info;
161 scoped_ptr<ByteStreamReader> stream_reader;
162
163 handler_.OnResponseStarted(&create_info, &stream_reader);
164
165 create_info->download_id = download_id_;
166 create_info->request_handle.reset(
167 new RequestHandle(weak_ptr_factory_.GetWeakPtr(), manager_,
168 base::SequencedTaskRunnerHandle::Get()));
169 BrowserThread::PostTask(
170 BrowserThread::UI, FROM_HERE,
171 base::Bind(&DownloadManagerImpl::StartDownload, manager_,
172 base::Passed(&create_info), base::Passed(&stream_reader),
173 base::ResetAndReturn(&on_started_callback_)));
116 174
117 if (request_->status().is_success()) 175 if (request_->status().is_success())
118 StartReading(false); // Read the first chunk. 176 StartReading(false); // Read the first chunk.
119 else 177 else
120 ResponseCompleted(); 178 ResponseCompleted();
121 } 179 }
122 180
123 void UrlDownloader::StartReading(bool is_continuation) { 181 void UrlDownloader::StartReading(bool is_continuation) {
124 int bytes_read; 182 int bytes_read;
125 183
126 // Make sure we track the buffer in at least one place. This ensures it gets 184 // Make sure we track the buffer in at least one place. This ensures it gets
127 // deleted even in the case the request has already finished its job and 185 // deleted even in the case the request has already finished its job and
128 // doesn't use the buffer. 186 // doesn't use the buffer.
129 scoped_refptr<net::IOBuffer> buf; 187 scoped_refptr<net::IOBuffer> buf;
130 int buf_size; 188 int buf_size;
131 if (!handler_->OnWillRead(&buf, &buf_size, -1)) { 189 if (!handler_.OnWillRead(&buf, &buf_size, -1)) {
132 request_->CancelWithError(net::ERR_ABORTED); 190 request_->CancelWithError(net::ERR_ABORTED);
133 base::ThreadTaskRunnerHandle::Get()->PostTask( 191 base::SequencedTaskRunnerHandle::Get()->PostTask(
134 FROM_HERE, base::Bind(&UrlDownloader::ResponseCompleted, 192 FROM_HERE, base::Bind(&UrlDownloader::ResponseCompleted,
135 weak_ptr_factory_.GetWeakPtr())); 193 weak_ptr_factory_.GetWeakPtr()));
136 return; 194 return;
137 } 195 }
138 196
139 DCHECK(buf.get()); 197 DCHECK(buf.get());
140 DCHECK(buf_size > 0); 198 DCHECK(buf_size > 0);
141 199
142 request_->Read(buf.get(), buf_size, &bytes_read); 200 request_->Read(buf.get(), buf_size, &bytes_read);
143 201
144 // If IO is pending, wait for the URLRequest to call OnReadCompleted. 202 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
145 if (request_->status().is_io_pending()) 203 if (request_->status().is_io_pending())
146 return; 204 return;
147 205
148 if (!is_continuation || bytes_read <= 0) { 206 if (!is_continuation || bytes_read <= 0) {
149 OnReadCompleted(request_.get(), bytes_read); 207 OnReadCompleted(request_.get(), bytes_read);
150 } else { 208 } else {
151 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO 209 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
152 // thread in case the URLRequest can provide data synchronously. 210 // thread in case the URLRequest can provide data synchronously.
153 base::ThreadTaskRunnerHandle::Get()->PostTask( 211 base::SequencedTaskRunnerHandle::Get()->PostTask(
154 FROM_HERE, 212 FROM_HERE,
155 base::Bind(&UrlDownloader::OnReadCompleted, 213 base::Bind(&UrlDownloader::OnReadCompleted,
156 weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read)); 214 weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read));
157 } 215 }
158 } 216 }
159 217
160 void UrlDownloader::OnReadCompleted(net::URLRequest* request, int bytes_read) { 218 void UrlDownloader::OnReadCompleted(net::URLRequest* request, int bytes_read) {
161 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\"" 219 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
162 << " bytes_read = " << bytes_read; 220 << " bytes_read = " << bytes_read;
163 221
164 // bytes_read == -1 always implies an error. 222 // bytes_read == -1 always implies an error.
165 if (bytes_read == -1 || !request_->status().is_success()) { 223 if (bytes_read == -1 || !request_->status().is_success()) {
166 ResponseCompleted(); 224 ResponseCompleted();
167 return; 225 return;
168 } 226 }
169 227
170 DCHECK(bytes_read >= 0); 228 DCHECK(bytes_read >= 0);
171 DCHECK(request_->status().is_success()); 229 DCHECK(request_->status().is_success());
172 230
173 bool defer = false; 231 bool defer = false;
174 if (!handler_->OnReadCompleted(bytes_read, &defer)) { 232 if (!handler_.OnReadCompleted(bytes_read, &defer)) {
175 request_->CancelWithError(net::ERR_ABORTED); 233 request_->CancelWithError(net::ERR_ABORTED);
176 return; 234 return;
177 } else if (defer) { 235 } else if (defer) {
178 return; 236 return;
179 } 237 }
180 238
181 if (!request_->status().is_success()) 239 if (!request_->status().is_success())
182 return; 240 return;
183 241
184 if (bytes_read > 0) { 242 if (bytes_read > 0) {
185 StartReading(true); // Read the next chunk. 243 StartReading(true); // Read the next chunk.
186 } else { 244 } else {
187 // URLRequest reported an EOF. Call ResponseCompleted. 245 // URLRequest reported an EOF. Call ResponseCompleted.
188 DCHECK_EQ(0, bytes_read); 246 DCHECK_EQ(0, bytes_read);
189 ResponseCompleted(); 247 ResponseCompleted();
190 } 248 }
191 } 249 }
192 250
193 void UrlDownloader::ResponseCompleted() { 251 void UrlDownloader::ResponseCompleted() {
194 DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); 252 DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
195 253
196 handler_->OnResponseCompleted(request_->status()); 254 handler_.OnResponseCompleted(request_->status());
197 BrowserThread::PostTask( 255 BrowserThread::PostTask(
198 BrowserThread::UI, FROM_HERE, 256 BrowserThread::UI, FROM_HERE,
199 base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this)); 257 base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this));
200 } 258 }
201 259
202 void UrlDownloader::ResumeReading() { 260 void UrlDownloader::ResumeReading() {
203 if (request_->status().is_success()) { 261 if (request_->status().is_success()) {
204 StartReading(false); // Read the next chunk (OK to complete synchronously). 262 StartReading(false); // Read the next chunk (OK to complete synchronously).
205 } else { 263 } else {
206 ResponseCompleted(); 264 ResponseCompleted();
207 } 265 }
208 } 266 }
209 267
268 void UrlDownloader::CallStartedCallbackOnFailure(
269 DownloadInterruptReason result) {
270 if (on_started_callback_.is_null())
271 return;
272 BrowserThread::PostTask(
273 BrowserThread::UI, FROM_HERE,
274 base::Bind(base::ResetAndReturn(&on_started_callback_), nullptr, result));
275 }
276
277 void UrlDownloader::PauseRequest() {
278 handler_.PauseRequest();
279 }
280
281 void UrlDownloader::ResumeRequest() {
282 handler_.ResumeRequest();
283 }
284
285 void UrlDownloader::CancelRequest() {
286 BrowserThread::PostTask(
287 BrowserThread::UI, FROM_HERE,
288 base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this));
289 }
290
210 } // namespace content 291 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/url_downloader.h ('k') | content/test/data/download/gzip-content.gz » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698