| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/url_request/url_fetcher_core.h" | 5 #include "net/url_request/url_fetcher_core.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_util_proxy.h" | 8 #include "base/files/file_util_proxy.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 request_type_(request_type), | 274 request_type_(request_type), |
| 275 delegate_(d), | 275 delegate_(d), |
| 276 delegate_task_runner_( | 276 delegate_task_runner_( |
| 277 base::ThreadTaskRunnerHandle::Get()), | 277 base::ThreadTaskRunnerHandle::Get()), |
| 278 request_(NULL), | 278 request_(NULL), |
| 279 load_flags_(LOAD_NORMAL), | 279 load_flags_(LOAD_NORMAL), |
| 280 response_code_(URLFetcher::RESPONSE_CODE_INVALID), | 280 response_code_(URLFetcher::RESPONSE_CODE_INVALID), |
| 281 buffer_(new IOBuffer(kBufferSize)), | 281 buffer_(new IOBuffer(kBufferSize)), |
| 282 url_request_data_key_(NULL), | 282 url_request_data_key_(NULL), |
| 283 was_fetched_via_proxy_(false), | 283 was_fetched_via_proxy_(false), |
| 284 upload_content_set_(false), |
| 284 is_chunked_upload_(false), | 285 is_chunked_upload_(false), |
| 285 was_cancelled_(false), | 286 was_cancelled_(false), |
| 286 response_destination_(STRING), | 287 response_destination_(STRING), |
| 287 stop_on_redirect_(false), | 288 stop_on_redirect_(false), |
| 288 stopped_on_redirect_(false), | 289 stopped_on_redirect_(false), |
| 289 automatically_retry_on_5xx_(true), | 290 automatically_retry_on_5xx_(true), |
| 290 num_retries_on_5xx_(0), | 291 num_retries_on_5xx_(0), |
| 291 max_retries_on_5xx_(0), | 292 max_retries_on_5xx_(0), |
| 292 num_retries_on_network_changes_(0), | 293 num_retries_on_network_changes_(0), |
| 293 max_retries_on_network_changes_(0), | 294 max_retries_on_network_changes_(0), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 324 CancelURLRequest(); | 325 CancelURLRequest(); |
| 325 } else { | 326 } else { |
| 326 network_task_runner_->PostTask( | 327 network_task_runner_->PostTask( |
| 327 FROM_HERE, base::Bind(&URLFetcherCore::CancelURLRequest, this)); | 328 FROM_HERE, base::Bind(&URLFetcherCore::CancelURLRequest, this)); |
| 328 } | 329 } |
| 329 } | 330 } |
| 330 | 331 |
| 331 void URLFetcherCore::SetUploadData(const std::string& upload_content_type, | 332 void URLFetcherCore::SetUploadData(const std::string& upload_content_type, |
| 332 const std::string& upload_content) { | 333 const std::string& upload_content) { |
| 333 DCHECK(!is_chunked_upload_); | 334 DCHECK(!is_chunked_upload_); |
| 334 DCHECK(!upload_content_); | 335 DCHECK(!upload_content_set_); |
| 336 DCHECK(upload_content_.empty()); |
| 335 DCHECK(upload_content_type_.empty()); | 337 DCHECK(upload_content_type_.empty()); |
| 336 | 338 |
| 337 // Empty |upload_content_type| is allowed iff the |upload_content| is empty. | 339 // Empty |upload_content_type| is allowed iff the |upload_content| is empty. |
| 338 DCHECK(upload_content.empty() || !upload_content_type.empty()); | 340 DCHECK(upload_content.empty() || !upload_content_type.empty()); |
| 339 | 341 |
| 340 upload_content_type_ = upload_content_type; | 342 upload_content_type_ = upload_content_type; |
| 341 scoped_ptr<UploadElementReader> reader( | 343 upload_content_ = upload_content; |
| 342 UploadOwnedBytesElementReader::CreateWithString(upload_content)); | 344 upload_content_set_ = true; |
| 343 upload_content_.reset(UploadDataStream::CreateWithReader(reader.Pass(), 0)); | |
| 344 } | |
| 345 | |
| 346 void URLFetcherCore::SetUploadDataStream( | |
| 347 const std::string& upload_content_type, | |
| 348 scoped_ptr<UploadDataStream> upload_content) { | |
| 349 DCHECK(!is_chunked_upload_); | |
| 350 DCHECK(!upload_content_); | |
| 351 DCHECK(upload_content_type_.empty()); | |
| 352 | |
| 353 // Empty |upload_content_type| is not allowed here, because it is impossible | |
| 354 // to ensure non-empty |upload_content| as it may not be initialized yet. | |
| 355 DCHECK(!upload_content_type.empty()); | |
| 356 | |
| 357 upload_content_type_ = upload_content_type; | |
| 358 upload_content_ = upload_content.Pass(); | |
| 359 } | 345 } |
| 360 | 346 |
| 361 void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { | 347 void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { |
| 362 DCHECK(is_chunked_upload_ || | 348 DCHECK(is_chunked_upload_ || |
| 363 (upload_content_type_.empty() && | 349 (upload_content_type_.empty() && |
| 364 !upload_content_)); | 350 upload_content_.empty())); |
| 365 | 351 |
| 366 // Empty |content_type| is not allowed here, because it is impossible | 352 // Empty |content_type| is not allowed here, because it is impossible |
| 367 // to ensure non-empty upload content as it is not yet supplied. | 353 // to ensure non-empty upload content as it is not yet supplied. |
| 368 DCHECK(!content_type.empty()); | 354 DCHECK(!content_type.empty()); |
| 369 | 355 |
| 370 upload_content_type_ = content_type; | 356 upload_content_type_ = content_type; |
| 371 upload_content_.reset(); | 357 upload_content_.clear(); |
| 372 is_chunked_upload_ = true; | 358 is_chunked_upload_ = true; |
| 373 } | 359 } |
| 374 | 360 |
| 375 void URLFetcherCore::AppendChunkToUpload(const std::string& content, | 361 void URLFetcherCore::AppendChunkToUpload(const std::string& content, |
| 376 bool is_last_chunk) { | 362 bool is_last_chunk) { |
| 377 DCHECK(delegate_task_runner_); | 363 DCHECK(delegate_task_runner_); |
| 378 DCHECK(network_task_runner_.get()); | 364 DCHECK(network_task_runner_.get()); |
| 379 network_task_runner_->PostTask( | 365 network_task_runner_->PostTask( |
| 380 FROM_HERE, | 366 FROM_HERE, |
| 381 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, | 367 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 } | 730 } |
| 745 | 731 |
| 746 switch (request_type_) { | 732 switch (request_type_) { |
| 747 case URLFetcher::GET: | 733 case URLFetcher::GET: |
| 748 break; | 734 break; |
| 749 | 735 |
| 750 case URLFetcher::POST: | 736 case URLFetcher::POST: |
| 751 case URLFetcher::PUT: | 737 case URLFetcher::PUT: |
| 752 case URLFetcher::PATCH: | 738 case URLFetcher::PATCH: |
| 753 // Upload content must be set. | 739 // Upload content must be set. |
| 754 DCHECK(is_chunked_upload_ || upload_content_); | 740 DCHECK(is_chunked_upload_ || upload_content_set_); |
| 755 | 741 |
| 756 request_->set_method( | 742 request_->set_method( |
| 757 request_type_ == URLFetcher::POST ? "POST" : | 743 request_type_ == URLFetcher::POST ? "POST" : |
| 758 request_type_ == URLFetcher::PUT ? "PUT" : "PATCH"); | 744 request_type_ == URLFetcher::PUT ? "PUT" : "PATCH"); |
| 745 extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, |
| 746 upload_content_type_); |
| 759 if (!upload_content_type_.empty()) { | 747 if (!upload_content_type_.empty()) { |
| 760 extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, | 748 extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, |
| 761 upload_content_type_); | 749 upload_content_type_); |
| 762 } | 750 } |
| 763 if (upload_content_) | 751 if (!upload_content_.empty()) { |
| 764 request_->set_upload(upload_content_.Pass()); | 752 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader( |
| 753 upload_content_.data(), upload_content_.size())); |
| 754 request_->set_upload(make_scoped_ptr( |
| 755 UploadDataStream::CreateWithReader(reader.Pass(), 0))); |
| 756 } |
| 757 |
| 765 current_upload_bytes_ = -1; | 758 current_upload_bytes_ = -1; |
| 766 // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the | 759 // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the |
| 767 // layer and avoid using timer here. | 760 // layer and avoid using timer here. |
| 768 upload_progress_checker_timer_.reset( | 761 upload_progress_checker_timer_.reset( |
| 769 new base::RepeatingTimer<URLFetcherCore>()); | 762 new base::RepeatingTimer<URLFetcherCore>()); |
| 770 upload_progress_checker_timer_->Start( | 763 upload_progress_checker_timer_->Start( |
| 771 FROM_HERE, | 764 FROM_HERE, |
| 772 base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval), | 765 base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval), |
| 773 this, | 766 this, |
| 774 &URLFetcherCore::InformDelegateUploadProgress); | 767 &URLFetcherCore::InformDelegateUploadProgress); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 file_writer_->DisownFile(); | 1012 file_writer_->DisownFile(); |
| 1020 } | 1013 } |
| 1021 | 1014 |
| 1022 void URLFetcherCore::InformDelegateUploadProgress() { | 1015 void URLFetcherCore::InformDelegateUploadProgress() { |
| 1023 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 1016 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 1024 if (request_.get()) { | 1017 if (request_.get()) { |
| 1025 int64 current = request_->GetUploadProgress().position(); | 1018 int64 current = request_->GetUploadProgress().position(); |
| 1026 if (current_upload_bytes_ != current) { | 1019 if (current_upload_bytes_ != current) { |
| 1027 current_upload_bytes_ = current; | 1020 current_upload_bytes_ = current; |
| 1028 int64 total = -1; | 1021 int64 total = -1; |
| 1029 if (!is_chunked_upload_) { | 1022 if (!is_chunked_upload_) |
| 1030 total = static_cast<int64>(request_->GetUploadProgress().size()); | 1023 total = static_cast<int64>(upload_content_.size()); |
| 1031 // Total may be zero if the UploadDataStream::Init has not been called | |
| 1032 // yet. Don't send the upload progress until the size is initialized. | |
| 1033 if (!total) | |
| 1034 return; | |
| 1035 } | |
| 1036 delegate_task_runner_->PostTask( | 1024 delegate_task_runner_->PostTask( |
| 1037 FROM_HERE, | 1025 FROM_HERE, |
| 1038 base::Bind( | 1026 base::Bind( |
| 1039 &URLFetcherCore::InformDelegateUploadProgressInDelegateThread, | 1027 &URLFetcherCore::InformDelegateUploadProgressInDelegateThread, |
| 1040 this, current, total)); | 1028 this, current, total)); |
| 1041 } | 1029 } |
| 1042 } | 1030 } |
| 1043 } | 1031 } |
| 1044 | 1032 |
| 1045 void URLFetcherCore::InformDelegateUploadProgressInDelegateThread( | 1033 void URLFetcherCore::InformDelegateUploadProgressInDelegateThread( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 } | 1067 } |
| 1080 | 1068 |
| 1081 void URLFetcherCore::InformDelegateDownloadDataInDelegateThread( | 1069 void URLFetcherCore::InformDelegateDownloadDataInDelegateThread( |
| 1082 scoped_ptr<std::string> download_data) { | 1070 scoped_ptr<std::string> download_data) { |
| 1083 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); | 1071 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); |
| 1084 if (delegate_) | 1072 if (delegate_) |
| 1085 delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass()); | 1073 delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass()); |
| 1086 } | 1074 } |
| 1087 | 1075 |
| 1088 } // namespace net | 1076 } // namespace net |
| OLD | NEW |