Skip to content

Commit

Permalink
Support range uploading of a file.
Browse files Browse the repository at this point in the history
URLFetcher currently supports uploading std::string or a whole file.
With this CL, URLFetcher also supports a part of file, which will be used
to upload a file from Drive file system.

BUG=234178
TEST=Ran unit_tests

Review URL: https://chromiumcodereview.appspot.com/14578004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@197878 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
hidehiko@chromium.org committed May 2, 2013
1 parent 2599bba commit 7b0db73
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 8 deletions.
3 changes: 3 additions & 0 deletions chrome/browser/safe_browsing/two_phase_uploader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "chrome/browser/safe_browsing/two_phase_uploader.h"

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/task_runner.h"
#include "net/base/net_errors.h"
Expand Down Expand Up @@ -134,6 +135,8 @@ void TwoPhaseUploader::UploadFile() {
url_fetcher_->SetRequestContext(url_request_context_getter_);
url_fetcher_->SetUploadFilePath(kUploadContentType,
file_path_,
0,
kuint64max,
file_task_runner_);
url_fetcher_->Start();
}
Expand Down
2 changes: 2 additions & 0 deletions net/url_request/test_url_fetcher_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ void TestURLFetcher::SetUploadData(const std::string& upload_content_type,
void TestURLFetcher::SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) {
upload_file_path_ = file_path;
}
Expand Down
2 changes: 2 additions & 0 deletions net/url_request/test_url_fetcher_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class TestURLFetcher : public URLFetcher {
virtual void SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) OVERRIDE;
virtual void SetChunkedUpload(
const std::string& upload_content_type) OVERRIDE;
Expand Down
4 changes: 4 additions & 0 deletions net/url_request/url_fetcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,14 @@ class NET_EXPORT URLFetcher {
// |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).
// |range_offset| and |range_length| specify the range of the part
// to be uploaded. To upload the whole file, (0, kuint64max) can be used.
// |file_task_runner| will be used for all file operations.
virtual void SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) = 0;

