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

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: Rebase. 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/service_worker/service_worker_request_handler.h"
11 #include "content/browser/ssl/ssl_policy.h"
12 #include "content/common/ssl_status_serialization.h"
13 #include "content/public/browser/cert_store.h"
14 #include "content/public/browser/download_save_info.h"
15 #include "content/public/browser/signed_certificate_timestamp_store.h"
16 #include "content/public/common/process_type.h"
17 #include "content/public/common/security_style.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/load_flags.h"
20 #include "net/base/net_errors.h"
21 #include "net/http/http_response_headers.h"
22 #include "net/http/http_status_code.h"
23 #include "ui/base/page_transition_types.h"
24
25 namespace content {
26
27 scoped_ptr<UrlDownloader> UrlDownloader::BeginDownload(
asanka 2015/12/08 16:58:33 // static above this line.
svaldez 2015/12/08 20:39:26 Done.
28 base::WeakPtr<DownloadManagerImpl> download_manager,
29 scoped_ptr<net::URLRequest> request,
30 const Referrer& referrer,
31 bool is_content_initiated,
32 bool prefer_cache,
33 bool do_not_prompt_for_login,
34 scoped_ptr<DownloadSaveInfo> save_info,
35 uint32 download_id,
36 const DownloadUrlParameters::OnStartedCallback& started_callback) {
37 if (!referrer.url.is_valid())
38 request->SetReferrer(std::string());
39 else
40 request->SetReferrer(referrer.url.spec());
41
42 int extra_load_flags = net::LOAD_NORMAL;
43 if (prefer_cache) {
44 // If there is upload data attached, only retrieve from cache because there
45 // is no current mechanism to prompt the user for their consent for a
46 // re-post. For GETs, try to retrieve data from the cache and skip
47 // validating the entry if present.
48 if (request->get_upload() != NULL)
49 extra_load_flags |= net::LOAD_ONLY_FROM_CACHE;
50 else
51 extra_load_flags |= net::LOAD_PREFERRING_CACHE;
52 } else {
53 extra_load_flags |= net::LOAD_DISABLE_CACHE;
54 }
55 request->SetLoadFlags(request->load_flags() | extra_load_flags);
56
57 // We treat a download as a main frame load, and thus update the policy URL on
58 // redirects.
59 //
60 // TODO(davidben): Is this correct? If this came from a
61 // ViewHostMsg_DownloadUrl in a frame, should it have first-party URL set
62 // appropriately?
asanka 2015/12/08 16:58:33 This was done for downloads because we wanted to t
svaldez 2015/12/08 20:39:26 Done.
63 request->set_first_party_url_policy(
64 net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
65
66 if (request->url().SchemeIs(url::kBlobScheme))
67 return nullptr;
68
69 scoped_ptr<DownloadRequestCore> handler(new DownloadRequestCore(
70 download_id, request.get(), started_callback, save_info.Pass(),
71 download_manager));
72
73 // From this point forward, the |UrlDownloader| is responsible for
74 // |started_callback|.
75 scoped_ptr<UrlDownloader> downloader(
76 new UrlDownloader(request.Pass(), handler.Pass()));
77
78 downloader->Start();
79
80 return downloader;
81 }
82
83 UrlDownloader::UrlDownloader(scoped_ptr<net::URLRequest> request,
84 scoped_ptr<DownloadRequestCore> handler)
85 : request_(request.Pass()),
86 handler_(handler.Pass()),
87 weak_ptr_factory_(this) {}
88
89 UrlDownloader::~UrlDownloader() {
90 handler_.reset();
91 }
92
93 void UrlDownloader::Start() {
94 DCHECK(!request_->is_pending());
95
96 if (!request_->status().is_success()) {
asanka 2015/12/08 16:58:33 Nit: no { Also, do you know when this would be tr
svaldez 2015/12/08 20:39:26 Requests which are prematurely killed? Copied from
97 return;
98 }
99
100 request_->set_delegate(this);
101 request_->Start();
102 }
103
104 void UrlDownloader::OnReceivedRedirect(net::URLRequest* request,
105 const net::RedirectInfo& redirect_info,
106 bool* defer_redirect) {
107 DVLOG(1) << "OnReceivedRedirect: " << request_->url().spec();
108 request_->CancelWithError(net::ERR_ABORTED);
109 }
110
111 void UrlDownloader::OnResponseStarted(net::URLRequest* request) {
112 DVLOG(1) << "OnResponseStarted: " << request_->url().spec();
113
114 if (!request_->status().is_success()) {
115 ResponseCompleted();
116 return;
117 }
118
119 handler_->OnResponseStarted();
120
121 if (request_->status().is_success())
asanka 2015/12/08 16:58:33 I'm guessing you are copying logic in ResourceLoad
svaldez 2015/12/08 20:39:26 Acknowledged.
122 StartReading(false); // Read the first chunk.
123 else
124 ResponseCompleted();
125 }
126
127 void UrlDownloader::OnReadCompleted(net::URLRequest* request, int bytes_read) {
asanka 2015/12/08 16:58:33 Nit: let's move OnReadCompleted below StartReading
svaldez 2015/12/08 20:39:26 Done.
128 DVLOG(1) << "OnReadCompleted: \"" << request_->url().spec() << "\""
129 << " bytes_read = " << bytes_read;
130
131 // bytes_read == -1 always implies an error.
132 if (bytes_read == -1 || !request_->status().is_success()) {
133 ResponseCompleted();
134 return;
135 }
136
137 DCHECK(bytes_read >= 0);
138 DCHECK(request_->status().is_success());
139
140 bool defer = false;
141 if (!handler_->OnReadCompleted(bytes_read, &defer)) {
142 request_->CancelWithError(net::ERR_ABORTED);
143 return;
144 }
145 DCHECK(!defer);
asanka 2015/12/08 16:58:33 This is not correct. The ByteStreamWriter can requ
svaldez 2015/12/08 20:39:26 Done.
146
147 if (!request_->status().is_success())
148 return;
149
150 if (bytes_read > 0) {
151 StartReading(true); // Read the next chunk.
152 } else {
153 // URLRequest reported an EOF. Call ResponseCompleted.
154 DCHECK_EQ(0, bytes_read);
155 ResponseCompleted();
156 }
157 }
158
159 void UrlDownloader::StartReading(bool is_continuation) {
160 int bytes_read;
161
162 // Make sure we track the buffer in at least one place. This ensures it gets
163 // deleted even in the case the request has already finished its job and
164 // doesn't use the buffer.
165 scoped_refptr<net::IOBuffer> buf;
166 int buf_size;
167 if (!handler_->OnWillRead(&buf, &buf_size, -1)) {
168 request_->CancelWithError(net::ERR_ABORTED);
169 return;
asanka 2015/12/08 16:58:33 How does OnResponseCompleted() get called in this
svaldez 2015/12/08 20:39:26 Done.
170 }
171
172 DCHECK(buf.get());
173 DCHECK(buf_size > 0);
174
175 request_->Read(buf.get(), buf_size, &bytes_read);
176
177 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
178 if (request_->status().is_io_pending())
179 return;
180
181 if (!is_continuation || bytes_read <= 0) {
182 OnReadCompleted(request_.get(), bytes_read);
183 } else {
184 // Else, trigger OnReadCompleted asynchronously to avoid starving the IO
185 // thread in case the URLRequest can provide data synchronously.
186 base::ThreadTaskRunnerHandle::Get()->PostTask(
187 FROM_HERE,
188 base::Bind(&UrlDownloader::OnReadCompleted,
189 weak_ptr_factory_.GetWeakPtr(), request_.get(), bytes_read));
190 }
191 }
192
193 void UrlDownloader::ResponseCompleted() {
194 DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
195
196 handler_->OnResponseCompleted(request_->status());
asanka 2015/12/08 16:58:33 We should discard handler_ after this point since
svaldez 2015/12/08 20:39:26 Done.
197 }
198
199 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698