| Index: chrome/common/net/url_fetcher.cc
|
| diff --git a/chrome/common/net/url_fetcher.cc b/chrome/common/net/url_fetcher.cc
|
| index 4f267af3388475e763b2fed2679b619aa6444165..08a5bdfcb0104cf48ed423ab564644e608186ad2 100644
|
| --- a/chrome/common/net/url_fetcher.cc
|
| +++ b/chrome/common/net/url_fetcher.cc
|
| @@ -102,6 +102,13 @@ class URLFetcher::Core
|
| // |original_url_| and |url_|.
|
| base::TimeTicks GetBackoffReleaseTime();
|
|
|
| + void AddUploadDataChunkInThread(const std::string& data);
|
| +
|
| + // Adds a block of data to be uploaded in a POST body. This can be called
|
| + // before or after Start() is called.
|
| + void AppendChunkToUpload(const std::string& data);
|
| + void MarkEndOfChunks();
|
| +
|
| URLFetcher* fetcher_; // Corresponding fetcher object
|
| GURL original_url_; // The URL we were asked to fetch
|
| GURL url_; // The URL we eventually wound up at
|
| @@ -127,6 +134,7 @@ class URLFetcher::Core
|
|
|
| std::string upload_content_; // HTTP POST payload
|
| std::string upload_content_type_; // MIME type of POST payload
|
| + bool upload_in_chunks_; // True if using chunked transfer encoding
|
|
|
| // Used to determine how long to wait before making a request or doing a
|
| // retry.
|
| @@ -222,6 +230,7 @@ URLFetcher::Core::Core(URLFetcher* fetcher,
|
| response_code_(-1),
|
| buffer_(new net::IOBuffer(kBufferSize)),
|
| num_retries_(0),
|
| + upload_in_chunks_(false),
|
| was_cancelled_(false) {
|
| }
|
|
|
| @@ -282,6 +291,35 @@ void URLFetcher::Core::OnResponseStarted(net::URLRequest* request) {
|
| OnReadCompleted(request_.get(), bytes_read);
|
| }
|
|
|
| +void URLFetcher::Core::AddUploadDataChunkInThread(const std::string& content) {
|
| + DCHECK(upload_in_chunks_);
|
| + DCHECK(request_.get());
|
| + if (content.length() > 0) {
|
| + request_->AppendChunkToUpload(content.data(),
|
| + static_cast<int>(content.size()));
|
| + } else {
|
| + request_->MarkEndOfChunks();
|
| + }
|
| +}
|
| +
|
| +void URLFetcher::Core::AppendChunkToUpload(const std::string& content) {
|
| + DCHECK(content.length() > 0);
|
| + DCHECK(delegate_loop_proxy_);
|
| + CHECK(io_message_loop_proxy_.get());
|
| + io_message_loop_proxy_->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableMethod(this, &Core::AddUploadDataChunkInThread, content));
|
| +}
|
| +
|
| +void URLFetcher::Core::MarkEndOfChunks() {
|
| + DCHECK(delegate_loop_proxy_);
|
| + CHECK(io_message_loop_proxy_.get());
|
| + std::string empty;
|
| + io_message_loop_proxy_->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableMethod(this, &Core::AddUploadDataChunkInThread, empty));
|
| +}
|
| +
|
| void URLFetcher::Core::OnReadCompleted(net::URLRequest* request,
|
| int bytes_read) {
|
| DCHECK(request == request_);
|
| @@ -334,6 +372,8 @@ void URLFetcher::Core::StartURLRequest() {
|
| if (!g_interception_enabled) {
|
| flags = flags | net::LOAD_DISABLE_INTERCEPT;
|
| }
|
| + if (upload_in_chunks_)
|
| + request_->set_chunked_transfer_upload();
|
| request_->set_load_flags(flags);
|
| request_->set_context(request_context_getter_->GetURLRequestContext());
|
|
|
| @@ -342,14 +382,16 @@ void URLFetcher::Core::StartURLRequest() {
|
| break;
|
|
|
| case POST:
|
| - DCHECK(!upload_content_.empty());
|
| + DCHECK(!upload_content_.empty() || upload_in_chunks_);
|
| DCHECK(!upload_content_type_.empty());
|
|
|
| request_->set_method("POST");
|
| extra_request_headers_.SetHeader(net::HttpRequestHeaders::kContentType,
|
| upload_content_type_);
|
| - request_->AppendBytesToUpload(upload_content_.data(),
|
| - static_cast<int>(upload_content_.size()));
|
| + if (!upload_content_.empty()) {
|
| + request_->AppendBytesToUpload(upload_content_.data(),
|
| + static_cast<int>(upload_content_.size()));
|
| + }
|
| break;
|
|
|
| case HEAD:
|
| @@ -474,6 +516,20 @@ void URLFetcher::set_upload_data(const std::string& upload_content_type,
|
| const std::string& upload_content) {
|
| core_->upload_content_type_ = upload_content_type;
|
| core_->upload_content_ = upload_content;
|
| + core_->upload_in_chunks_ = false;
|
| +}
|
| +
|
| +void URLFetcher::set_chunked_transfer_upload(const std::string& content_type) {
|
| + core_->upload_content_type_ = content_type;
|
| + core_->upload_in_chunks_ = true;
|
| +}
|
| +
|
| +void URLFetcher::AppendChunkToUpload(const std::string& data) {
|
| + core_->AppendChunkToUpload(data);
|
| +}
|
| +
|
| +void URLFetcher::MarkEndOfChunks() {
|
| + core_->MarkEndOfChunks();
|
| }
|
|
|
| const std::string& URLFetcher::upload_data() const {
|
|
|