// Indicates that the POST data is sent via chunked transfer encoding.
Expand Down
12 changes: 11 additions & 1 deletion net/url_request/url_fetcher_core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ URLFetcherCore::URLFetcherCore(URLFetcher* fetcher,
url_request_data_key_(NULL),
was_fetched_via_proxy_(false),
upload_content_set_(false),
upload_range_offset_(0),
upload_range_length_(0),
is_chunked_upload_(false),
was_cancelled_(false),
file_writer_(NULL),
Expand Down Expand Up @@ -145,16 +147,22 @@ void URLFetcherCore::SetUploadData(const std::string& upload_content_type,
void URLFetcherCore::SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
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_EQ(upload_range_offset_, 0ULL);
DCHECK_EQ(upload_range_length_, 0ULL);
DCHECK(upload_content_type_.empty());
DCHECK(!upload_content_type.empty());

upload_content_type_ = upload_content_type;
upload_file_path_ = file_path;
upload_range_offset_ = range_offset;
upload_range_length_ = range_length;
upload_file_task_runner_ = file_task_runner;
upload_content_set_ = true;
}
Expand Down Expand Up @@ -569,7 +577,9 @@ void URLFetcherCore::StartURLRequest() {
scoped_ptr<UploadElementReader> reader(new UploadFileElementReader(
upload_file_task_runner_,
upload_file_path_,
0, kuint64max, base::Time()));
upload_range_offset_,
upload_range_length_,
base::Time()));
request_->set_upload(make_scoped_ptr(
UploadDataStream::CreateWithReader(reader.Pass(), 0)));
}
Expand Down
6 changes: 6 additions & 0 deletions net/url_request/url_fetcher_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class URLFetcherCore
const std::string& upload_content);
void SetUploadFilePath(const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
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
Expand Down Expand Up @@ -245,6 +247,10 @@ 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
uint64 upload_range_offset_; // Offset from the beginning of the file
// to be uploaded.
uint64 upload_range_length_; // The length of the part of file to be
// uploaded.
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
Expand Down
8 changes: 7 additions & 1 deletion net/url_request/url_fetcher_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ void URLFetcherImpl::SetUploadData(const std::string& upload_content_type,
void URLFetcherImpl::SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) {
core_->SetUploadFilePath(upload_content_type, file_path, file_task_runner);
core_->SetUploadFilePath(upload_content_type,
file_path,
range_offset,
range_length,
file_task_runner);
}

void URLFetcherImpl::SetChunkedUpload(const std::string& content_type) {
Expand Down
2 changes: 2 additions & 0 deletions net/url_request/url_fetcher_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class NET_EXPORT_PRIVATE URLFetcherImpl : public URLFetcher {
virtual void SetUploadFilePath(
const std::string& upload_content_type,
const base::FilePath& file_path,
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) OVERRIDE;
virtual void SetChunkedUpload(
const std::string& upload_content_type) OVERRIDE;
Expand Down
37 changes: 31 additions & 6 deletions net/url_request/url_fetcher_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "net/url_request/url_fetcher_impl.h"

#include <algorithm>
#include <string>

#include "base/bind.h"
Expand Down Expand Up @@ -243,6 +244,11 @@ class URLFetcherPostFileTest : public URLFetcherTest {
public:
URLFetcherPostFileTest();

void SetUploadRange(uint64 range_offset, uint64 range_length) {
range_offset_ = range_offset;
range_length_ = range_length;
}

// URLFetcherTest:
virtual void CreateFetcher(const GURL& url) OVERRIDE;

Expand All @@ -251,6 +257,8 @@ class URLFetcherPostFileTest : public URLFetcherTest {

private:
base::FilePath path_;
uint64 range_offset_;
uint64 range_length_;
};

// Version of URLFetcherTest that does a POST instead with empty upload body
Expand Down Expand Up @@ -524,7 +532,9 @@ void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source) {
URLFetcherTest::OnURLFetchComplete(source);
}

URLFetcherPostFileTest::URLFetcherPostFileTest() {
URLFetcherPostFileTest::URLFetcherPostFileTest()
: range_offset_(0),
range_length_(kuint64max) {
PathService::Get(base::DIR_SOURCE_ROOT, &path_);
path_ = path_.Append(FILE_PATH_LITERAL("net"));
path_ = path_.Append(FILE_PATH_LITERAL("data"));
Expand All @@ -538,19 +548,22 @@ void URLFetcherPostFileTest::CreateFetcher(const GURL& url) {
io_message_loop_proxy(), request_context()));
fetcher_->SetUploadFilePath("application/x-www-form-urlencoded",
path_,
range_offset_,
range_length_,
base::MessageLoopProxy::current());
fetcher_->Start();
}

void URLFetcherPostFileTest::OnURLFetchComplete(const URLFetcher* source) {
int64 size = 0;
ASSERT_EQ(true, file_util::GetFileSize(path_, &size));
scoped_ptr<char[]> expected(new char[size]);
ASSERT_EQ(size, file_util::ReadFile(path_, expected.get(), size));
std::string expected;
ASSERT_TRUE(file_util::ReadFileToString(path_, &expected));
ASSERT_LE(range_offset_, expected.size());
uint64 expected_size =
std::min(range_length_, expected.size() - range_offset_);

std::string data;
EXPECT_TRUE(source->GetResponseAsString(&data));
EXPECT_EQ(std::string(&expected[0], size), data);
EXPECT_EQ(expected.substr(range_offset_, expected_size), data);
URLFetcherTest::OnURLFetchComplete(source);
}

Expand Down Expand Up @@ -1063,6 +1076,18 @@ TEST_F(URLFetcherPostFileTest, Basic) {
MessageLoop::current()->Run();
}

TEST_F(URLFetcherPostFileTest, Range) {
TestServer test_server(TestServer::TYPE_HTTP,
TestServer::kLocalhost,
base::FilePath(kDocRoot));
ASSERT_TRUE(test_server.Start());

SetUploadRange(30, 100);

CreateFetcher(test_server.GetURL("echo"));
MessageLoop::current()->Run();
}

TEST_F(URLFetcherEmptyPostTest, Basic) {
TestServer test_server(TestServer::TYPE_HTTP,
TestServer::kLocalhost,
Expand Down

0 comments on commit 7b0db73

Please sign in to comment.