Clean up extension confirmation prompts and make them consistent between Views and...
[chromium-blink-merge.git] / components / cronet / android / url_request_adapter.cc
blob43fb8f416b98e2d85b79c82ffff70d2d1ced11ec
1 // Copyright 2014 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.
5 #include "url_request_adapter.h"
7 #include <string.h>
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "components/cronet/android/url_request_context_adapter.h"
15 #include "components/cronet/android/wrapped_channel_upload_element_reader.h"
16 #include "net/base/elements_upload_data_stream.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/upload_bytes_element_reader.h"
20 #include "net/http/http_response_headers.h"
21 #include "net/http/http_status_code.h"
23 namespace cronet {
25 static const size_t kReadBufferSize = 32768;
27 URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context,
28 URLRequestAdapterDelegate* delegate,
29 GURL url,
30 net::RequestPriority priority)
31 : method_("GET"),
32 total_bytes_read_(0),
33 error_code_(0),
34 http_status_code_(0),
35 canceled_(false),
36 expected_size_(0),
37 chunked_upload_(false),
38 disable_redirect_(false) {
39 context_ = context;
40 delegate_ = delegate;
41 url_ = url;
42 priority_ = priority;
45 URLRequestAdapter::~URLRequestAdapter() {
46 DCHECK(OnNetworkThread());
47 CHECK(url_request_ == NULL);
50 void URLRequestAdapter::SetMethod(const std::string& method) {
51 method_ = method;
54 void URLRequestAdapter::AddHeader(const std::string& name,
55 const std::string& value) {
56 headers_.SetHeader(name, value);
59 void URLRequestAdapter::SetUploadContent(const char* bytes, int bytes_len) {
60 std::vector<char> data(bytes, bytes + bytes_len);
61 scoped_ptr<net::UploadElementReader> reader(
62 new net::UploadOwnedBytesElementReader(&data));
63 upload_data_stream_ =
64 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0);
67 void URLRequestAdapter::SetUploadChannel(JNIEnv* env, int64 content_length) {
68 scoped_ptr<net::UploadElementReader> reader(
69 new WrappedChannelElementReader(delegate_, content_length));
70 upload_data_stream_ =
71 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0);
74 void URLRequestAdapter::DisableRedirects() {
75 disable_redirect_ = true;
78 void URLRequestAdapter::EnableChunkedUpload() {
79 chunked_upload_ = true;
82 void URLRequestAdapter::AppendChunk(const char* bytes, int bytes_len,
83 bool is_last_chunk) {
84 VLOG(1) << "AppendChunk, len: " << bytes_len << ", last: " << is_last_chunk;
85 scoped_ptr<char[]> buf(new char[bytes_len]);
86 memcpy(buf.get(), bytes, bytes_len);
87 context_->PostTaskToNetworkThread(
88 FROM_HERE,
89 base::Bind(&URLRequestAdapter::OnAppendChunk,
90 base::Unretained(this),
91 Passed(buf.Pass()),
92 bytes_len,
93 is_last_chunk));
96 std::string URLRequestAdapter::GetHeader(const std::string& name) const {
97 std::string value;
98 if (url_request_ != NULL) {
99 url_request_->GetResponseHeaderByName(name, &value);
101 return value;
104 net::HttpResponseHeaders* URLRequestAdapter::GetResponseHeaders() const {
105 if (url_request_ == NULL) {
106 return NULL;
108 return url_request_->response_headers();
111 std::string URLRequestAdapter::GetNegotiatedProtocol() const {
112 if (url_request_ == NULL)
113 return std::string();
114 return url_request_->response_info().npn_negotiated_protocol;
117 bool URLRequestAdapter::GetWasCached() const {
118 if (url_request_ == NULL)
119 return false;
120 return url_request_->response_info().was_cached;
123 void URLRequestAdapter::Start() {
124 context_->PostTaskToNetworkThread(
125 FROM_HERE,
126 base::Bind(&URLRequestAdapter::OnInitiateConnection,
127 base::Unretained(this)));
130 void URLRequestAdapter::OnAppendChunk(const scoped_ptr<char[]> bytes,
131 int bytes_len, bool is_last_chunk) {
132 DCHECK(OnNetworkThread());
133 // Request could have completed and been destroyed on the network thread
134 // while appendChunk was posting the task from an application thread.
135 if (!url_request_) {
136 VLOG(1) << "Cannot append chunk to destroyed request: "
137 << url_.possibly_invalid_spec().c_str();
138 return;
140 url_request_->AppendChunkToUpload(bytes.get(), bytes_len, is_last_chunk);
143 void URLRequestAdapter::OnInitiateConnection() {
144 DCHECK(OnNetworkThread());
145 if (canceled_) {
146 return;
149 VLOG(1) << "Starting chromium request: "
150 << url_.possibly_invalid_spec().c_str()
151 << " priority: " << RequestPriorityToString(priority_);
152 url_request_ = context_->GetURLRequestContext()->CreateRequest(
153 url_, net::DEFAULT_PRIORITY, this);
154 int flags = net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES;
155 if (context_->load_disable_cache())
156 flags |= net::LOAD_DISABLE_CACHE;
157 url_request_->SetLoadFlags(flags);
158 url_request_->set_method(method_);
159 url_request_->SetExtraRequestHeaders(headers_);
160 if (!headers_.HasHeader(net::HttpRequestHeaders::kUserAgent)) {
161 std::string user_agent;
162 user_agent = context_->GetUserAgent(url_);
163 url_request_->SetExtraRequestHeaderByName(
164 net::HttpRequestHeaders::kUserAgent, user_agent, true /* override */);
167 if (upload_data_stream_) {
168 url_request_->set_upload(upload_data_stream_.Pass());
169 } else if (chunked_upload_) {
170 url_request_->EnableChunkedUpload();
173 url_request_->SetPriority(priority_);
175 url_request_->Start();
178 void URLRequestAdapter::Cancel() {
179 context_->PostTaskToNetworkThread(
180 FROM_HERE,
181 base::Bind(&URLRequestAdapter::OnCancelRequest, base::Unretained(this)));
184 void URLRequestAdapter::OnCancelRequest() {
185 DCHECK(OnNetworkThread());
186 DCHECK(!canceled_);
187 VLOG(1) << "Canceling chromium request: " << url_.possibly_invalid_spec();
188 canceled_ = true;
189 // Check whether request has already completed.
190 if (url_request_ == nullptr)
191 return;
193 url_request_->Cancel();
194 OnRequestCompleted();
197 void URLRequestAdapter::Destroy() {
198 context_->PostTaskToNetworkThread(
199 FROM_HERE, base::Bind(&URLRequestAdapter::OnDestroyRequest, this));
202 // static
203 void URLRequestAdapter::OnDestroyRequest(URLRequestAdapter* self) {
204 DCHECK(self->OnNetworkThread());
205 VLOG(1) << "Destroying chromium request: "
206 << self->url_.possibly_invalid_spec();
207 delete self;
210 // static
211 void URLRequestAdapter::OnResponseStarted(net::URLRequest* request) {
212 DCHECK(OnNetworkThread());
213 if (request->status().status() != net::URLRequestStatus::SUCCESS) {
214 OnRequestFailed();
215 return;
218 http_status_code_ = request->GetResponseCode();
219 VLOG(1) << "Response started with status: " << http_status_code_;
221 net::HttpResponseHeaders* headers = request->response_headers();
222 if (headers)
223 http_status_text_ = headers->GetStatusText();
225 request->GetResponseHeaderByName("Content-Type", &content_type_);
226 expected_size_ = request->GetExpectedContentSize();
227 delegate_->OnResponseStarted(this);
229 Read();
232 // Reads all available data or starts an asynchronous read.
233 void URLRequestAdapter::Read() {
234 DCHECK(OnNetworkThread());
235 if (!read_buffer_.get())
236 read_buffer_ = new net::IOBufferWithSize(kReadBufferSize);
238 while(true) {
239 int bytes_read = 0;
240 url_request_->Read(read_buffer_.get(), kReadBufferSize, &bytes_read);
241 // If IO is pending, wait for the URLRequest to call OnReadCompleted.
242 if (url_request_->status().is_io_pending())
243 return;
244 // Stop when request has failed or succeeded.
245 if (!HandleReadResult(bytes_read))
246 return;
250 bool URLRequestAdapter::HandleReadResult(int bytes_read) {
251 DCHECK(OnNetworkThread());
252 if (!url_request_->status().is_success()) {
253 OnRequestFailed();
254 return false;
255 } else if (bytes_read == 0) {
256 OnRequestSucceeded();
257 return false;
260 total_bytes_read_ += bytes_read;
261 delegate_->OnBytesRead(this, bytes_read);
263 return true;
266 void URLRequestAdapter::OnReadCompleted(net::URLRequest* request,
267 int bytes_read) {
268 if (!HandleReadResult(bytes_read))
269 return;
271 Read();
274 void URLRequestAdapter::OnReceivedRedirect(net::URLRequest* request,
275 const net::RedirectInfo& info,
276 bool* defer_redirect) {
277 DCHECK(OnNetworkThread());
278 if (disable_redirect_) {
279 http_status_code_ = request->GetResponseCode();
280 request->CancelWithError(net::ERR_TOO_MANY_REDIRECTS);
281 error_code_ = net::ERR_TOO_MANY_REDIRECTS;
282 canceled_ = true;
283 *defer_redirect = false;
284 OnRequestCompleted();
288 void URLRequestAdapter::OnRequestSucceeded() {
289 DCHECK(OnNetworkThread());
290 if (canceled_) {
291 return;
294 VLOG(1) << "Request completed with HTTP status: " << http_status_code_
295 << ". Total bytes read: " << total_bytes_read_;
297 OnRequestCompleted();
300 void URLRequestAdapter::OnRequestFailed() {
301 DCHECK(OnNetworkThread());
302 if (canceled_) {
303 return;
306 error_code_ = url_request_->status().error();
307 VLOG(1) << "Request failed with status: " << url_request_->status().status()
308 << " and error: " << net::ErrorToString(error_code_);
309 OnRequestCompleted();
312 void URLRequestAdapter::OnRequestCompleted() {
313 DCHECK(OnNetworkThread());
314 VLOG(1) << "Completed: " << url_.possibly_invalid_spec();
316 DCHECK(url_request_ != nullptr);
318 delegate_->OnRequestFinished(this);
319 url_request_.reset();
322 unsigned char* URLRequestAdapter::Data() const {
323 DCHECK(OnNetworkThread());
324 return reinterpret_cast<unsigned char*>(read_buffer_->data());
327 bool URLRequestAdapter::OnNetworkThread() const {
328 return context_->GetNetworkTaskRunner()->BelongsToCurrentThread();
331 } // namespace cronet