Chromium Code Reviews| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 | 198 |
| 199 upload_content_type_ = content_type; | 199 upload_content_type_ = content_type; |
| 200 upload_content_.clear(); | 200 upload_content_.clear(); |
| 201 is_chunked_upload_ = true; | 201 is_chunked_upload_ = true; |
| 202 } | 202 } |
| 203 | 203 |
| 204 void URLFetcherCore::AppendChunkToUpload(const std::string& content, | 204 void URLFetcherCore::AppendChunkToUpload(const std::string& content, |
| 205 bool is_last_chunk) { | 205 bool is_last_chunk) { |
| 206 DCHECK(delegate_task_runner_.get()); | 206 DCHECK(delegate_task_runner_.get()); |
| 207 DCHECK(network_task_runner_.get()); | 207 DCHECK(network_task_runner_.get()); |
| 208 DCHECK(is_chunked_upload_); | |
| 208 network_task_runner_->PostTask( | 209 network_task_runner_->PostTask( |
| 209 FROM_HERE, | 210 FROM_HERE, |
| 210 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, | 211 base::Bind(&URLFetcherCore::CompleteAddingUploadDataChunk, this, content, |
| 211 is_last_chunk)); | 212 is_last_chunk)); |
| 212 } | 213 } |
| 213 | 214 |
| 214 void URLFetcherCore::SetLoadFlags(int load_flags) { | 215 void URLFetcherCore::SetLoadFlags(int load_flags) { |
| 215 load_flags_ = load_flags; | 216 load_flags_ = load_flags; |
| 216 } | 217 } |
| 217 | 218 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 473 const URLRequestStatus status = request_->status(); | 474 const URLRequestStatus status = request_->status(); |
| 474 if (status.is_success()) | 475 if (status.is_success()) |
| 475 request_->GetResponseCookies(&cookies_); | 476 request_->GetResponseCookies(&cookies_); |
| 476 | 477 |
| 477 // See comments re: HEAD requests in ReadResponse(). | 478 // See comments re: HEAD requests in ReadResponse(). |
| 478 if (!status.is_io_pending() || request_type_ == URLFetcher::HEAD) { | 479 if (!status.is_io_pending() || request_type_ == URLFetcher::HEAD) { |
| 479 status_ = status; | 480 status_ = status; |
| 480 received_response_content_length_ = | 481 received_response_content_length_ = |
| 481 request_->received_response_content_length(); | 482 request_->received_response_content_length(); |
| 482 total_received_bytes_ += request_->GetTotalReceivedBytes(); | 483 total_received_bytes_ += request_->GetTotalReceivedBytes(); |
| 483 ReleaseRequest(); | 484 ReleaseRequest(); |
|
mmenke
2016/03/02 19:42:37
Bug 2: On error, we release the request without s
| |
| 484 | 485 |
| 485 // No more data to write. | 486 // No more data to write. |
| 486 const int result = response_writer_->Finish( | 487 const int result = response_writer_->Finish( |
| 487 base::Bind(&URLFetcherCore::DidFinishWriting, this)); | 488 base::Bind(&URLFetcherCore::DidFinishWriting, this)); |
| 488 if (result != ERR_IO_PENDING) | 489 if (result != ERR_IO_PENDING) |
| 489 DidFinishWriting(result); | 490 DidFinishWriting(result); |
| 490 } | 491 } |
| 491 } | 492 } |
| 492 | 493 |
| 493 void URLFetcherCore::OnContextShuttingDown() { | 494 void URLFetcherCore::OnContextShuttingDown() { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 509 | 510 |
| 510 URLFetcherCore::~URLFetcherCore() { | 511 URLFetcherCore::~URLFetcherCore() { |
| 511 // |request_| should be NULL. If not, it's unsafe to delete it here since we | 512 // |request_| should be NULL. If not, it's unsafe to delete it here since we |
| 512 // may not be on the IO thread. | 513 // may not be on the IO thread. |
| 513 DCHECK(!request_.get()); | 514 DCHECK(!request_.get()); |
| 514 } | 515 } |
| 515 | 516 |
| 516 void URLFetcherCore::StartOnIOThread() { | 517 void URLFetcherCore::StartOnIOThread() { |
| 517 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 518 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 518 | 519 |
| 520 // Create ChunkedUploadDataStream, if needed, so the consumer can start | |
| 521 // appending data. Have to do it here because StartURLRequest() may be called | |
| 522 // asynchonously. | |
| 523 if (is_chunked_upload_) { | |
| 524 chunked_stream_.reset(new ChunkedUploadDataStream(0)); | |
| 525 chunked_stream_writer_ = chunked_stream_->CreateWriter(); | |
| 526 } | |
| 527 | |
| 519 if (!response_writer_) | 528 if (!response_writer_) |
| 520 response_writer_.reset(new URLFetcherStringWriter); | 529 response_writer_.reset(new URLFetcherStringWriter); |
| 521 | 530 |
| 522 const int result = response_writer_->Initialize( | 531 const int result = response_writer_->Initialize( |
| 523 base::Bind(&URLFetcherCore::DidInitializeWriter, this)); | 532 base::Bind(&URLFetcherCore::DidInitializeWriter, this)); |
| 524 if (result != ERR_IO_PENDING) | 533 if (result != ERR_IO_PENDING) |
| 525 DidInitializeWriter(result); | 534 DidInitializeWriter(result); |
|
mmenke
2016/03/02 19:42:37
Bug 1: Note that this can call DidInitializeWrite
| |
| 526 } | 535 } |
| 527 | 536 |
| 528 void URLFetcherCore::StartURLRequest() { | 537 void URLFetcherCore::StartURLRequest() { |
| 529 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 538 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 530 | 539 |
| 531 if (was_cancelled_) { | 540 if (was_cancelled_) { |
| 532 // Since StartURLRequest() is posted as a *delayed* task, it may | 541 // Since StartURLRequest() is posted as a *delayed* task, it may |
| 533 // run after the URLFetcher was already stopped. | 542 // run after the URLFetcher was already stopped. |
| 534 return; | 543 return; |
| 535 } | 544 } |
| 536 | 545 |
| 537 if (!request_context_getter_->GetURLRequestContext()) { | 546 if (!request_context_getter_->GetURLRequestContext()) { |
| 538 CancelRequestAndInformDelegate(ERR_CONTEXT_SHUT_DOWN); | 547 CancelRequestAndInformDelegate(ERR_CONTEXT_SHUT_DOWN); |
| 539 return; | 548 return; |
| 540 } | 549 } |
| 541 | 550 |
| 542 DCHECK(request_context_getter_.get()); | 551 DCHECK(request_context_getter_.get()); |
| 543 DCHECK(!request_.get()); | 552 DCHECK(!request_.get()); |
| 544 | 553 |
| 545 g_registry.Get().AddURLFetcherCore(this); | 554 g_registry.Get().AddURLFetcherCore(this); |
| 546 current_response_bytes_ = 0; | 555 current_response_bytes_ = 0; |
| 547 request_context_getter_->AddObserver(this); | 556 request_context_getter_->AddObserver(this); |
| 548 request_ = request_context_getter_->GetURLRequestContext()->CreateRequest( | 557 request_ = request_context_getter_->GetURLRequestContext()->CreateRequest( |
| 549 original_url_, DEFAULT_PRIORITY, this); | 558 original_url_, DEFAULT_PRIORITY, this); |
| 550 request_->set_stack_trace(stack_trace_); | 559 request_->set_stack_trace(stack_trace_); |
| 551 int flags = request_->load_flags() | load_flags_; | 560 int flags = request_->load_flags() | load_flags_; |
| 552 | 561 |
| 553 if (is_chunked_upload_) | 562 // TODO(mmenke): This should really be with the other code to set the upload |
| 554 request_->EnableChunkedUpload(); | 563 // body, below. |
| 564 if (chunked_stream_) | |
| 565 request_->set_upload(make_scoped_ptr(chunked_stream_.release())); | |
| 566 | |
| 555 request_->SetLoadFlags(flags); | 567 request_->SetLoadFlags(flags); |
| 556 request_->SetReferrer(referrer_); | 568 request_->SetReferrer(referrer_); |
| 557 request_->set_referrer_policy(referrer_policy_); | 569 request_->set_referrer_policy(referrer_policy_); |
| 558 request_->set_first_party_for_cookies(initiator_.is_empty() ? original_url_ | 570 request_->set_first_party_for_cookies(initiator_.is_empty() ? original_url_ |
| 559 : initiator_); | 571 : initiator_); |
| 560 request_->set_initiator(initiator_.is_empty() ? url::Origin(original_url_) | 572 request_->set_initiator(initiator_.is_empty() ? url::Origin(original_url_) |
| 561 : url::Origin(initiator_)); | 573 : url::Origin(initiator_)); |
| 562 if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) { | 574 if (url_request_data_key_ && !url_request_create_data_callback_.is_null()) { |
| 563 request_->SetUserData(url_request_data_key_, | 575 request_->SetUserData(url_request_data_key_, |
| 564 url_request_create_data_callback_.Run()); | 576 url_request_create_data_callback_.Run()); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 destination_url_backoff = | 840 destination_url_backoff = |
| 829 url_throttler_entry_->GetExponentialBackoffReleaseTime(); | 841 url_throttler_entry_->GetExponentialBackoffReleaseTime(); |
| 830 } | 842 } |
| 831 | 843 |
| 832 return original_url_backoff > destination_url_backoff ? | 844 return original_url_backoff > destination_url_backoff ? |
| 833 original_url_backoff : destination_url_backoff; | 845 original_url_backoff : destination_url_backoff; |
| 834 } | 846 } |
| 835 | 847 |
| 836 void URLFetcherCore::CompleteAddingUploadDataChunk( | 848 void URLFetcherCore::CompleteAddingUploadDataChunk( |
| 837 const std::string& content, bool is_last_chunk) { | 849 const std::string& content, bool is_last_chunk) { |
| 838 if (was_cancelled_) { | |
| 839 // Since CompleteAddingUploadDataChunk() is posted as a *delayed* task, it | |
| 840 // may run after the URLFetcher was already stopped. | |
| 841 return; | |
| 842 } | |
| 843 DCHECK(is_chunked_upload_); | 850 DCHECK(is_chunked_upload_); |
| 844 DCHECK(request_.get()); | |
| 845 DCHECK(!content.empty()); | 851 DCHECK(!content.empty()); |
| 846 request_->AppendChunkToUpload(content.data(), | 852 chunked_stream_writer_->AppendData( |
| 847 static_cast<int>(content.length()), | 853 content.data(), static_cast<int>(content.length()), is_last_chunk); |
| 848 is_last_chunk); | |
| 849 } | 854 } |
| 850 | 855 |
| 851 int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) { | 856 int URLFetcherCore::WriteBuffer(scoped_refptr<DrainableIOBuffer> data) { |
| 852 while (data->BytesRemaining() > 0) { | 857 while (data->BytesRemaining() > 0) { |
| 853 const int result = response_writer_->Write( | 858 const int result = response_writer_->Write( |
| 854 data.get(), | 859 data.get(), |
| 855 data->BytesRemaining(), | 860 data->BytesRemaining(), |
| 856 base::Bind(&URLFetcherCore::DidWriteBuffer, this, data)); | 861 base::Bind(&URLFetcherCore::DidWriteBuffer, this, data)); |
| 857 if (result < 0) { | 862 if (result < 0) { |
| 858 if (result != ERR_IO_PENDING) | 863 if (result != ERR_IO_PENDING) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 953 } | 958 } |
| 954 | 959 |
| 955 void URLFetcherCore::AssertHasNoUploadData() const { | 960 void URLFetcherCore::AssertHasNoUploadData() const { |
| 956 DCHECK(!upload_content_set_); | 961 DCHECK(!upload_content_set_); |
| 957 DCHECK(upload_content_.empty()); | 962 DCHECK(upload_content_.empty()); |
| 958 DCHECK(upload_file_path_.empty()); | 963 DCHECK(upload_file_path_.empty()); |
| 959 DCHECK(upload_stream_factory_.is_null()); | 964 DCHECK(upload_stream_factory_.is_null()); |
| 960 } | 965 } |
| 961 | 966 |
| 962 } // namespace net | 967 } // namespace net |
| OLD | NEW |