OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/download_resource_handler.h" | 5 #include "content/browser/download/download_resource_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "net/base/net_errors.h" | 29 #include "net/base/net_errors.h" |
30 #include "net/http/http_response_headers.h" | 30 #include "net/http/http_response_headers.h" |
31 #include "net/url_request/url_request_context.h" | 31 #include "net/url_request/url_request_context.h" |
32 | 32 |
33 using content::BrowserThread; | 33 using content::BrowserThread; |
34 using content::DownloadId; | 34 using content::DownloadId; |
35 using content::DownloadItem; | 35 using content::DownloadItem; |
36 using content::DownloadManager; | 36 using content::DownloadManager; |
37 using content::ResourceRequestInfoImpl; | 37 using content::ResourceRequestInfoImpl; |
38 | 38 |
| 39 namespace { |
| 40 |
| 41 void CallStartedCBOnUIThread( |
| 42 const DownloadResourceHandler::OnStartedCallback& started_cb, |
| 43 DownloadId id, |
| 44 net::Error error) { |
| 45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 46 if (started_cb.is_null()) |
| 47 return; |
| 48 started_cb.Run(id, error); |
| 49 } |
| 50 |
| 51 } // namespace |
| 52 |
39 DownloadResourceHandler::DownloadResourceHandler( | 53 DownloadResourceHandler::DownloadResourceHandler( |
40 ResourceDispatcherHost* rdh, | 54 ResourceDispatcherHost* rdh, |
41 int render_process_host_id, | 55 int render_process_host_id, |
42 int render_view_id, | 56 int render_view_id, |
43 int request_id, | 57 int request_id, |
44 const GURL& url, | 58 const GURL& url, |
45 DownloadFileManager* download_file_manager, | 59 DownloadFileManager* download_file_manager, |
46 net::URLRequest* request, | 60 net::URLRequest* request, |
47 const DownloadResourceHandler::OnStartedCallback& started_cb, | 61 const DownloadResourceHandler::OnStartedCallback& started_cb, |
48 const DownloadSaveInfo& save_info) | 62 const DownloadSaveInfo& save_info) |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 168 |
155 // We can't start saving the data before we create the file on disk and have a | 169 // We can't start saving the data before we create the file on disk and have a |
156 // download id. The request will be un-paused in | 170 // download id. The request will be un-paused in |
157 // DownloadFileManager::CreateDownloadFile. | 171 // DownloadFileManager::CreateDownloadFile. |
158 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, true); | 172 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, true); |
159 | 173 |
160 return true; | 174 return true; |
161 } | 175 } |
162 | 176 |
163 void DownloadResourceHandler::CallStartedCB(DownloadId id, net::Error error) { | 177 void DownloadResourceHandler::CallStartedCB(DownloadId id, net::Error error) { |
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
165 if (started_cb_.is_null()) | 178 if (started_cb_.is_null()) |
166 return; | 179 return; |
167 started_cb_.Run(id, error); | 180 BrowserThread::PostTask( |
| 181 BrowserThread::UI, FROM_HERE, |
| 182 base::Bind(&CallStartedCBOnUIThread, started_cb_, id, error)); |
168 started_cb_.Reset(); | 183 started_cb_.Reset(); |
169 } | 184 } |
170 | 185 |
171 bool DownloadResourceHandler::OnWillStart(int request_id, | 186 bool DownloadResourceHandler::OnWillStart(int request_id, |
172 const GURL& url, | 187 const GURL& url, |
173 bool* defer) { | 188 bool* defer) { |
174 return true; | 189 return true; |
175 } | 190 } |
176 | 191 |
177 // Create a new buffer, which will be handed to the download thread for file | 192 // Create a new buffer, which will be handed to the download thread for file |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 default: | 308 default: |
294 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; | 309 reason = content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; |
295 break; | 310 break; |
296 } | 311 } |
297 } | 312 } |
298 } | 313 } |
299 | 314 |
300 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); | 315 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); |
301 | 316 |
302 // If the callback was already run on the UI thread, this will be a noop. | 317 // If the callback was already run on the UI thread, this will be a noop. |
303 BrowserThread::PostTask( | 318 CallStartedCB(download_id_, error_code); |
304 BrowserThread::UI, FROM_HERE, | |
305 base::Bind(&DownloadResourceHandler::CallStartedCB, this, | |
306 download_id_, error_code)); | |
307 | 319 |
308 // We transfer ownership to |DownloadFileManager| to delete |buffer_|, | 320 // We transfer ownership to |DownloadFileManager| to delete |buffer_|, |
309 // so that any functions queued up on the FILE thread are executed | 321 // so that any functions queued up on the FILE thread are executed |
310 // before deletion. | 322 // before deletion. |
311 BrowserThread::PostTask( | 323 BrowserThread::PostTask( |
312 BrowserThread::FILE, FROM_HERE, | 324 BrowserThread::FILE, FROM_HERE, |
313 base::Bind(&DownloadFileManager::OnResponseCompleted, | 325 base::Bind(&DownloadFileManager::OnResponseCompleted, |
314 download_file_manager_, download_id_, reason, security_info)); | 326 download_file_manager_, download_id_, reason, security_info)); |
315 buffer_ = NULL; // The buffer is longer needed by |DownloadResourceHandler|. | 327 buffer_ = NULL; // The buffer is longer needed by |DownloadResourceHandler|. |
316 read_buffer_ = NULL; | 328 read_buffer_ = NULL; |
317 } | 329 } |
318 | 330 |
319 void DownloadResourceHandler::OnRequestClosed() { | 331 void DownloadResourceHandler::OnRequestClosed() { |
320 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", | 332 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", |
321 base::TimeTicks::Now() - download_start_time_); | 333 base::TimeTicks::Now() - download_start_time_); |
322 } | 334 } |
323 | 335 |
324 void DownloadResourceHandler::StartOnUIThread( | 336 void DownloadResourceHandler::StartOnUIThread( |
325 scoped_ptr<DownloadCreateInfo> info, | 337 scoped_ptr<DownloadCreateInfo> info, |
326 const DownloadRequestHandle& handle) { | 338 const DownloadRequestHandle& handle) { |
327 DownloadManager* download_manager = handle.GetDownloadManager(); | 339 DownloadManager* download_manager = handle.GetDownloadManager(); |
328 if (!download_manager) { | 340 if (!download_manager) { |
329 // NULL in unittests or if the page closed right after starting the | 341 // NULL in unittests or if the page closed right after starting the |
330 // download. | 342 // download. |
| 343 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED); |
331 return; | 344 return; |
332 } | 345 } |
333 DownloadId download_id = download_manager->delegate()->GetNextId(); | 346 DownloadId download_id = download_manager->delegate()->GetNextId(); |
334 info->download_id = download_id; | 347 info->download_id = download_id; |
335 BrowserThread::PostTask( | 348 BrowserThread::PostTask( |
336 BrowserThread::IO, FROM_HERE, | 349 BrowserThread::IO, FROM_HERE, |
337 base::Bind(&DownloadResourceHandler::set_download_id, this, | 350 base::Bind(&DownloadResourceHandler::set_download_id, this, |
338 info->download_id)); | 351 info->download_id)); |
339 // It's safe to continue on with download initiation before we have | 352 // It's safe to continue on with download initiation before we have |
340 // confirmation that that download_id_ has been set on the IO thread, as any | 353 // confirmation that that download_id_ has been set on the IO thread, as any |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 StartPauseTimer(); | 389 StartPauseTimer(); |
377 | 390 |
378 if (is_paused_ != should_pause) { | 391 if (is_paused_ != should_pause) { |
379 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, | 392 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, |
380 should_pause); | 393 should_pause); |
381 is_paused_ = should_pause; | 394 is_paused_ = should_pause; |
382 } | 395 } |
383 } | 396 } |
384 | 397 |
385 DownloadResourceHandler::~DownloadResourceHandler() { | 398 DownloadResourceHandler::~DownloadResourceHandler() { |
| 399 // This won't do anything if the callback was called before. |
| 400 // If it goes through, it will likely be because OnWillStart() returned |
| 401 // false somewhere in the chain of resource handlers. |
| 402 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED); |
386 } | 403 } |
387 | 404 |
388 void DownloadResourceHandler::StartPauseTimer() { | 405 void DownloadResourceHandler::StartPauseTimer() { |
389 if (!pause_timer_.IsRunning()) | 406 if (!pause_timer_.IsRunning()) |
390 pause_timer_.Start(FROM_HERE, | 407 pause_timer_.Start(FROM_HERE, |
391 base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this, | 408 base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this, |
392 &DownloadResourceHandler::CheckWriteProgress); | 409 &DownloadResourceHandler::CheckWriteProgress); |
393 } | 410 } |
394 | 411 |
395 std::string DownloadResourceHandler::DebugString() const { | 412 std::string DownloadResourceHandler::DebugString() const { |
396 return base::StringPrintf("{" | 413 return base::StringPrintf("{" |
397 " url_ = " "\"%s\"" | 414 " url_ = " "\"%s\"" |
398 " download_id_ = " "%d" | 415 " download_id_ = " "%d" |
399 " global_id_ = {" | 416 " global_id_ = {" |
400 " child_id = " "%d" | 417 " child_id = " "%d" |
401 " request_id = " "%d" | 418 " request_id = " "%d" |
402 " }" | 419 " }" |
403 " render_view_id_ = " "%d" | 420 " render_view_id_ = " "%d" |
404 " save_info_.file_path = \"%" PRFilePath "\"" | 421 " save_info_.file_path = \"%" PRFilePath "\"" |
405 " }", | 422 " }", |
406 request_->url().spec().c_str(), | 423 request_ ? |
| 424 request_->url().spec().c_str() : |
| 425 "<NULL request>", |
407 download_id_.local(), | 426 download_id_.local(), |
408 global_id_.child_id, | 427 global_id_.child_id, |
409 global_id_.request_id, | 428 global_id_.request_id, |
410 render_view_id_, | 429 render_view_id_, |
411 save_info_.file_path.value().c_str()); | 430 save_info_.file_path.value().c_str()); |
412 } | 431 } |
OLD | NEW |