summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-24 07:10:22 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-24 07:10:22 +0000
commitc38c4d0430b077c1f01f5e9e88784d8cdbe799e9 (patch)
tree30c208a25ae401cb107b4733c0a31d2963d944e5 /net
parentbcee181553b7201d156f47e7ffb54305ad37336c (diff)
downloadchromium_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.cc7
-rw-r--r--net/url_request/test_url_fetcher_factory.h9
-rw-r--r--net/url_request/url_fetcher.h14
-rw-r--r--net/url_request/url_fetcher_core.cc36
-rw-r--r--net/url_request/url_fetcher_core.h4
-rw-r--r--net/url_request/url_fetcher_impl.cc7
-rw-r--r--net/url_request/url_fetcher_impl.h3
-rw-r--r--net/url_request/url_fetcher_impl_unittest.cc60
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,