diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-24 07:10:22 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-24 07:10:22 +0000 |
commit | c38c4d0430b077c1f01f5e9e88784d8cdbe799e9 (patch) | |
tree | 30c208a25ae401cb107b4733c0a31d2963d944e5 /net | |
parent | bcee181553b7201d156f47e7ffb54305ad37336c (diff) | |
download | chromium_src-c38c4d0430b077c1f01f5e9e88784d8cdbe799e9.zip chromium_src-c38c4d0430b077c1f01f5e9e88784d8cdbe799e9.tar.gz chromium_src-c38c4d0430b077c1f01f5e9e88784d8cdbe799e9.tar.bz2 |
Add SetUploadDataStream method to URLFetcher.
BUG=169551
TEST=net_unittests
Review URL: https://chromiumcodereview.appspot.com/11843003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178535 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/url_request/test_url_fetcher_factory.cc | 7 | ||||
-rw-r--r-- | net/url_request/test_url_fetcher_factory.h | 9 | ||||
-rw-r--r-- | net/url_request/url_fetcher.h | 14 | ||||
-rw-r--r-- | net/url_request/url_fetcher_core.cc | 36 | ||||
-rw-r--r-- | net/url_request/url_fetcher_core.h | 4 | ||||
-rw-r--r-- | net/url_request/url_fetcher_impl.cc | 7 | ||||
-rw-r--r-- | net/url_request/url_fetcher_impl.h | 3 | ||||
-rw-r--r-- | net/url_request/url_fetcher_impl_unittest.cc | 60 |
8 files changed, 124 insertions, 16 deletions
diff --git a/net/url_request/test_url_fetcher_factory.cc b/net/url_request/test_url_fetcher_factory.cc index 08ba483..e645329 100644 --- a/net/url_request/test_url_fetcher_factory.cc +++ b/net/url_request/test_url_fetcher_factory.cc @@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop.h" #include "net/base/host_port_pair.h" +#include "net/base/upload_data_stream.h" #include "net/http/http_response_headers.h" #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_fetcher_impl.h" @@ -52,6 +53,12 @@ TestURLFetcher::~TestURLFetcher() { owner_->RemoveFetcherFromMap(id_); } +void TestURLFetcher::SetUploadDataStream( + const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content) { + upload_data_stream_ = upload_content.Pass(); +} + void TestURLFetcher::SetUploadData(const std::string& upload_content_type, const std::string& upload_content) { upload_data_ = upload_content; diff --git a/net/url_request/test_url_fetcher_factory.h b/net/url_request/test_url_fetcher_factory.h index 27f2f7a..d7f0d30 100644 --- a/net/url_request/test_url_fetcher_factory.h +++ b/net/url_request/test_url_fetcher_factory.h @@ -81,6 +81,9 @@ class TestURLFetcher : public URLFetcher { virtual ~TestURLFetcher(); // URLFetcher implementation + virtual void SetUploadDataStream( + const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content) OVERRIDE; virtual void SetUploadData(const std::string& upload_content_type, const std::string& upload_content) OVERRIDE; virtual void SetChunkedUpload( @@ -145,6 +148,11 @@ class TestURLFetcher : public URLFetcher { // Unique ID in our factory. int id() const { return id_; } + // Returns the data stream uploaded on this URLFetcher. + const UploadDataStream* upload_data_stream() const { + return upload_data_stream_.get(); + } + // Returns the data uploaded on this URLFetcher. const std::string& upload_data() const { return upload_data_; } @@ -186,6 +194,7 @@ class TestURLFetcher : public URLFetcher { URLFetcherDelegate* delegate_; DelegateForTests* delegate_for_tests_; std::string upload_data_; + scoped_ptr<UploadDataStream> upload_data_stream_; 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 79bbd17..211994d 100644 --- a/net/url_request/url_fetcher.h +++ b/net/url_request/url_fetcher.h @@ -10,6 +10,7 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "base/platform_file.h" #include "base/supports_user_data.h" #include "base/task_runner.h" @@ -27,6 +28,7 @@ namespace net { class HostPortPair; class HttpRequestHeaders; class HttpResponseHeaders; +class UploadDataStream; class URLFetcherDelegate; class URLRequestContextGetter; class URLRequestStatus; @@ -116,9 +118,15 @@ class NET_EXPORT URLFetcher { static void SetEnableInterceptionForTests(bool enabled); // 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 SetUploadData* 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. + virtual void SetUploadDataStream( + const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content) = 0; + + // Convenience method for setting upload data from a string. + // (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; diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc index 20fab1f..0578e16 100644 --- a/net/url_request/url_fetcher_core.cc +++ b/net/url_request/url_fetcher_core.cc @@ -329,17 +329,29 @@ void URLFetcherCore::Stop() { void URLFetcherCore::SetUploadData(const std::string& upload_content_type, const std::string& upload_content) { + scoped_ptr<UploadElementReader> reader( + UploadOwnedBytesElementReader::CreateWithString(upload_content)); + SetUploadDataStream( + upload_content_type, + make_scoped_ptr(UploadDataStream::CreateWithReader(reader.Pass(), 0))); +} + +void URLFetcherCore::SetUploadDataStream( + const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content) { DCHECK(!is_chunked_upload_); + DCHECK(!upload_content_); + DCHECK(upload_content_type_.empty()); upload_content_type_ = upload_content_type; - upload_content_ = upload_content; + upload_content_ = upload_content.Pass(); } void URLFetcherCore::SetChunkedUpload(const std::string& content_type) { DCHECK(is_chunked_upload_ || (upload_content_type_.empty() && - upload_content_.empty())); + !upload_content_)); upload_content_type_ = content_type; - upload_content_.clear(); + upload_content_.reset(); is_chunked_upload_ = true; } @@ -715,13 +727,8 @@ void URLFetcherCore::StartURLRequest() { request_type_ == URLFetcher::POST ? "POST" : "PUT"); extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType, upload_content_type_); - if (!upload_content_.empty()) { - scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader( - upload_content_.data(), upload_content_.size())); - request_->set_upload(make_scoped_ptr( - UploadDataStream::CreateWithReader(reader.Pass(), 0))); - } - + if (upload_content_) + request_->set_upload(upload_content_.Pass()); current_upload_bytes_ = -1; // TODO(kinaba): http://crbug.com/118103. Implement upload callback in the // layer and avoid using timer here. @@ -986,8 +993,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 fe4eec7..01dc965 100644 --- a/net/url_request/url_fetcher_core.h +++ b/net/url_request/url_fetcher_core.h @@ -61,6 +61,8 @@ class URLFetcherCore // For POST requests, set |content_type| to the MIME type of the // content and set |content| to the data to upload. + void SetUploadDataStream(const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content); void SetUploadData(const std::string& upload_content_type, const std::string& upload_content); void SetChunkedUpload(const std::string& upload_content_type); @@ -332,7 +334,7 @@ class URLFetcherCore bool was_fetched_via_proxy_; HostPortPair socket_address_; - std::string upload_content_; // HTTP POST payload + scoped_ptr<UploadDataStream> upload_content_; // HTTP 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 cdbd104..f7493de 100644 --- a/net/url_request/url_fetcher_impl.cc +++ b/net/url_request/url_fetcher_impl.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/message_loop_proxy.h" +#include "net/base/upload_data_stream.h" #include "net/url_request/url_fetcher_core.h" #include "net/url_request/url_fetcher_factory.h" @@ -24,6 +25,12 @@ URLFetcherImpl::~URLFetcherImpl() { core_->Stop(); } +void URLFetcherImpl::SetUploadDataStream( + const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content) { + core_->SetUploadDataStream(upload_content_type, upload_content.Pass()); +} + void URLFetcherImpl::SetUploadData(const std::string& upload_content_type, const std::string& upload_content) { core_->SetUploadData(upload_content_type, upload_content); diff --git a/net/url_request/url_fetcher_impl.h b/net/url_request/url_fetcher_impl.h index 9b0c1de..c8d7418ff 100644 --- a/net/url_request/url_fetcher_impl.h +++ b/net/url_request/url_fetcher_impl.h @@ -35,6 +35,9 @@ class NET_EXPORT_PRIVATE URLFetcherImpl : public URLFetcher { virtual ~URLFetcherImpl(); // URLFetcher implementation: + virtual void SetUploadDataStream( + const std::string& upload_content_type, + scoped_ptr<UploadDataStream> upload_content) OVERRIDE; virtual void SetUploadData(const std::string& upload_content_type, const std::string& upload_content) OVERRIDE; virtual void SetChunkedUpload( diff --git a/net/url_request/url_fetcher_impl_unittest.cc b/net/url_request/url_fetcher_impl_unittest.cc index a648ca2..0537ad1 100644 --- a/net/url_request/url_fetcher_impl_unittest.cc +++ b/net/url_request/url_fetcher_impl_unittest.cc @@ -17,6 +17,8 @@ #include "crypto/nss_util.h" #include "net/base/mock_host_resolver.h" #include "net/base/network_change_notifier.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/test/test_server.h" #include "net/url_request/url_fetcher_delegate.h" @@ -236,6 +238,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: + FilePath path_; +}; + // Version of URLFetcherTest that does a POST instead with empty upload body class URLFetcherEmptyPostTest : public URLFetcherTest { public: @@ -503,6 +521,38 @@ 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())); + scoped_ptr<UploadElementReader> reader(new UploadFileElementReader( + base::MessageLoopProxy::current(), path_, 0, kuint64max, base::Time())); + fetcher_->SetUploadDataStream( + "application/x-www-form-urlencoded", + make_scoped_ptr(UploadDataStream::CreateWithReader(reader.Pass(), 0))); + 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( @@ -1002,6 +1052,16 @@ TEST_F(URLFetcherPostTest, Basic) { MessageLoop::current()->Run(); } +TEST_F(URLFetcherPostFileTest, Basic) { + TestServer test_server(TestServer::TYPE_HTTP, + TestServer::kLocalhost, + 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, |