diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-02 21:46:15 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-02 21:46:15 +0000 |
commit | e81652c1b097ea71d019120061e5602d0fdd5f68 (patch) | |
tree | c63148f5c09447ba4be05de3114a9f590cfcbf60 /net/url_request | |
parent | d34a7217d22ab2a385258d7a33a147702942c223 (diff) | |
download | chromium_src-e81652c1b097ea71d019120061e5602d0fdd5f68.zip chromium_src-e81652c1b097ea71d019120061e5602d0fdd5f68.tar.gz chromium_src-e81652c1b097ea71d019120061e5602d0fdd5f68.tar.bz2 |
Add SetUploadFilePath method to URLFetcher.
BUG=169551
Review URL: https://chromiumcodereview.appspot.com/12383015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185780 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request')
-rw-r--r-- | net/url_request/test_url_fetcher_factory.cc | 7 | ||||
-rw-r--r-- | net/url_request/test_url_fetcher_factory.h | 6 | ||||
-rw-r--r-- | net/url_request/url_fetcher.h | 18 | ||||
-rw-r--r-- | net/url_request/url_fetcher_core.cc | 35 | ||||
-rw-r--r-- | net/url_request/url_fetcher_core.h | 8 | ||||
-rw-r--r-- | net/url_request/url_fetcher_impl.cc | 7 | ||||
-rw-r--r-- | net/url_request/url_fetcher_impl.h | 4 | ||||
-rw-r--r-- | net/url_request/url_fetcher_impl_unittest.cc | 56 |
8 files changed, 135 insertions, 6 deletions
diff --git a/net/url_request/test_url_fetcher_factory.cc b/net/url_request/test_url_fetcher_factory.cc index 0fce9d9..c3e94fe 100644 --- a/net/url_request/test_url_fetcher_factory.cc +++ b/net/url_request/test_url_fetcher_factory.cc @@ -57,6 +57,13 @@ void TestURLFetcher::SetUploadData(const std::string& upload_content_type, upload_data_ = upload_content; } +void TestURLFetcher::SetUploadFilePath( + const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner) { + upload_file_path_ = file_path; +} + void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) { } diff --git a/net/url_request/test_url_fetcher_factory.h b/net/url_request/test_url_fetcher_factory.h index cd19088..fab5216 100644 --- a/net/url_request/test_url_fetcher_factory.h +++ b/net/url_request/test_url_fetcher_factory.h @@ -87,6 +87,10 @@ class TestURLFetcher : public URLFetcher { // URLFetcher implementation virtual void SetUploadData(const std::string& upload_content_type, const std::string& upload_content) OVERRIDE; + virtual void SetUploadFilePath( + const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner) OVERRIDE; virtual void SetChunkedUpload( const std::string& upload_content_type) OVERRIDE; // Overriden to cache the chunks uploaded. Caller can read back the uploaded @@ -151,6 +155,7 @@ class TestURLFetcher : public URLFetcher { // Returns the data uploaded on this URLFetcher. const std::string& upload_data() const { return upload_data_; } + const base::FilePath& upload_file_path() const { return upload_file_path_; } // Returns the chunks of data uploaded on this URLFetcher. const std::list<std::string>& upload_chunks() const { return chunks_; } @@ -190,6 +195,7 @@ class TestURLFetcher : public URLFetcher { URLFetcherDelegate* delegate_; DelegateForTests* delegate_for_tests_; std::string upload_data_; + base::FilePath upload_file_path_; std::list<std::string> chunks_; bool did_receive_last_chunk_; diff --git a/net/url_request/url_fetcher.h b/net/url_request/url_fetcher.h index 4aa07f3..aebfcd4 100644 --- a/net/url_request/url_fetcher.h +++ b/net/url_request/url_fetcher.h @@ -124,12 +124,24 @@ class NET_EXPORT URLFetcher { static void SetIgnoreCertificateRequests(bool ignored); // Sets data only needed by POSTs. All callers making POST requests should - // call this before the request is started. |upload_content_type| is the MIME - // type of the content, while |upload_content| is the data to be sent (the - // Content-Length header value will be set to the length of this data). + // call one of the SetUpload* methods before the request is started. + // |upload_content_type| is the MIME type of the content, while + // |upload_content| is the data to be sent (the Content-Length header value + // will be set to the length of this data). virtual void SetUploadData(const std::string& upload_content_type, const std::string& upload_content) = 0; + // Sets data only needed by POSTs. All callers making POST requests should + // call one of the SetUpload* methods before the request is started. + // |upload_content_type| is the MIME type of the content, while + // |file_path| is the path to the file containing the data to be sent (the + // Content-Length header value will be set to the length of this file). + // |file_task_runner| will be used for all file operations. + virtual void SetUploadFilePath( + const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner) = 0; + // Indicates that the POST data is sent via chunked transfer encoding. // This may only be called before calling Start(). // Use AppendChunkToUpload() to give the data chunks after calling Start(). diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc index 5efd1e8..b2ef270 100644 --- a/net/url_request/url_fetcher_core.cc +++ b/net/url_request/url_fetcher_core.cc @@ -16,6 +16,7 @@ #include "net/base/net_errors.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" +#include "net/base/upload_file_element_reader.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_fetcher_file_writer.h" @@ -129,6 +130,7 @@ void URLFetcherCore::SetUploadData(const std::string& upload_content_type, DCHECK(!is_chunked_upload_); DCHECK(!upload_content_set_); DCHECK(upload_content_.empty()); + DCHECK(upload_file_path_.empty()); DCHECK(upload_content_type_.empty()); // Empty |upload_content_type| is allowed iff the |upload_content| is empty. @@ -139,6 +141,23 @@ void URLFetcherCore::SetUploadData(const std::string& upload_content_type, upload_content_set_ = true; } +void URLFetcherCore::SetUploadFilePath( + const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner) { + DCHECK(!is_chunked_upload_); + DCHECK(!upload_content_set_); + DCHECK(upload_content_.empty()); + DCHECK(upload_file_path_.empty()); + DCHECK(upload_content_type_.empty()); + DCHECK(!upload_content_type.empty()); + + upload_content_type_ = upload_content_type; + upload_file_path_ = file_path; + upload_file_task_runner_ = file_task_runner; + upload_content_set_ = true; +} + void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { DCHECK(is_chunked_upload_ || (upload_content_type_.empty() && @@ -551,6 +570,13 @@ void URLFetcherCore::StartURLRequest() { upload_content_.data(), upload_content_.size())); request_->set_upload(make_scoped_ptr( UploadDataStream::CreateWithReader(reader.Pass(), 0))); + } else if (!upload_file_path_.empty()) { + scoped_ptr<UploadElementReader> reader(new UploadFileElementReader( + upload_file_task_runner_, + upload_file_path_, + 0, kuint64max, base::Time())); + request_->set_upload(make_scoped_ptr( + UploadDataStream::CreateWithReader(reader.Pass(), 0))); } current_upload_bytes_ = -1; @@ -850,8 +876,13 @@ void URLFetcherCore::InformDelegateUploadProgress() { if (current_upload_bytes_ != current) { current_upload_bytes_ = current; int64 total = -1; - if (!is_chunked_upload_) - total = static_cast<int64>(upload_content_.size()); + if (!is_chunked_upload_) { + total = static_cast<int64>(request_->GetUploadProgress().size()); + // Total may be zero if the UploadDataStream::Init has not been called + // yet. Don't send the upload progress until the size is initialized. + if (!total) + return; + } delegate_task_runner_->PostTask( FROM_HERE, base::Bind( diff --git a/net/url_request/url_fetcher_core.h b/net/url_request/url_fetcher_core.h index 082b994..0289f63 100644 --- a/net/url_request/url_fetcher_core.h +++ b/net/url_request/url_fetcher_core.h @@ -63,6 +63,9 @@ class URLFetcherCore // content and set |content| to the data to upload. void SetUploadData(const std::string& upload_content_type, const std::string& upload_content); + void SetUploadFilePath(const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner); void SetChunkedUpload(const std::string& upload_content_type); // Adds a block of data to be uploaded in a POST body. This can only be // called after Start(). @@ -223,8 +226,10 @@ class URLFetcherCore scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_; // Task runner for the creating thread. scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; - // Task runner for file access. + // Task runner for download file access. scoped_refptr<base::TaskRunner> file_task_runner_; + // Task runner for upload file access. + scoped_refptr<base::TaskRunner> upload_file_task_runner_; // Task runner for the thread // on which file access happens. scoped_ptr<URLRequest> request_; // The actual request this wraps @@ -248,6 +253,7 @@ class URLFetcherCore bool upload_content_set_; // SetUploadData has been called std::string upload_content_; // HTTP POST payload + base::FilePath upload_file_path_; // Path to file containing POST payload std::string upload_content_type_; // MIME type of POST payload std::string referrer_; // HTTP Referer header value bool is_chunked_upload_; // True if using chunked transfer encoding diff --git a/net/url_request/url_fetcher_impl.cc b/net/url_request/url_fetcher_impl.cc index 5f7a011..bcbf644 100644 --- a/net/url_request/url_fetcher_impl.cc +++ b/net/url_request/url_fetcher_impl.cc @@ -29,6 +29,13 @@ void URLFetcherImpl::SetUploadData(const std::string& upload_content_type, core_->SetUploadData(upload_content_type, upload_content); } +void URLFetcherImpl::SetUploadFilePath( + const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner) { + core_->SetUploadFilePath(upload_content_type, file_path, file_task_runner); +} + void URLFetcherImpl::SetChunkedUpload(const std::string& content_type) { core_->SetChunkedUpload(content_type); } diff --git a/net/url_request/url_fetcher_impl.h b/net/url_request/url_fetcher_impl.h index b76c568..668032c 100644 --- a/net/url_request/url_fetcher_impl.h +++ b/net/url_request/url_fetcher_impl.h @@ -37,6 +37,10 @@ class NET_EXPORT_PRIVATE URLFetcherImpl : public URLFetcher { // URLFetcher implementation: virtual void SetUploadData(const std::string& upload_content_type, const std::string& upload_content) OVERRIDE; + virtual void SetUploadFilePath( + const std::string& upload_content_type, + const base::FilePath& file_path, + scoped_refptr<base::TaskRunner> file_task_runner) OVERRIDE; virtual void SetChunkedUpload( const std::string& upload_content_type) OVERRIDE; virtual void AppendChunkToUpload(const std::string& data, diff --git a/net/url_request/url_fetcher_impl_unittest.cc b/net/url_request/url_fetcher_impl_unittest.cc index 5e22ce0..5d166b8 100644 --- a/net/url_request/url_fetcher_impl_unittest.cc +++ b/net/url_request/url_fetcher_impl_unittest.cc @@ -237,6 +237,22 @@ class URLFetcherPostTest : public URLFetcherTest { virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; }; +// Version of URLFetcherTest that does a POST of a file using +// SetUploadDataStream +class URLFetcherPostFileTest : public URLFetcherTest { + public: + URLFetcherPostFileTest(); + + // URLFetcherTest: + virtual void CreateFetcher(const GURL& url) OVERRIDE; + + // URLFetcherDelegate: + virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE; + + private: + base::FilePath path_; +}; + // Version of URLFetcherTest that does a POST instead with empty upload body class URLFetcherEmptyPostTest : public URLFetcherTest { public: @@ -504,6 +520,36 @@ void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source) { URLFetcherTest::OnURLFetchComplete(source); } +URLFetcherPostFileTest::URLFetcherPostFileTest() { + PathService::Get(base::DIR_SOURCE_ROOT, &path_); + path_ = path_.Append(FILE_PATH_LITERAL("net")); + path_ = path_.Append(FILE_PATH_LITERAL("data")); + path_ = path_.Append(FILE_PATH_LITERAL("url_request_unittest")); + path_ = path_.Append(FILE_PATH_LITERAL("BullRunSpeech.txt")); +} + +void URLFetcherPostFileTest::CreateFetcher(const GURL& url) { + fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); + fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter( + io_message_loop_proxy(), request_context())); + fetcher_->SetUploadFilePath("application/x-www-form-urlencoded", + path_, + base::MessageLoopProxy::current()); + fetcher_->Start(); +} + +void URLFetcherPostFileTest::OnURLFetchComplete(const URLFetcher* source) { + int64 size = 0; + ASSERT_EQ(true, file_util::GetFileSize(path_, &size)); + scoped_array<char> expected(new char[size]); + ASSERT_EQ(size, file_util::ReadFile(path_, expected.get(), size)); + + std::string data; + EXPECT_TRUE(source->GetResponseAsString(&data)); + EXPECT_EQ(std::string(&expected[0], size), data); + URLFetcherTest::OnURLFetchComplete(source); +} + void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) { fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this); fetcher_->SetRequestContext(new TestURLRequestContextGetter( @@ -1003,6 +1049,16 @@ TEST_F(URLFetcherPostTest, Basic) { MessageLoop::current()->Run(); } +TEST_F(URLFetcherPostFileTest, Basic) { + TestServer test_server(TestServer::TYPE_HTTP, + TestServer::kLocalhost, + base::FilePath(kDocRoot)); + ASSERT_TRUE(test_server.Start()); + + CreateFetcher(test_server.GetURL("echo")); + MessageLoop::current()->Run(); +} + TEST_F(URLFetcherEmptyPostTest, Basic) { TestServer test_server(TestServer::TYPE_HTTP, TestServer::kLocalhost, |