Chromium Code Reviews| 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 kReadBufferSize = 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()), | |
| 33 bytes_read_(0), | 32 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; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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() { |
| 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(); |
| 188 | 181 if (canceled_) { |
| 182 return; | |
| 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 OnRequestCanceled(); |
| 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)); |
| (...skipping 25 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_.get()) |
| 235 if (read_buffer_->RemainingCapacity() == 0) { | 231 read_buffer_ = new net::IOBufferWithSize(kReadBufferSize); |
| 236 int new_capacity = read_buffer_->capacity() + kBufferSizeIncrement; | |
| 237 read_buffer_->SetCapacity(new_capacity); | |
| 238 } | |
| 239 | 232 |
| 240 int bytes_read; | 233 int bytes_read = 0; |
| 241 if (url_request_->Read(read_buffer_.get(), | 234 url_request_->Read( |
| 242 read_buffer_->RemainingCapacity(), | 235 read_buffer_.get(), read_buffer_->size(), &bytes_read); |
| 243 &bytes_read)) { | 236 // If IO is pending, wait for the URLRequest to call OnReadCompleted. |
| 244 if (bytes_read == 0) { | 237 if (url_request_->status().is_io_pending()) |
| 245 OnRequestSucceeded(); | 238 return; |
| 246 break; | |
| 247 } | |
| 248 | 239 |
| 249 VLOG(1) << "Synchronously read: " << bytes_read << " bytes"; | 240 VLOG(1) << "Synchronously read: " << bytes_read << " bytes"; |
| 250 OnBytesRead(bytes_read); | 241 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 } | 242 } |
| 268 | 243 |
| 269 void URLRequestAdapter::OnReadCompleted(net::URLRequest* request, | 244 void URLRequestAdapter::OnReadCompleted(net::URLRequest* request, |
| 270 int bytes_read) { | 245 int bytes_read) { |
| 271 DCHECK(OnNetworkThread()); | 246 DCHECK(OnNetworkThread()); |
| 272 VLOG(1) << "Asynchronously read: " << bytes_read << " bytes"; | 247 VLOG(1) << "Completed read: " << bytes_read << " bytes"; |
| 273 if (bytes_read < 0) { | 248 if (!url_request_->status().is_success()) { |
|
miloslav
2014/11/26 10:44:35
Could url_request_->status().is_success() be false
mef
2014/11/26 14:06:21
We use the same logic in other places and I would
| |
| 274 OnRequestFailed(); | 249 OnRequestFailed(); |
| 275 return; | 250 return; |
| 276 } else if (bytes_read == 0) { | 251 } else if (bytes_read == 0) { |
| 277 OnRequestSucceeded(); | 252 OnRequestSucceeded(); |
| 278 return; | 253 return; |
| 279 } | 254 } |
| 280 | 255 |
| 281 OnBytesRead(bytes_read); | 256 OnBytesRead(bytes_read); |
| 282 Read(); | 257 Read(); |
| 283 } | 258 } |
| 284 | 259 |
| 285 void URLRequestAdapter::OnReceivedRedirect(net::URLRequest* request, | 260 void URLRequestAdapter::OnReceivedRedirect(net::URLRequest* request, |
| 286 const net::RedirectInfo& info, | 261 const net::RedirectInfo& info, |
| 287 bool* defer_redirect) { | 262 bool* defer_redirect) { |
| 288 DCHECK(OnNetworkThread()); | 263 DCHECK(OnNetworkThread()); |
| 289 if (disable_redirect_) { | 264 if (disable_redirect_) { |
| 290 http_status_code_ = request->GetResponseCode(); | 265 http_status_code_ = request->GetResponseCode(); |
| 291 request->CancelWithError(net::ERR_TOO_MANY_REDIRECTS); | 266 request->CancelWithError(net::ERR_TOO_MANY_REDIRECTS); |
| 292 error_code_ = net::ERR_TOO_MANY_REDIRECTS; | 267 error_code_ = net::ERR_TOO_MANY_REDIRECTS; |
| 293 canceled_ = true; | 268 canceled_ = true; |
| 294 *defer_redirect = false; | 269 *defer_redirect = false; |
| 295 OnRequestCompleted(); | 270 OnRequestCompleted(); |
| 296 } | 271 } |
| 297 } | 272 } |
| 298 | 273 |
| 299 void URLRequestAdapter::OnBytesRead(int bytes_read) { | 274 void URLRequestAdapter::OnBytesRead(int bytes_read) { |
| 300 DCHECK(OnNetworkThread()); | 275 DCHECK(OnNetworkThread()); |
| 301 read_buffer_->set_offset(read_buffer_->offset() + bytes_read); | 276 bytes_read_ = bytes_read; |
| 302 bytes_read_ += bytes_read; | |
| 303 total_bytes_read_ += bytes_read; | 277 total_bytes_read_ += bytes_read; |
| 278 delegate_->OnBytesRead(this); | |
| 304 } | 279 } |
| 305 | 280 |
| 306 void URLRequestAdapter::OnRequestSucceeded() { | 281 void URLRequestAdapter::OnRequestSucceeded() { |
| 307 DCHECK(OnNetworkThread()); | 282 DCHECK(OnNetworkThread()); |
| 308 if (canceled_) { | 283 if (canceled_) { |
| 309 return; | 284 return; |
| 310 } | 285 } |
| 311 | 286 |
| 312 VLOG(1) << "Request completed with HTTP status: " << http_status_code_ | 287 VLOG(1) << "Request completed with HTTP status: " << http_status_code_ |
| 313 << ". Total bytes read: " << total_bytes_read_; | 288 << ". Total bytes read: " << total_bytes_read_; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 329 | 304 |
| 330 void URLRequestAdapter::OnRequestCanceled() { | 305 void URLRequestAdapter::OnRequestCanceled() { |
| 331 DCHECK(OnNetworkThread()); | 306 DCHECK(OnNetworkThread()); |
| 332 OnRequestCompleted(); | 307 OnRequestCompleted(); |
| 333 } | 308 } |
| 334 | 309 |
| 335 void URLRequestAdapter::OnRequestCompleted() { | 310 void URLRequestAdapter::OnRequestCompleted() { |
| 336 DCHECK(OnNetworkThread()); | 311 DCHECK(OnNetworkThread()); |
| 337 VLOG(1) << "Completed: " << url_.possibly_invalid_spec(); | 312 VLOG(1) << "Completed: " << url_.possibly_invalid_spec(); |
| 338 | 313 |
| 339 delegate_->OnBytesRead(this); | 314 if (url_request_ == nullptr) |
|
mef
2014/11/26 14:14:28
I believe that calling OnBytesRead in combination
|
mmenke
2014/11/26 14:07:43
I'm assuming this compiles? Didn't realize scoped
mef
2014/11/26 14:14:28
Should I add .get() for clarity?
mmenke
2014/11/26 14:34:14
If it works, I'm assuming it's supposed to work, s
|
| 315 return; | |
| 316 | |
| 340 delegate_->OnRequestFinished(this); | 317 delegate_->OnRequestFinished(this); |
| 341 url_request_.reset(); | 318 url_request_.reset(); |
| 342 } | 319 } |
| 343 | 320 |
| 344 unsigned char* URLRequestAdapter::Data() const { | 321 unsigned char* URLRequestAdapter::Data() const { |
| 345 DCHECK(OnNetworkThread()); | 322 DCHECK(OnNetworkThread()); |
| 346 return reinterpret_cast<unsigned char*>(read_buffer_->StartOfBuffer()); | 323 return reinterpret_cast<unsigned char*>(read_buffer_->data()); |
| 347 } | 324 } |
| 348 | 325 |
| 349 bool URLRequestAdapter::OnNetworkThread() const { | 326 bool URLRequestAdapter::OnNetworkThread() const { |
| 350 return context_->GetNetworkTaskRunner()->BelongsToCurrentThread(); | 327 return context_->GetNetworkTaskRunner()->BelongsToCurrentThread(); |
| 351 } | 328 } |
| 352 | 329 |
| 353 } // namespace cronet | 330 } // namespace cronet |
| OLD | NEW |