| OLD | NEW | 
|---|
| 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/callback_helpers.h" | 
| 8 #include "base/location.h" | 8 #include "base/location.h" | 
| 9 #include "base/macros.h" | 9 #include "base/macros.h" | 
| 10 #include "base/threading/sequenced_task_runner_handle.h" | 10 #include "base/threading/sequenced_task_runner_handle.h" | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 67   base::WeakPtr<DownloadManagerImpl> download_manager_impl_; | 67   base::WeakPtr<DownloadManagerImpl> download_manager_impl_; | 
| 68   scoped_refptr<base::SequencedTaskRunner> downloader_task_runner_; | 68   scoped_refptr<base::SequencedTaskRunner> downloader_task_runner_; | 
| 69 | 69 | 
| 70   DISALLOW_COPY_AND_ASSIGN(RequestHandle); | 70   DISALLOW_COPY_AND_ASSIGN(RequestHandle); | 
| 71 }; | 71 }; | 
| 72 | 72 | 
| 73 // static | 73 // static | 
| 74 scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload( | 74 scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload( | 
| 75     base::WeakPtr<DownloadManagerImpl> download_manager, | 75     base::WeakPtr<DownloadManagerImpl> download_manager, | 
| 76     scoped_ptr<net::URLRequest> request, | 76     scoped_ptr<net::URLRequest> request, | 
| 77     const Referrer& referrer, | 77     const Referrer& referrer) { | 
| 78     bool prefer_cache, |  | 
| 79     scoped_ptr<DownloadSaveInfo> save_info, |  | 
| 80     uint32_t download_id, |  | 
| 81     const DownloadUrlParameters::OnStartedCallback& started_callback) { |  | 
| 82   if (!referrer.url.is_valid()) | 78   if (!referrer.url.is_valid()) | 
| 83     request->SetReferrer(std::string()); | 79     request->SetReferrer(std::string()); | 
| 84   else | 80   else | 
| 85     request->SetReferrer(referrer.url.spec()); | 81     request->SetReferrer(referrer.url.spec()); | 
| 86 | 82 | 
| 87   int extra_load_flags = net::LOAD_NORMAL; |  | 
| 88   if (prefer_cache) { |  | 
| 89     // If there is upload data attached, only retrieve from cache because there |  | 
| 90     // is no current mechanism to prompt the user for their consent for a |  | 
| 91     // re-post. For GETs, try to retrieve data from the cache and skip |  | 
| 92     // validating the entry if present. |  | 
| 93     if (request->get_upload() != NULL) |  | 
| 94       extra_load_flags |= net::LOAD_ONLY_FROM_CACHE; |  | 
| 95     else |  | 
| 96       extra_load_flags |= net::LOAD_PREFERRING_CACHE; |  | 
| 97   } else { |  | 
| 98     extra_load_flags |= net::LOAD_DISABLE_CACHE; |  | 
| 99   } |  | 
| 100   request->SetLoadFlags(request->load_flags() | extra_load_flags); |  | 
| 101 |  | 
| 102   if (request->url().SchemeIs(url::kBlobScheme)) | 83   if (request->url().SchemeIs(url::kBlobScheme)) | 
| 103     return nullptr; | 84     return nullptr; | 
| 104 | 85 | 
| 105   // From this point forward, the |UrlDownloader| is responsible for | 86   // From this point forward, the |UrlDownloader| is responsible for | 
| 106   // |started_callback|. | 87   // |started_callback|. | 
| 107   scoped_ptr<UrlDownloader> downloader( | 88   scoped_ptr<UrlDownloader> downloader( | 
| 108       new UrlDownloader(std::move(request), download_manager, | 89       new UrlDownloader(std::move(request), download_manager)); | 
| 109                         std::move(save_info), download_id, started_callback)); |  | 
| 110   downloader->Start(); | 90   downloader->Start(); | 
| 111 | 91 | 
| 112   return downloader; | 92   return downloader; | 
| 113 } | 93 } | 
| 114 | 94 | 
| 115 UrlDownloader::UrlDownloader( | 95 UrlDownloader::UrlDownloader(scoped_ptr<net::URLRequest> request, | 
| 116     scoped_ptr<net::URLRequest> request, | 96                              base::WeakPtr<DownloadManagerImpl> manager) | 
| 117     base::WeakPtr<DownloadManagerImpl> manager, |  | 
| 118     scoped_ptr<DownloadSaveInfo> save_info, |  | 
| 119     uint32_t download_id, |  | 
| 120     const DownloadUrlParameters::OnStartedCallback& on_started_callback) |  | 
| 121     : request_(std::move(request)), | 97     : request_(std::move(request)), | 
| 122       manager_(manager), | 98       manager_(manager), | 
| 123       download_id_(download_id), | 99       core_(request_.get(), this), | 
| 124       on_started_callback_(on_started_callback), |  | 
| 125       handler_( |  | 
| 126           request_.get(), |  | 
| 127           std::move(save_info), |  | 
| 128           base::Bind(&UrlDownloader::ResumeReading, base::Unretained(this))), |  | 
| 129       weak_ptr_factory_(this) {} | 100       weak_ptr_factory_(this) {} | 
| 130 | 101 | 
| 131 UrlDownloader::~UrlDownloader() { | 102 UrlDownloader::~UrlDownloader() { | 
| 132   CallStartedCallbackOnFailure(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); |  | 
| 133 } | 103 } | 
| 134 | 104 | 
| 135 void UrlDownloader::Start() { | 105 void UrlDownloader::Start() { | 
| 136   DCHECK(!request_->is_pending()); | 106   DCHECK(!request_->is_pending()); | 
| 137 | 107 | 
| 138   if (!request_->status().is_success()) | 108   if (!request_->status().is_success()) | 
| 139     return; | 109     return; | 
| 140 | 110 | 
| 141   request_->set_delegate(this); | 111   request_->set_delegate(this); | 
| 142   request_->Start(); | 112   request_->Start(); | 
| 143 } | 113 } | 
| 144 | 114 | 
| 145 void UrlDownloader::OnReceivedRedirect(net::URLRequest* request, | 115 void UrlDownloader::OnReceivedRedirect(net::URLRequest* request, | 
| 146                                        const net::RedirectInfo& redirect_info, | 116                                        const net::RedirectInfo& redirect_info, | 
| 147                                        bool* defer_redirect) { | 117                                        bool* defer_redirect) { | 
| 148   DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); | 118   DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec(); | 
| 149   request_->CancelWithError(net::ERR_ABORTED); | 119   request_->CancelWithError(net::ERR_ABORTED); | 
| 150 } | 120 } | 
| 151 | 121 | 
| 152 void UrlDownloader::OnResponseStarted(net::URLRequest* request) { | 122 void UrlDownloader::OnResponseStarted(net::URLRequest* request) { | 
| 153   DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); | 123   DVLOG(1) << "OnResponseStarted: " << request_->url().spec(); | 
| 154 | 124 | 
| 155   if (!request_->status().is_success()) { | 125   if (!request_->status().is_success()) { | 
| 156     ResponseCompleted(); | 126     ResponseCompleted(); | 
| 157     return; | 127     return; | 
| 158   } | 128   } | 
| 159 | 129 | 
| 160   scoped_ptr<DownloadCreateInfo> create_info; | 130   if (core_.OnResponseStarted(std::string())) | 
| 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_))); |  | 
| 174 |  | 
| 175   if (request_->status().is_success()) |  | 
| 176     StartReading(false);  // Read the first chunk. | 131     StartReading(false);  // Read the first chunk. | 
| 177   else | 132   else | 
| 178     ResponseCompleted(); | 133     ResponseCompleted(); | 
| 179 } | 134 } | 
| 180 | 135 | 
| 181 void UrlDownloader::StartReading(bool is_continuation) { | 136 void UrlDownloader::StartReading(bool is_continuation) { | 
| 182   int bytes_read; | 137   int bytes_read; | 
| 183 | 138 | 
| 184   // Make sure we track the buffer in at least one place.  This ensures it gets | 139   // Make sure we track the buffer in at least one place.  This ensures it gets | 
| 185   // deleted even in the case the request has already finished its job and | 140   // deleted even in the case the request has already finished its job and | 
| 186   // doesn't use the buffer. | 141   // doesn't use the buffer. | 
| 187   scoped_refptr<net::IOBuffer> buf; | 142   scoped_refptr<net::IOBuffer> buf; | 
| 188   int buf_size; | 143   int buf_size; | 
| 189   if (!handler_.OnWillRead(&buf, &buf_size, -1)) { | 144   if (!core_.OnWillRead(&buf, &buf_size, -1)) { | 
| 190     request_->CancelWithError(net::ERR_ABORTED); | 145     request_->CancelWithError(net::ERR_ABORTED); | 
| 191     base::SequencedTaskRunnerHandle::Get()->PostTask( | 146     base::SequencedTaskRunnerHandle::Get()->PostTask( | 
| 192         FROM_HERE, base::Bind(&UrlDownloader::ResponseCompleted, | 147         FROM_HERE, base::Bind(&UrlDownloader::ResponseCompleted, | 
| 193                               weak_ptr_factory_.GetWeakPtr())); | 148                               weak_ptr_factory_.GetWeakPtr())); | 
| 194     return; | 149     return; | 
| 195   } | 150   } | 
| 196 | 151 | 
| 197   DCHECK(buf.get()); | 152   DCHECK(buf.get()); | 
| 198   DCHECK(buf_size > 0); | 153   DCHECK(buf_size > 0); | 
| 199 | 154 | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 222   // bytes_read == -1 always implies an error. | 177   // bytes_read == -1 always implies an error. | 
| 223   if (bytes_read == -1 || !request_->status().is_success()) { | 178   if (bytes_read == -1 || !request_->status().is_success()) { | 
| 224     ResponseCompleted(); | 179     ResponseCompleted(); | 
| 225     return; | 180     return; | 
| 226   } | 181   } | 
| 227 | 182 | 
| 228   DCHECK(bytes_read >= 0); | 183   DCHECK(bytes_read >= 0); | 
| 229   DCHECK(request_->status().is_success()); | 184   DCHECK(request_->status().is_success()); | 
| 230 | 185 | 
| 231   bool defer = false; | 186   bool defer = false; | 
| 232   if (!handler_.OnReadCompleted(bytes_read, &defer)) { | 187   if (!core_.OnReadCompleted(bytes_read, &defer)) { | 
| 233     request_->CancelWithError(net::ERR_ABORTED); | 188     request_->CancelWithError(net::ERR_ABORTED); | 
| 234     return; | 189     return; | 
| 235   } else if (defer) { | 190   } else if (defer) { | 
| 236     return; | 191     return; | 
| 237   } | 192   } | 
| 238 | 193 | 
| 239   if (!request_->status().is_success()) | 194   if (!request_->status().is_success()) | 
| 240     return; | 195     return; | 
| 241 | 196 | 
| 242   if (bytes_read > 0) { | 197   if (bytes_read > 0) { | 
| 243     StartReading(true);  // Read the next chunk. | 198     StartReading(true);  // Read the next chunk. | 
| 244   } else { | 199   } else { | 
| 245     // URLRequest reported an EOF. Call ResponseCompleted. | 200     // URLRequest reported an EOF. Call ResponseCompleted. | 
| 246     DCHECK_EQ(0, bytes_read); | 201     DCHECK_EQ(0, bytes_read); | 
| 247     ResponseCompleted(); | 202     ResponseCompleted(); | 
| 248   } | 203   } | 
| 249 } | 204 } | 
| 250 | 205 | 
| 251 void UrlDownloader::ResponseCompleted() { | 206 void UrlDownloader::ResponseCompleted() { | 
| 252   DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); | 207   DVLOG(1) << "ResponseCompleted: " << request_->url().spec(); | 
| 253 | 208 | 
| 254   handler_.OnResponseCompleted(request_->status()); | 209   core_.OnResponseCompleted(request_->status()); | 
|  | 210   Destroy(); | 
|  | 211 } | 
|  | 212 | 
|  | 213 void UrlDownloader::OnStart( | 
|  | 214     scoped_ptr<DownloadCreateInfo> create_info, | 
|  | 215     scoped_ptr<ByteStreamReader> stream_reader, | 
|  | 216     const DownloadUrlParameters::OnStartedCallback& callback) { | 
|  | 217   create_info->request_handle.reset( | 
|  | 218       new RequestHandle(weak_ptr_factory_.GetWeakPtr(), manager_, | 
|  | 219                         base::SequencedTaskRunnerHandle::Get())); | 
|  | 220   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 
|  | 221                           base::Bind(&DownloadManagerImpl::StartDownload, | 
|  | 222                                      manager_, base::Passed(&create_info), | 
|  | 223                                      base::Passed(&stream_reader), callback)); | 
|  | 224 } | 
|  | 225 | 
|  | 226 void UrlDownloader::OnReadyToRead() { | 
|  | 227   if (request_->status().is_success()) | 
|  | 228     StartReading(false);  // Read the next chunk (OK to complete synchronously). | 
|  | 229   else | 
|  | 230     ResponseCompleted(); | 
|  | 231 } | 
|  | 232 | 
|  | 233 void UrlDownloader::PauseRequest() { | 
|  | 234   core_.PauseRequest(); | 
|  | 235 } | 
|  | 236 | 
|  | 237 void UrlDownloader::ResumeRequest() { | 
|  | 238   core_.ResumeRequest(); | 
|  | 239 } | 
|  | 240 | 
|  | 241 void UrlDownloader::CancelRequest() { | 
|  | 242   Destroy(); | 
|  | 243 } | 
|  | 244 | 
|  | 245 void UrlDownloader::Destroy() { | 
| 255   BrowserThread::PostTask( | 246   BrowserThread::PostTask( | 
| 256       BrowserThread::UI, FROM_HERE, | 247       BrowserThread::UI, FROM_HERE, | 
| 257       base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this)); | 248       base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this)); | 
| 258 } |  | 
| 259 |  | 
| 260 void UrlDownloader::ResumeReading() { |  | 
| 261   if (request_->status().is_success()) { |  | 
| 262     StartReading(false);  // Read the next chunk (OK to complete synchronously). |  | 
| 263   } else { |  | 
| 264     ResponseCompleted(); |  | 
| 265   } |  | 
| 266 } |  | 
| 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 } | 249 } | 
| 290 | 250 | 
| 291 }  // namespace content | 251 }  // namespace content | 
| OLD | NEW | 
|---|