OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "url_request_adapter.h" | 5 #include "url_request_adapter.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "components/cronet/android/url_request_context_adapter.h" | 14 #include "components/cronet/android/url_request_context_adapter.h" |
15 #include "components/cronet/android/wrapped_channel_upload_element_reader.h" | 15 #include "components/cronet/android/wrapped_channel_upload_element_reader.h" |
16 #include "net/base/elements_upload_data_stream.h" | 16 #include "net/base/elements_upload_data_stream.h" |
17 #include "net/base/load_flags.h" | 17 #include "net/base/load_flags.h" |
18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
19 #include "net/base/upload_bytes_element_reader.h" | 19 #include "net/base/upload_bytes_element_reader.h" |
20 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
21 #include "net/http/http_status_code.h" | 21 #include "net/http/http_status_code.h" |
22 | 22 |
23 namespace cronet { | 23 namespace cronet { |
24 | 24 |
25 static const size_t kBufferSizeIncrement = 8192; | 25 static const size_t kBufferSizeIncrement = 32768; |
26 | 26 |
27 URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context, | 27 URLRequestAdapter::URLRequestAdapter(URLRequestContextAdapter* context, |
28 URLRequestAdapterDelegate* delegate, | 28 URLRequestAdapterDelegate* delegate, |
29 GURL url, | 29 GURL url, |
30 net::RequestPriority priority) | 30 net::RequestPriority priority) |
31 : method_("GET"), | 31 : method_("GET"), |
32 read_buffer_(new net::GrowableIOBuffer()), | 32 read_buffer_(new net::GrowableIOBuffer()), |
33 bytes_read_(0), | |
34 total_bytes_read_(0), | 33 total_bytes_read_(0), |
35 error_code_(0), | 34 error_code_(0), |
36 http_status_code_(0), | 35 http_status_code_(0), |
37 canceled_(false), | 36 canceled_(false), |
38 expected_size_(0), | 37 expected_size_(0), |
39 chunked_upload_(false), | 38 chunked_upload_(false), |
40 disable_redirect_(false) { | 39 disable_redirect_(false) { |
41 context_ = context; | 40 context_ = context; |
42 delegate_ = delegate; | 41 delegate_ = delegate; |
43 url_ = url; | 42 url_ = url; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 url_request_->set_upload(upload_data_stream_.Pass()); | 162 url_request_->set_upload(upload_data_stream_.Pass()); |
164 } else if (chunked_upload_) { | 163 } else if (chunked_upload_) { |
165 url_request_->EnableChunkedUpload(); | 164 url_request_->EnableChunkedUpload(); |
166 } | 165 } |
167 | 166 |
168 url_request_->SetPriority(priority_); | 167 url_request_->SetPriority(priority_); |
169 | 168 |
170 url_request_->Start(); | 169 url_request_->Start(); |
171 } | 170 } |
172 | 171 |
173 void URLRequestAdapter::Cancel() { | 172 void URLRequestAdapter::Cancel() { |
mmenke
2014/12/02 20:33:47
Problem: What if cancel is called on the network
mef
2014/12/05 23:25:07
Done. I don't think embedder can expect immediate
| |
174 if (canceled_) { | |
175 return; | |
176 } | |
177 | |
178 canceled_ = true; | |
179 | |
180 context_->PostTaskToNetworkThread( | 173 context_->PostTaskToNetworkThread( |
181 FROM_HERE, | 174 FROM_HERE, |
182 base::Bind(&URLRequestAdapter::OnCancelRequest, base::Unretained(this))); | 175 base::Bind(&URLRequestAdapter::OnCancelRequest, base::Unretained(this))); |
183 } | 176 } |
184 | 177 |
185 void URLRequestAdapter::OnCancelRequest() { | 178 void URLRequestAdapter::OnCancelRequest() { |
186 DCHECK(OnNetworkThread()); | 179 DCHECK(OnNetworkThread()); |
187 VLOG(1) << "Canceling chromium request: " << url_.possibly_invalid_spec(); | 180 VLOG(1) << "Canceling chromium request: " << url_.possibly_invalid_spec(); |
181 if (canceled_) | |
182 return; | |
188 | 183 |
184 canceled_ = true; | |
189 if (url_request_ != NULL) { | 185 if (url_request_ != NULL) { |
190 url_request_->Cancel(); | 186 url_request_->Cancel(); |
191 } | 187 } |
192 | 188 |
193 OnRequestCanceled(); | 189 OnRequestCompleted(); |
194 } | 190 } |
195 | 191 |
196 void URLRequestAdapter::Destroy() { | 192 void URLRequestAdapter::Destroy() { |
197 context_->PostTaskToNetworkThread( | 193 context_->PostTaskToNetworkThread( |
198 FROM_HERE, base::Bind(&URLRequestAdapter::OnDestroyRequest, this)); | 194 FROM_HERE, base::Bind(&URLRequestAdapter::OnDestroyRequest, this)); |
199 } | 195 } |
200 | 196 |
201 // static | 197 // static |
202 void URLRequestAdapter::OnDestroyRequest(URLRequestAdapter* self) { | 198 void URLRequestAdapter::OnDestroyRequest(URLRequestAdapter* self) { |
203 DCHECK(self->OnNetworkThread()); | 199 DCHECK(self->OnNetworkThread()); |
(...skipping 20 matching lines...) Expand all Loading... | |
224 request->GetResponseHeaderByName("Content-Type", &content_type_); | 220 request->GetResponseHeaderByName("Content-Type", &content_type_); |
225 expected_size_ = request->GetExpectedContentSize(); | 221 expected_size_ = request->GetExpectedContentSize(); |
226 delegate_->OnResponseStarted(this); | 222 delegate_->OnResponseStarted(this); |
227 | 223 |
228 Read(); | 224 Read(); |
229 } | 225 } |
230 | 226 |
231 // Reads all available data or starts an asynchronous read. | 227 // Reads all available data or starts an asynchronous read. |
232 void URLRequestAdapter::Read() { | 228 void URLRequestAdapter::Read() { |
233 DCHECK(OnNetworkThread()); | 229 DCHECK(OnNetworkThread()); |
234 while (true) { | 230 if (read_buffer_->RemainingCapacity() == 0) { |
235 if (read_buffer_->RemainingCapacity() == 0) { | 231 int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement; |
236 int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement; | 232 read_buffer_->SetCapacity(new_capacity); |
237 read_buffer_->SetCapacity(new_capacity); | 233 } |
238 } | |
239 | 234 |
240 int bytes_read; | 235 int bytes_read = 0; |
241 if (url_request_->Read(read_buffer_.get(), | 236 url_request_->Read( |
242 read_buffer_->RemainingCapacity(), | 237 read_buffer_.get(), read_buffer_->RemainingCapacity(), &bytes_read); |
243 &bytes_read)) { | 238 // If IO is pending, wait for the URLRequest to call OnReadCompleted. |
244 if (bytes_read == 0) { | 239 if (url_request_->status().is_io_pending()) |
245 OnRequestSucceeded(); | 240 return; |
246 break; | |
247 } | |
248 | 241 |
249 VLOG(1) << "Synchronously read: " << bytes_read << " bytes"; | 242 VLOG(1) << "Synchronously read: " << bytes_read << " bytes"; |
250 OnBytesRead(bytes_read); | 243 OnReadCompleted(url_request_.get(), bytes_read); |
251 } else if (url_request_->status().status() == | |
252 net::URLRequestStatus::IO_PENDING) { | |
253 if (bytes_read_ != 0) { | |
254 VLOG(1) << "Flushing buffer: " << bytes_read_ << " bytes"; | |
255 | |
256 delegate_->OnBytesRead(this); | |
257 read_buffer_->set_offset(0); | |
258 bytes_read_ = 0; | |
259 } | |
260 VLOG(1) << "Started async read"; | |
261 break; | |
262 } else { | |
263 OnRequestFailed(); | |
264 break; | |
265 } | |
266 } | |
267 } | 244 } |
268 | 245 |
269 void URLRequestAdapter::OnReadCompleted(net::URLRequest* request, | 246 void URLRequestAdapter::OnReadCompleted(net::URLRequest* request, |
270 int bytes_read) { | 247 int bytes_read) { |
271 DCHECK(OnNetworkThread()); | 248 DCHECK(OnNetworkThread()); |
272 VLOG(1) << "Asynchronously read: " << bytes_read << " bytes"; | 249 VLOG(1) << "Completed read: " << bytes_read << " bytes"; |
273 if (bytes_read < 0) { | 250 if (!url_request_->status().is_success()) { |
274 OnRequestFailed(); | 251 OnRequestFailed(); |
275 return; | 252 return; |
276 } else if (bytes_read == 0) { | 253 } else if (bytes_read == 0) { |
277 OnRequestSucceeded(); | 254 OnRequestSucceeded(); |
278 return; | 255 return; |
279 } | 256 } |
280 | 257 |
281 OnBytesRead(bytes_read); | 258 total_bytes_read_ += bytes_read; |
259 delegate_->OnBytesRead(this, bytes_read); | |
260 read_buffer_->set_offset(0); | |
261 | |
282 Read(); | 262 Read(); |
263 // context_->PostTaskToNetworkThread( | |
264 // FROM_HERE, | |
265 // base::Bind(&URLRequestAdapter::Read, base::Unretained(this))); | |
283 } | 266 } |
284 | 267 |
285 void URLRequestAdapter::OnReceivedRedirect(net::URLRequest* request, | 268 void URLRequestAdapter::OnReceivedRedirect(net::URLRequest* request, |
286 const net::RedirectInfo& info, | 269 const net::RedirectInfo& info, |
287 bool* defer_redirect) { | 270 bool* defer_redirect) { |
288 DCHECK(OnNetworkThread()); | 271 DCHECK(OnNetworkThread()); |
289 if (disable_redirect_) { | 272 if (disable_redirect_) { |
290 http_status_code_ = request->GetResponseCode(); | 273 http_status_code_ = request->GetResponseCode(); |
291 request->CancelWithError(net::ERR_TOO_MANY_REDIRECTS); | 274 request->CancelWithError(net::ERR_TOO_MANY_REDIRECTS); |
292 error_code_ = net::ERR_TOO_MANY_REDIRECTS; | 275 error_code_ = net::ERR_TOO_MANY_REDIRECTS; |
293 canceled_ = true; | 276 canceled_ = true; |
294 *defer_redirect = false; | 277 *defer_redirect = false; |
295 OnRequestCompleted(); | 278 OnRequestCompleted(); |
296 } | 279 } |
297 } | 280 } |
298 | 281 |
299 void URLRequestAdapter::OnBytesRead(int bytes_read) { | |
300 DCHECK(OnNetworkThread()); | |
301 read_buffer_->set_offset(read_buffer_->offset() + bytes_read); | |
302 bytes_read_ += bytes_read; | |
303 total_bytes_read_ += bytes_read; | |
304 } | |
305 | |
306 void URLRequestAdapter::OnRequestSucceeded() { | 282 void URLRequestAdapter::OnRequestSucceeded() { |
307 DCHECK(OnNetworkThread()); | 283 DCHECK(OnNetworkThread()); |
308 if (canceled_) { | 284 if (canceled_) { |
309 return; | 285 return; |
310 } | 286 } |
311 | 287 |
312 VLOG(1) << "Request completed with HTTP status: " << http_status_code_ | 288 VLOG(1) << "Request completed with HTTP status: " << http_status_code_ |
313 << ". Total bytes read: " << total_bytes_read_; | 289 << ". Total bytes read: " << total_bytes_read_; |
314 | 290 |
315 OnRequestCompleted(); | 291 OnRequestCompleted(); |
316 } | 292 } |
317 | 293 |
318 void URLRequestAdapter::OnRequestFailed() { | 294 void URLRequestAdapter::OnRequestFailed() { |
319 DCHECK(OnNetworkThread()); | 295 DCHECK(OnNetworkThread()); |
320 if (canceled_) { | 296 if (canceled_) { |
321 return; | 297 return; |
322 } | 298 } |
323 | 299 |
324 error_code_ = url_request_->status().error(); | 300 error_code_ = url_request_->status().error(); |
325 VLOG(1) << "Request failed with status: " << url_request_->status().status() | 301 VLOG(1) << "Request failed with status: " << url_request_->status().status() |
326 << " and error: " << net::ErrorToString(error_code_); | 302 << " and error: " << net::ErrorToString(error_code_); |
327 OnRequestCompleted(); | 303 OnRequestCompleted(); |
328 } | 304 } |
329 | 305 |
330 void URLRequestAdapter::OnRequestCanceled() { | |
331 DCHECK(OnNetworkThread()); | |
332 OnRequestCompleted(); | |
333 } | |
334 | |
335 void URLRequestAdapter::OnRequestCompleted() { | 306 void URLRequestAdapter::OnRequestCompleted() { |
336 DCHECK(OnNetworkThread()); | 307 DCHECK(OnNetworkThread()); |
337 VLOG(1) << "Completed: " << url_.possibly_invalid_spec(); | 308 VLOG(1) << "Completed: " << url_.possibly_invalid_spec(); |
338 | 309 |
339 delegate_->OnBytesRead(this); | 310 if (url_request_ == nullptr) |
311 return; | |
312 | |
340 delegate_->OnRequestFinished(this); | 313 delegate_->OnRequestFinished(this); |
341 url_request_.reset(); | 314 url_request_.reset(); |
342 } | 315 } |
343 | 316 |
344 unsigned char* URLRequestAdapter::Data() const { | 317 unsigned char* URLRequestAdapter::Data() const { |
345 DCHECK(OnNetworkThread()); | 318 DCHECK(OnNetworkThread()); |
346 return reinterpret_cast<unsigned char*>(read_buffer_->StartOfBuffer()); | 319 return reinterpret_cast<unsigned char*>(read_buffer_->StartOfBuffer()); |
347 } | 320 } |
348 | 321 |
349 bool URLRequestAdapter::OnNetworkThread() const { | 322 bool URLRequestAdapter::OnNetworkThread() const { |
350 return context_->GetNetworkTaskRunner()->BelongsToCurrentThread(); | 323 return context_->GetNetworkTaskRunner()->BelongsToCurrentThread(); |
351 } | 324 } |
352 | 325 |
353 } // namespace cronet | 326 } // namespace cronet |
OLD | NEW |