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

Side by Side Diff: net/url_request/url_fetcher_core.cc

Issue 12224066: Fix UrlFetcher upload retry handling. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Explicitly forbid retries for chunked uploads Created 7 years, 10 months 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
« no previous file with comments | « net/url_request/url_fetcher_core.h ('k') | net/url_request/url_fetcher_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 CancelURLRequest(); 324 CancelURLRequest();
325 } else { 325 } else {
326 network_task_runner_->PostTask( 326 network_task_runner_->PostTask(
327 FROM_HERE, base::Bind(&URLFetcherCore::CancelURLRequest, this)); 327 FROM_HERE, base::Bind(&URLFetcherCore::CancelURLRequest, this));
328 } 328 }
329 } 329 }
330 330
331 void URLFetcherCore::SetUploadData(const std::string& upload_content_type, 331 void URLFetcherCore::SetUploadData(const std::string& upload_content_type,
332 const std::string& upload_content) { 332 const std::string& upload_content) {
333 DCHECK(!is_chunked_upload_); 333 DCHECK(!is_chunked_upload_);
334 DCHECK(!upload_content_); 334 DCHECK(!upload_data_stream_);
335 DCHECK(upload_content_type_.empty());
336
337 // Empty |upload_content_type| is allowed iff the |upload_content| is empty.
338 DCHECK(upload_content.empty() || !upload_content_type.empty());
339
340 upload_content_type_ = upload_content_type; 335 upload_content_type_ = upload_content_type;
341 scoped_ptr<UploadElementReader> reader( 336 upload_content_ = upload_content;
342 UploadOwnedBytesElementReader::CreateWithString(upload_content));
343 upload_content_.reset(UploadDataStream::CreateWithReader(reader.Pass(), 0));
344 } 337 }
345 338
346 void URLFetcherCore::SetUploadDataStream( 339 void URLFetcherCore::SetUploadDataStream(
347 const std::string& upload_content_type, 340 const std::string& upload_content_type,
348 scoped_ptr<UploadDataStream> upload_content) { 341 scoped_ptr<UploadDataStream> upload_data_stream) {
349 DCHECK(!is_chunked_upload_); 342 DCHECK(!is_chunked_upload_);
350 DCHECK(!upload_content_); 343 DCHECK(upload_content_.empty());
344 DCHECK(!upload_data_stream_);
351 DCHECK(upload_content_type_.empty()); 345 DCHECK(upload_content_type_.empty());
352 346
347 // Data stream uploading can't be retried, as the stream can't be restarted.
348 DCHECK(!automatically_retry_on_5xx_ || max_retries_on_5xx_ == 0);
349 DCHECK_EQ(max_retries_on_network_changes_, 0);
Joao da Silva 2013/02/13 10:53:18 Same for max_retries_on_network_changes_
350
353 // Empty |upload_content_type| is not allowed here, because it is impossible 351 // 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. 352 // to ensure non-empty |upload_content| as it may not be initialized yet.
355 DCHECK(!upload_content_type.empty()); 353 DCHECK(!upload_content_type.empty());
356 354
357 upload_content_type_ = upload_content_type; 355 upload_content_type_ = upload_content_type;
358 upload_content_ = upload_content.Pass(); 356 upload_data_stream_ = upload_data_stream.Pass();
359 } 357 }
360 358
361 void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { 359 void URLFetcherCore::SetChunkedUpload(const std::string& content_type) {
362 DCHECK(is_chunked_upload_ || 360 DCHECK(is_chunked_upload_ ||
363 (upload_content_type_.empty() && 361 (upload_content_type_.empty() &&
364 !upload_content_)); 362 upload_content_.empty() &&
363 !upload_data_stream_));
364
365 // Chunked uploading can't be retried, as chunked data may have been directly
366 // added to the previous URLRequest object.
367 DCHECK(!automatically_retry_on_5xx_ || max_retries_on_5xx_ == 0);
368 DCHECK_EQ(max_retries_on_network_changes_, 0);
Joao da Silva 2013/02/13 10:53:18 Same here
365 369
366 // Empty |content_type| is not allowed here, because it is impossible 370 // Empty |content_type| is not allowed here, because it is impossible
367 // to ensure non-empty upload content as it is not yet supplied. 371 // to ensure non-empty upload content as it is not yet supplied.
368 DCHECK(!content_type.empty()); 372 DCHECK(!content_type.empty());
369 373
370 upload_content_type_ = content_type; 374 upload_content_type_ = content_type;
371 upload_content_.reset(); 375 upload_content_.clear();
372 is_chunked_upload_ = true; 376 is_chunked_upload_ = true;
373 } 377 }
374 378
375 void URLFetcherCore::AppendChunkToUpload(const std::string& content, 379 void URLFetcherCore::AppendChunkToUpload(const std::string& content,
376 bool is_last_chunk) { 380 bool is_last_chunk) {
377 DCHECK(delegate_task_runner_); 381 DCHECK(delegate_task_runner_);
378 DCHECK(network_task_runner_.get()); 382 DCHECK(network_task_runner_.get());
379 network_task_runner_->PostTask( 383 network_task_runner_->PostTask(
380 FROM_HERE, 384 FROM_HERE,
381 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, 385 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content,
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 url_request_create_data_callback_.Run()); 747 url_request_create_data_callback_.Run());
744 } 748 }
745 749
746 switch (request_type_) { 750 switch (request_type_) {
747 case URLFetcher::GET: 751 case URLFetcher::GET:
748 break; 752 break;
749 753
750 case URLFetcher::POST: 754 case URLFetcher::POST:
751 case URLFetcher::PUT: 755 case URLFetcher::PUT:
752 case URLFetcher::PATCH: 756 case URLFetcher::PATCH:
753 // Upload content must be set.
754 DCHECK(is_chunked_upload_ || upload_content_);
755
756 request_->set_method( 757 request_->set_method(
757 request_type_ == URLFetcher::POST ? "POST" : 758 request_type_ == URLFetcher::POST ? "POST" :
758 request_type_ == URLFetcher::PUT ? "PUT" : "PATCH"); 759 request_type_ == URLFetcher::PUT ? "PUT" : "PATCH");
759 if (!upload_content_type_.empty()) { 760 if (!upload_content_type_.empty()) {
760 extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, 761 extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType,
761 upload_content_type_); 762 upload_content_type_);
762 } 763 }
763 if (upload_content_) 764 if (!is_chunked_upload_ &&
764 request_->set_upload(upload_content_.Pass()); 765 (!upload_content_.empty() || upload_content_type_.empty())) {
766 DCHECK(!upload_data_stream_);
767 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
768 upload_content_.data(), upload_content_.size()));
769 request_->set_upload(make_scoped_ptr(
770 UploadDataStream::CreateWithReader(reader.Pass(), 0)));
771 } else if (!is_chunked_upload_ && upload_data_stream_) {
772 request_->set_upload(upload_data_stream_.Pass());
773 }
774
765 current_upload_bytes_ = -1; 775 current_upload_bytes_ = -1;
766 // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the 776 // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the
767 // layer and avoid using timer here. 777 // layer and avoid using timer here.
768 upload_progress_checker_timer_.reset( 778 upload_progress_checker_timer_.reset(
769 new base::RepeatingTimer<URLFetcherCore>()); 779 new base::RepeatingTimer<URLFetcherCore>());
770 upload_progress_checker_timer_->Start( 780 upload_progress_checker_timer_->Start(
771 FROM_HERE, 781 FROM_HERE,
772 base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval), 782 base::TimeDelta::FromMilliseconds(kUploadProgressTimerInterval),
773 this, 783 this,
774 &URLFetcherCore::InformDelegateUploadProgress); 784 &URLFetcherCore::InformDelegateUploadProgress);
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 } 1093 }
1084 1094
1085 void URLFetcherCore::InformDelegateDownloadDataInDelegateThread( 1095 void URLFetcherCore::InformDelegateDownloadDataInDelegateThread(
1086 scoped_ptr<std::string> download_data) { 1096 scoped_ptr<std::string> download_data) {
1087 DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 1097 DCHECK(delegate_task_runner_->BelongsToCurrentThread());
1088 if (delegate_) 1098 if (delegate_)
1089 delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass()); 1099 delegate_->OnURLFetchDownloadData(fetcher_, download_data.Pass());
1090 } 1100 }
1091 1101
1092 } // namespace net 1102 } // namespace net
OLDNEW
« no previous file with comments | « net/url_request/url_fetcher_core.h ('k') | net/url_request/url_fetcher_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698