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

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

Issue 1418663010: Adding WebContent-free Download (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removing Core. 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/download/url_downloader.h"
6
7 #include "base/location.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "content/browser/appcache/appcache_interceptor.h"
10 #include "content/browser/download/download_manager_impl.h"
11 #include "content/browser/service_worker/service_worker_request_handler.h"
12 #include "content/browser/ssl/ssl_policy.h"
13 #include "content/common/ssl_status_serialization.h"
14 #include "content/public/browser/cert_store.h"
15 #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"
20 #include "net/base/load_flags.h"
21 #include "net/base/net_errors.h"
22 #include "net/http/http_response_headers.h"
23 #include "net/http/http_status_code.h"
24 #include "ui/base/page_transition_types.h"
25
26 namespace content {
27
28 // static
29 scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload(
30 base::WeakPtr<DownloadManagerImpl> download_manager,
31 scoped_ptr<net::URLRequest> request,
32 const Referrer& referrer,
33 bool is_content_initiated,
34 bool prefer_cache,
35 bool do_not_prompt_for_login,
36 scoped_ptr<DownloadSaveInfo> save_info,
37 uint32 download_id,
38 const DownloadUrlParameters::OnStartedCallback& started_callback) {
39 if (!referrer.url.is_valid())
40 request->SetReferrer(std::string());
41 else
42 request->SetReferrer(referrer.url.spec());
43
44 int extra_load_flags = net::LOAD_NORMAL;
45 if (prefer_cache) {
46 // 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
48 // re-post. For GETs, try to retrieve data from the cache and skip
49 // validating the entry if present.
50 if (request->get_upload() != NULL)
51 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE;
52 else
53 extra_load_flags |= net::LOAD_PREFERRING_CACHE;
54 } else {
55 extra_load_flags |= net::LOAD_DISABLE_CACHE;
56 }
57 request->SetLoadFlags(request->load_flags() | extra_load_flags);
58
59 if (request->url().SchemeIs(url::kBlobScheme))
60 return nullptr;
61
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
67 // |started_callback|.
68 scoped_ptr<UrlDownloader> downloader(
69 new UrlDownloader(request.Pass(), handler.Pass(), download_manager));
70
71 downloader->Start();
72
73 return downloader;
74 }
75
76 UrlDownloader::UrlDownloader(scoped_ptr<net::URLRequest> request,
77 scoped_ptr<DownloadRequestCore> handler,
78 base::WeakPtr<DownloadManagerImpl> manager)
79 : request_(request.Pass()),
80 handler_(handler.Pass()),
81 manager_(manager),
82 weak_ptr_factory_(this) {
83 handler_->set_downloader(this);
84 }
85
86 UrlDownloader::~UrlDownloader() {
87 handler_.reset();
88 }
89
90 void UrlDownloader::Start() {
91 DCHECK(!request_->is_pending());
92
93 if (!request_->status().is_success())
94 return;
95
96 request_->set_delegate(this);
97 request_->Start();
98 }
99
100 void UrlDownloader::OnReceivedRedirect(net::URLRequest* request,
101 const net::RedirectInfo& redirect_info,
102 bool* defer_redirect) {
103 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
104 request_->CancelWithError(net::ERR_ABORTED);
105 }
106
107 void UrlDownloader::OnResponseStarted(net::URLRequest* request) {
108 DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
109
110 if (!request_->status().is_success()) {
111 ResponseCompleted();
112 return;
113 }
114
115 handler_->OnResponseStarted();
116
117 if (request_->status().is_success())
118 StartReading(false); // Read the first chunk.
119 else
120 ResponseCompleted();
121 }
122
123 void UrlDownloader::StartReading(bool is_continuation) {
124 int bytes_read;
125
126 // 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
128 // doesn't use the buffer.
129 scoped_refptr<net::IOBuffer> buf;
130 int buf_size;
131 if (!handler_->OnWillRead(&buf, &buf_size, -1)) {
132 request_->CancelWithError(net::ERR_ABORTED);
133 base::ThreadTaskRunnerHandle::Get()->PostTask(
134 FROM_HERE, base::Bind(&UrlDownloader::ResponseCompleted,
135 weak_ptr_factory_.GetWeakPtr()));
136 return;
137 }
138
139 DCHECK(buf.get());
140 DCHECK(buf_size > 0);
141
142 request_->Read(buf.get(), buf_size, &bytes_read);
143
144 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
145 if (request_->status().is_io_pending())
146 return;
147
148 if (!is_continuation || bytes_read <= 0) {
149 OnReadCompleted(request_.get(), bytes_read);
150 } else {
151 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
152 // thread in case the URLRequest can provide data synchronously.
153 base::ThreadTaskRunnerHandle::Get()->PostTask(
154 FROM_HERE,
155 base::Bind(&UrlDownloader::OnReadCompleted,
156 weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read));
157 }
158 }
159
160 void UrlDownloader::OnReadCompleted(net::URLRequest* request, int bytes_read) {
161 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
162 << " bytes_read = " << bytes_read;
163
164 // bytes_read == -1 always implies an error.
165 if (bytes_read == -1 || !request_->status().is_success()) {
166 ResponseCompleted();
167 return;
168 }
169
170 DCHECK(bytes_read >= 0);
171 DCHECK(request_->status().is_success());
172
173 bool defer = false;
174 if (!handler_->OnReadCompleted(bytes_read, &defer)) {
175 request_->CancelWithError(net::ERR_ABORTED);
176 return;
177 } else if (defer) {
178 return;
179 }
180
181 if (!request_->status().is_success())
182 return;
183
184 if (bytes_read > 0) {
185 StartReading(true); // Read the next chunk.
186 } else {
187 // URLRequest reported an EOF. Call ResponseCompleted.
188 DCHECK_EQ(0, bytes_read);
189 ResponseCompleted();
190 }
191 }
192
193 void UrlDownloader::ResponseCompleted() {
194 DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
195
196 handler_->OnResponseCompleted(request_->status());
197 BrowserThread::PostTask(
198 BrowserThread::UI, FROM_HERE,
199 base::Bind(&DownloadManagerImpl::RemoveUrlDownloader, manager_, this));
200 }
201
202 void UrlDownloader::Resume() {
asanka 2015/12/08 21:53:56 Why the async invocation for ResumeReading()? Unle
svaldez 2015/12/09 17:20:41 Done.
203 base::ThreadTaskRunnerHandle::Get()->PostTask(
204 FROM_HERE, base::Bind(&UrlDownloader::ResumeReading,
205 weak_ptr_factory_.GetWeakPtr()));
206 }
207
208 void UrlDownloader::ResumeReading() {
209 if (request_->status().is_success()) {
210 StartReading(false); // Read the next chunk (OK to complete synchronously).
211 } else {
212 ResponseCompleted();
213 }
214 }
215
216 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698