12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/base_requests.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/location.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/sequenced_task_runner.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/request_sender.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/task_util.h" 161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/io_buffer.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_flags.h" 18a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/base/net_errors.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_byte_range.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_response_headers.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_util.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_status.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using net::URLFetcher; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Template for optional OAuth2 authorization HTTP header. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Template for GData API version HTTP header. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kGDataVersionHeader[] = "GData-Version: 3.0"; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Maximum number of attempts for re-authentication per request. 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kMaxReAuthenticateAttemptsPerRequest = 1; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Template for initiate upload of both GData WAPI and Drive API v2. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadContentType[] = "X-Upload-Content-Type: "; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadContentLength[] = "X-Upload-Content-Length: "; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadResponseLocation[] = "location"; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Template for upload data range of both GData WAPI and Drive API v2. 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadContentRange[] = "Content-Range: bytes "; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kUploadResponseRange[] = "range"; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Parses JSON passed in |json| on |blocking_task_runner|. Runs |callback| on 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// the calling thread when finished with either success or failure. 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// The callback must not be null. 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ParseJsonOnBlockingPool( 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TaskRunner* blocking_task_runner, 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& json, 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Callback<void(scoped_ptr<base::Value> value)>& callback) { 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::PostTaskAndReplyWithResult( 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blocking_task_runner, 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&google_apis::ParseJson, json), 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) callback); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns response headers as a string. Returns a warning message if 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |url_fetcher| does not contain a valid response. Used only for debugging. 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)std::string GetResponseHeadersAsString(const URLFetcher* url_fetcher) { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // net::HttpResponseHeaders::raw_headers(), as the name implies, stores 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // all headers in their raw format, i.e each header is null-terminated. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // So logging raw_headers() only shows the first header, which is probably 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the status line. GetNormalizedHeaders, on the other hand, will show all 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the headers, one per line, which is probably what we want. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string headers; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check that response code indicates response headers are valid (i.e. not 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // malformed) before we retrieve the headers. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (url_fetcher->GetResponseCode() == URLFetcher::RESPONSE_CODE_INVALID) { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) headers.assign("Response headers are malformed!!"); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher->GetResponseHeaders()->GetNormalizedHeaders(&headers); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return headers; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsSuccessfulResponseCode(int response_code) { 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 200 <= response_code && response_code <= 299; 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace google_apis { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_ptr<base::Value> ParseJson(const std::string& json) { 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int error_code = -1; 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string error_message; 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) json, base::JSON_PARSE_RFC, &error_code, &error_message)); 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!value.get()) { 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string trimmed_json; 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (json.size() < 80) { 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) trimmed_json = json; 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Take the first 50 and the last 10 bytes. 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) trimmed_json = base::StringPrintf( 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "%s [%s bytes] %s", 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) json.substr(0, 50).c_str(), 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Uint64ToString(json.size() - 60).c_str(), 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) json.substr(json.size() - 10).c_str()); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(WARNING) << "Error while parsing entry response: " << error_message 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << ", code: " << error_code << ", json:\n" << trimmed_json; 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return value.Pass(); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)//=========================== ResponseWriter ================================== 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResponseWriter::ResponseWriter(base::SequencedTaskRunner* file_task_runner, 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const base::FilePath& file_path, 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const GetContentCallback& get_content_callback) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : get_content_callback_(get_content_callback), 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_(this) { 1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!file_path.empty()) { 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) file_writer_.reset( 1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new net::URLFetcherFileWriter(file_task_runner, file_path)); 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ResponseWriter::~ResponseWriter() { 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ResponseWriter::DisownFile() { 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(file_writer_); 1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) file_writer_->DisownFile(); 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int ResponseWriter::Initialize(const net::CompletionCallback& callback) { 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (file_writer_) 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return file_writer_->Initialize(callback); 1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) data_.clear(); 1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return net::OK; 1371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int ResponseWriter::Write(net::IOBuffer* buffer, 1401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int num_bytes, 1411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const net::CompletionCallback& callback) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!get_content_callback_.is_null()) { 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_content_callback_.Run( 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HTTP_SUCCESS, 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) make_scoped_ptr(new std::string(buffer->data(), num_bytes))); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file_writer_) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int result = file_writer_->Write( 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer, num_bytes, 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ResponseWriter::DidWrite, 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) make_scoped_refptr(buffer), callback)); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DidWrite(buffer, net::CompletionCallback(), result); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return result; 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) data_.append(buffer->data(), num_bytes); 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return num_bytes; 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)int ResponseWriter::Finish(const net::CompletionCallback& callback) { 1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (file_writer_) 1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return file_writer_->Finish(callback); 1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return net::OK; 1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResponseWriter::DidWrite(scoped_refptr<net::IOBuffer> buffer, 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CompletionCallback& callback, 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int result) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result > 0) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Even if file_writer_ is used, append the data to |data_|, so that it can 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // be used to get error information in case of server side errors. 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The size limit is to avoid consuming too much redundant memory. 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const size_t kMaxStringSize = 1024*1024; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data_.size() < kMaxStringSize) { 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data_.append(buffer->data(), std::min(static_cast<size_t>(result), 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kMaxStringSize - data_.size())); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!callback.is_null()) 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(result); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//============================ UrlFetchRequestBase =========================== 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochUrlFetchRequestBase::UrlFetchRequestBase(RequestSender* sender) 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : re_authenticate_count_(0), 1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) response_writer_(NULL), 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sender_(sender), 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error_code_(GDATA_OTHER_ERROR), 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)UrlFetchRequestBase::~UrlFetchRequestBase() {} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UrlFetchRequestBase::Start(const std::string& access_token, 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& custom_user_agent, 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const ReAuthenticateCallback& callback) { 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(CalledOnValidThread()); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!access_token.empty()); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(re_authenticate_callback_.is_null()); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) re_authenticate_callback_ = callback; 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url = GetURL(); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (url.is_empty()) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Error is found on generating the url. Send the error message to the 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // callback, and then return immediately without trying to connect 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the server. 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunCallbackOnPrematureFailure(GDATA_OTHER_ERROR); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "URL: " << url.spec(); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLFetcher::RequestType request_type = GetRequestType(); 2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) url_fetcher_.reset(URLFetcher::Create(url, request_type, this)); 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_fetcher_->SetRequestContext(sender_->url_request_context_getter()); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Always set flags to neither send nor save cookies. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->SetLoadFlags( 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES | 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::LOAD_DISABLE_CACHE); 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::FilePath output_file_path; 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetContentCallback get_content_callback; 2301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetOutputFilePath(&output_file_path, &get_content_callback); 2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!get_content_callback.is_null()) 2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_content_callback = CreateRelayCallback(get_content_callback); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_writer_ = new ResponseWriter(blocking_task_runner(), 2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) output_file_path, 2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) get_content_callback); 2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) url_fetcher_->SaveResponseWithWriter( 2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<net::URLFetcherResponseWriter>(response_writer_)); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add request headers. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that SetExtraRequestHeaders clears the current headers and sets it 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the passed-in headers, so calling it for each header will result in 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only the last header being set in request headers. 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!custom_user_agent.empty()) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->AddExtraRequestHeader("User-Agent: " + custom_user_agent); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->AddExtraRequestHeader(kGDataVersionHeader); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->AddExtraRequestHeader( 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::StringPrintf(kAuthorizationHeaderFormat, access_token.data())); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> headers = GetExtraRequestHeaders(); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < headers.size(); ++i) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->AddExtraRequestHeader(headers[i]); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Extra header: " << headers[i]; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set upload data if available. 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string upload_content_type; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string upload_content; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetContentData(&upload_content_type, &upload_content)) { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->SetUploadData(upload_content_type, upload_content); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::FilePath local_file_path; 261a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int64 range_offset = 0; 262a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int64 range_length = 0; 263a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (GetContentFile(&local_file_path, &range_offset, &range_length, 264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &upload_content_type)) { 265a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) url_fetcher_->SetUploadFilePath( 266a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) upload_content_type, 267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) local_file_path, 268a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) range_offset, 269a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) range_length, 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch blocking_task_runner()); 271a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } else { 272a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Even if there is no content data, UrlFetcher requires to set empty 273a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // upload data string for POST, PUT and PATCH methods, explicitly. 274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // It is because that most requests of those methods have non-empty 275a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // body, and UrlFetcher checks whether it is actually not forgotten. 276a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (request_type == URLFetcher::POST || 277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) request_type == URLFetcher::PUT || 278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) request_type == URLFetcher::PATCH) { 279a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Set empty upload content-type and upload content, so that 280a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // the request will have no "Content-type: " header and no content. 281a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) url_fetcher_->SetUploadData(std::string(), std::string()); 282a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_->Start(); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)URLFetcher::RequestType UrlFetchRequestBase::GetRequestType() const { 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return URLFetcher::GET; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::vector<std::string> UrlFetchRequestBase::GetExtraRequestHeaders() const { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::vector<std::string>(); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool UrlFetchRequestBase::GetContentData(std::string* upload_content_type, 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string* upload_content) { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool UrlFetchRequestBase::GetContentFile(base::FilePath* local_file_path, 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64* range_offset, 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int64* range_length, 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string* upload_content_type) { 306a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 307a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 308a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void UrlFetchRequestBase::GetOutputFilePath( 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::FilePath* local_file_path, 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetContentCallback* get_content_callback) { 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid UrlFetchRequestBase::Cancel() { 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) response_writer_ = NULL; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url_fetcher_.reset(NULL); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunCallbackOnPrematureFailure(GDATA_CANCELLED); 318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sender_->RequestFinished(this); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GDataErrorCode UrlFetchRequestBase::GetErrorCode() { 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return error_code_; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool UrlFetchRequestBase::CalledOnValidThread() { 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return thread_checker_.CalledOnValidThread(); 327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)base::SequencedTaskRunner* UrlFetchRequestBase::blocking_task_runner() const { 3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return sender_->blocking_task_runner(); 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UrlFetchRequestBase::OnProcessURLFetchResultsComplete() { 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sender_->RequestFinished(this); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UrlFetchRequestBase::OnURLFetchComplete(const URLFetcher* source) { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Response headers:\n" << GetResponseHeadersAsString(source); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Determine error code. 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error_code_ = static_cast<GDataErrorCode>(source->GetResponseCode()); 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!source->GetStatus().is_success()) { 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (source->GetStatus().error()) { 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case net::ERR_NETWORK_CHANGED: 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error_code_ = GDATA_NO_CONNECTION; 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error_code_ = GDATA_OTHER_ERROR; 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The server may return detailed error status in JSON. 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // See https://developers.google.com/drive/handle-errors 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!IsSuccessfulResponseCode(error_code_)) { 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << response_writer_->data(); 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kErrorKey[] = "error"; 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kErrorErrorsKey[] = "errors"; 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kErrorReasonKey[] = "reason"; 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kErrorMessageKey[] = "message"; 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kErrorReasonRateLimitExceeded[] = "rateLimitExceeded"; 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kErrorReasonUserRateLimitExceeded[] = "userRateLimitExceeded"; 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char kErrorReasonQuotaExceeded[] = "quotaExceeded"; 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Value> value(ParseJson(response_writer_->data())); 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::DictionaryValue* dictionary = NULL; 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::DictionaryValue* error = NULL; 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (value && 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) value->GetAsDictionary(&dictionary) && 370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dictionary->GetDictionaryWithoutPathExpansion(kErrorKey, &error)) { 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Get error message. 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string message; 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error->GetStringWithoutPathExpansion(kErrorMessageKey, &message); 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DLOG(ERROR) << "code: " << error_code_ << ", message: " << message; 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Override the error code based on the reason of the first error. 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::ListValue* errors = NULL; 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::DictionaryValue* first_error = NULL; 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error->GetListWithoutPathExpansion(kErrorErrorsKey, &errors) && 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) errors->GetDictionary(0, &first_error)) { 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string reason; 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) first_error->GetStringWithoutPathExpansion(kErrorReasonKey, &reason); 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reason == kErrorReasonRateLimitExceeded || 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reason == kErrorReasonUserRateLimitExceeded) 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) error_code_ = HTTP_SERVICE_UNAVAILABLE; 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (reason == kErrorReasonQuotaExceeded) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_code_ = GDATA_NO_SPACE; 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Handle authentication failure. 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error_code_ == HTTP_UNAUTHORIZED) { 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (++re_authenticate_count_ <= kMaxReAuthenticateAttemptsPerRequest) { 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reset re_authenticate_callback_ so Start() can be called again. 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReAuthenticateCallback callback = re_authenticate_callback_; 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) re_authenticate_callback_.Reset(); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(this); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnAuthFailed(error_code_); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Overridden by each specialization 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessURLFetchResults(source); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UrlFetchRequestBase::OnAuthFailed(GDataErrorCode code) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunCallbackOnPrematureFailure(code); 412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sender_->RequestFinished(this); 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::WeakPtr<AuthenticatedRequestInterface> 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)UrlFetchRequestBase::GetWeakPtr() { 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return weak_ptr_factory_.GetWeakPtr(); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//============================ EntryActionRequest ============================ 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochEntryActionRequest::EntryActionRequest(RequestSender* sender, 423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const EntryActionCallback& callback) 424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : UrlFetchRequestBase(sender), 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(callback) { 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback_.is_null()); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)EntryActionRequest::~EntryActionRequest() {} 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void EntryActionRequest::ProcessURLFetchResults(const URLFetcher* source) { 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) callback_.Run(GetErrorCode()); 433d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) OnProcessURLFetchResultsComplete(); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void EntryActionRequest::RunCallbackOnPrematureFailure(GDataErrorCode code) { 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Run(code); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//========================= InitiateUploadRequestBase ======================== 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)InitiateUploadRequestBase::InitiateUploadRequestBase( 443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RequestSender* sender, 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InitiateUploadCallback& callback, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length) 447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : UrlFetchRequestBase(sender), 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(callback), 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type_(content_type), 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_length_(content_length) { 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback_.is_null()); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!content_type_.empty()); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(content_length_, 0); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)InitiateUploadRequestBase::~InitiateUploadRequestBase() {} 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void InitiateUploadRequestBase::ProcessURLFetchResults( 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const URLFetcher* source) { 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GDataErrorCode code = GetErrorCode(); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string upload_location; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (code == HTTP_SUCCESS) { 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Retrieve value of the first "Location" header. 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->GetResponseHeaders()->EnumerateHeader(NULL, 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadResponseLocation, 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &upload_location); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Run(code, GURL(upload_location)); 471d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) OnProcessURLFetchResultsComplete(); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 474868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void InitiateUploadRequestBase::RunCallbackOnPrematureFailure( 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDataErrorCode code) { 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Run(code, GURL()); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<std::string> 480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)InitiateUploadRequestBase::GetExtraRequestHeaders() const { 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> headers; 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) headers.push_back(kUploadContentType + content_type_); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) headers.push_back( 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kUploadContentLength + base::Int64ToString(content_length_)); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return headers; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//============================ UploadRangeResponse ============================= 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UploadRangeResponse::UploadRangeResponse() 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : code(HTTP_SUCCESS), 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position_received(0), 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position_received(0) { 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UploadRangeResponse::UploadRangeResponse(GDataErrorCode code, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position_received, 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position_received) 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : code(code), 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position_received(start_position_received), 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position_received(end_position_received) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UploadRangeResponse::~UploadRangeResponse() { 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//========================== UploadRangeRequestBase ========================== 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochUploadRangeRequestBase::UploadRangeRequestBase(RequestSender* sender, 510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GURL& upload_url) 511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : UrlFetchRequestBase(sender), 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) upload_url_(upload_url), 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)UploadRangeRequestBase::~UploadRangeRequestBase() {} 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GURL UploadRangeRequestBase::GetURL() const { 519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This is very tricky to get json from this request. To do that, &alt=json 520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // has to be appended not here but in InitiateUploadRequestBase::GetURL(). 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return upload_url_; 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)URLFetcher::RequestType UploadRangeRequestBase::GetRequestType() const { 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return URLFetcher::PUT; 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UploadRangeRequestBase::ProcessURLFetchResults( 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const URLFetcher* source) { 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GDataErrorCode code = GetErrorCode(); 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::HttpResponseHeaders* hdrs = source->GetResponseHeaders(); 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (code == HTTP_RESUME_INCOMPLETE) { 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Retrieve value of the first "Range" header. 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The Range header is appeared only if there is at least one received 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // byte. So, initialize the positions by 0 so that the [0,0) will be 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // returned via the |callback_| for empty data case. 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position_received = 0; 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position_received = 0; 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string range_received; 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hdrs->EnumerateHeader(NULL, kUploadResponseRange, &range_received); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!range_received.empty()) { // Parse the range header. 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<net::HttpByteRange> ranges; 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (net::HttpUtil::ParseRangeHeader(range_received, &ranges) && 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !ranges.empty() ) { 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We only care about the first start-end pair in the range. 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Range header represents the range inclusively, while we are treating 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ranges exclusively (i.e., end_position_received should be one passed 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the last valid index). So "+ 1" is added. 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position_received = ranges[0].first_byte_position(); 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position_received = ranges[0].last_byte_position() + 1; 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The Range header has the received data range, so the start position 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should be always 0. 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(start_position_received, 0); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OnRangeRequestComplete(UploadRangeResponse(code, 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) start_position_received, 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) end_position_received), 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value>()); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 564d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) OnProcessURLFetchResultsComplete(); 565bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } else if (code == HTTP_CREATED || code == HTTP_SUCCESS) { 566bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // The upload is successfully done. Parse the response which should be 567bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // the entry's metadata. 5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ParseJsonOnBlockingPool(blocking_task_runner(), 5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) response_writer()->data(), 5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&UploadRangeRequestBase::OnDataParsed, 5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) code)); 573bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } else { 574bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Failed to upload. Run callbacks to notify the error. 575bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch OnRangeRequestComplete( 576bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch UploadRangeResponse(code, -1, -1), scoped_ptr<base::Value>()); 577d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) OnProcessURLFetchResultsComplete(); 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UploadRangeRequestBase::OnDataParsed(GDataErrorCode code, 582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> value) { 583eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(CalledOnValidThread()); 584bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DCHECK(code == HTTP_CREATED || code == HTTP_SUCCESS); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OnRangeRequestComplete(UploadRangeResponse(code, -1, -1), value.Pass()); 587d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) OnProcessURLFetchResultsComplete(); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UploadRangeRequestBase::RunCallbackOnPrematureFailure( 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GDataErrorCode code) { 592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OnRangeRequestComplete( 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UploadRangeResponse(code, 0, 0), scoped_ptr<base::Value>()); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//========================== ResumeUploadRequestBase ========================= 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ResumeUploadRequestBase::ResumeUploadRequestBase( 599eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RequestSender* sender, 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& upload_location, 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 start_position, 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 end_position, 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 content_length, 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& content_type, 605a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& local_file_path) 606eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : UploadRangeRequestBase(sender, upload_location), 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_position_(start_position), 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) end_position_(end_position), 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_length_(content_length), 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_type_(content_type), 611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) local_file_path_(local_file_path) { 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(start_position_, end_position_); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ResumeUploadRequestBase::~ResumeUploadRequestBase() {} 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<std::string> 618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ResumeUploadRequestBase::GetExtraRequestHeaders() const { 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (content_length_ == 0) { 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For uploading an empty document, just PUT an empty content. 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(start_position_, 0); 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(end_position_, 0); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::vector<std::string>(); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The header looks like 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Content-Range: bytes <start_position>-<end_position>/<content_length> 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for example: 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Content-Range: bytes 7864320-8388607/13851821 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The header takes inclusive range, so we adjust by "end_position - 1". 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(start_position_, 0); 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(end_position_, 0); 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(content_length_, 0); 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> headers; 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) headers.push_back( 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(kUploadContentRange) + 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(start_position_) + "-" + 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(end_position_ - 1) + "/" + 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Int64ToString(content_length_)); 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return headers; 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ResumeUploadRequestBase::GetContentFile( 645a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::FilePath* local_file_path, 646a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int64* range_offset, 647a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int64* range_length, 648a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::string* upload_content_type) { 649a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (start_position_ == end_position_) { 650a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // No content data. 651a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 652a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 653a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 654a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) *local_file_path = local_file_path_; 655a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) *range_offset = start_position_; 656a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) *range_length = end_position_ - start_position_; 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *upload_content_type = content_type_; 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//======================== GetUploadStatusRequestBase ======================== 662a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGetUploadStatusRequestBase::GetUploadStatusRequestBase(RequestSender* sender, 664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GURL& upload_url, 665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 content_length) 666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : UploadRangeRequestBase(sender, upload_url), 667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content_length_(content_length) {} 668a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GetUploadStatusRequestBase::~GetUploadStatusRequestBase() {} 670a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 671a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::vector<std::string> 672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)GetUploadStatusRequestBase::GetExtraRequestHeaders() const { 673a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // The header looks like 674a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Content-Range: bytes */<content_length> 675a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // for example: 676a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Content-Range: bytes */13851821 677a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK_GE(content_length_, 0); 678a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 679a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::vector<std::string> headers; 680a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) headers.push_back( 681a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::string(kUploadContentRange) + "*/" + 682a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Int64ToString(content_length_)); 683a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return headers; 684a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 685a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//============================ DownloadFileRequestBase ========================= 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDownloadFileRequestBase::DownloadFileRequestBase( 689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RequestSender* sender, 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadActionCallback& download_action_callback, 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetContentCallback& get_content_callback, 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ProgressCallback& progress_callback, 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& download_url, 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& output_file_path) 695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : UrlFetchRequestBase(sender), 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_action_callback_(download_action_callback), 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) get_content_callback_(get_content_callback), 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback_(progress_callback), 699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch download_url_(download_url), 700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch output_file_path_(output_file_path) { 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!download_action_callback_.is_null()); 702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!output_file_path_.empty()); 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // get_content_callback may be null. 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDownloadFileRequestBase::~DownloadFileRequestBase() {} 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Overridden from UrlFetchRequestBase. 709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGURL DownloadFileRequestBase::GetURL() const { 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return download_url_; 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DownloadFileRequestBase::GetOutputFilePath( 7141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::FilePath* local_file_path, 7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetContentCallback* get_content_callback) { 716eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Configure so that the downloaded content is saved to |output_file_path_|. 717eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *local_file_path = output_file_path_; 7181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) *get_content_callback = get_content_callback_; 719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 720eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DownloadFileRequestBase::OnURLFetchDownloadProgress( 722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const URLFetcher* source, 723eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 current, 724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 total) { 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!progress_callback_.is_null()) 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) progress_callback_.Run(current, total); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DownloadFileRequestBase::ProcessURLFetchResults(const URLFetcher* source) { 730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GDataErrorCode code = GetErrorCode(); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Take over the ownership of the the downloaded temp file. 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath temp_file; 7341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (code == HTTP_SUCCESS) { 7351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) response_writer()->DisownFile(); 7361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) temp_file = output_file_path_; 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_action_callback_.Run(code, temp_file); 740d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) OnProcessURLFetchResultsComplete(); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DownloadFileRequestBase::RunCallbackOnPrematureFailure( 744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GDataErrorCode code) { 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_action_callback_.Run(code, base::FilePath()); 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace google_apis 749