summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 07:51:31 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 07:51:31 +0000
commit2c03980fa0873647293a0e8fade9b6d0adc1193c (patch)
tree0edbea1a354e6457af64991a5ee1d77cfab17349 /webkit
parentf7528eca39a09fab8d37f5435e2eb0ef7139776d (diff)
downloadchromium_src-2c03980fa0873647293a0e8fade9b6d0adc1193c.zip
chromium_src-2c03980fa0873647293a0e8fade9b6d0adc1193c.tar.gz
chromium_src-2c03980fa0873647293a0e8fade9b6d0adc1193c.tar.bz2
Split net::UploadData into two: for resource request IPC and for upload handling
Introducing webkit_glue::ResourceRequestBody as a content-level abstraction corresponding to WebHTTPBody and as an alternative of net::UploadData in ResourceRequest. This interface can contain content-level objects like Blob (or FileSystem URL in later patches) while net::UploadData should NOT. This patch also removes Blob support in net::UploadData. BUG=110119 TEST=existing tests Review URL: https://chromiumcodereview.appspot.com/10834289 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152528 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/blob/blob_storage_controller.cc29
-rw-r--r--webkit/blob/blob_storage_controller.h13
-rw-r--r--webkit/blob/blob_storage_controller_unittest.cc163
-rw-r--r--webkit/glue/resource_loader_bridge.h30
-rw-r--r--webkit/glue/resource_request_body.cc76
-rw-r--r--webkit/glue/resource_request_body.h181
-rw-r--r--webkit/glue/resource_request_body_unittest.cc48
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/glue/weburlloader_impl.cc16
-rw-r--r--webkit/tools/test_shell/simple_resource_loader_bridge.cc46
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
11 files changed, 440 insertions, 165 deletions
diff --git a/webkit/blob/blob_storage_controller.cc b/webkit/blob/blob_storage_controller.cc
index 6a10811..4c3c3bb 100644
--- a/webkit/blob/blob_storage_controller.cc
+++ b/webkit/blob/blob_storage_controller.cc
@@ -6,8 +6,10 @@
#include "base/logging.h"
#include "googleurl/src/gurl.h"
-#include "net/base/upload_data.h"
#include "webkit/blob/blob_data.h"
+#include "webkit/glue/resource_request_body.h"
+
+using webkit_glue::ResourceRequestBody;
namespace webkit_blob {
@@ -169,15 +171,15 @@ BlobData* BlobStorageController::GetBlobDataFromUrl(const GURL& url) {
return (found != blob_map_.end()) ? found->second : NULL;
}
-void BlobStorageController::ResolveBlobReferencesInUploadData(
- net::UploadData* upload_data) {
- DCHECK(upload_data);
+void BlobStorageController::ResolveBlobReferencesInRequestBody(
+ ResourceRequestBody* request_body) {
+ DCHECK(request_body);
- std::vector<net::UploadElement>* uploads =
- upload_data->elements_mutable();
- std::vector<net::UploadElement>::iterator iter;
+ std::vector<ResourceRequestBody::Element>* uploads =
+ request_body->elements_mutable();
+ std::vector<ResourceRequestBody::Element>::iterator iter;
for (iter = uploads->begin(); iter != uploads->end();) {
- if (iter->type() != net::UploadElement::TYPE_BLOB) {
+ if (iter->type() != ResourceRequestBody::TYPE_BLOB) {
iter++;
continue;
}
@@ -202,22 +204,19 @@ void BlobStorageController::ResolveBlobReferencesInUploadData(
// Ensure the blob and any attached shareable files survive until
// upload completion.
- upload_data->SetUserData(blob_data,
- new base::UserDataAdapter<BlobData>(blob_data));
+ request_body->SetUserData(
+ blob_data, new base::UserDataAdapter<BlobData>(blob_data));
// Insert the elements in the referred blob data.
// Note that we traverse from the bottom so that the elements can be
// inserted in the original order.
for (size_t i = blob_data->items().size(); i > 0; --i) {
- iter = uploads->insert(iter, net::UploadElement());
+ iter = uploads->insert(iter, ResourceRequestBody::Element());
const BlobData::Item& item = blob_data->items().at(i - 1);
switch (item.type) {
case BlobData::TYPE_DATA:
- // TODO(jianli): Figure out how to avoid copying the data.
- // TODO(michaeln): Now that blob_data surives for the duration,
- // maybe UploadData could take a raw ptr without having to copy.
- iter->SetToBytes(
+ iter->SetToSharedBytes(
&item.data.at(0) + static_cast<int>(item.offset),
static_cast<int>(item.length));
break;
diff --git a/webkit/blob/blob_storage_controller.h b/webkit/blob/blob_storage_controller.h
index a32fab3..fddd6ff 100644
--- a/webkit/blob/blob_storage_controller.h
+++ b/webkit/blob/blob_storage_controller.h
@@ -13,6 +13,7 @@
#include "base/process.h"
#include "webkit/blob/blob_data.h"
#include "webkit/blob/blob_export.h"
+#include "webkit/glue/resource_request_body.h"
class GURL;
class FilePath;
@@ -20,8 +21,9 @@ class FilePath;
namespace base {
class Time;
}
-namespace net {
-class UploadData;
+
+namespace webkit_glue {
+class ResourceRequestBody;
}
namespace webkit_blob {
@@ -40,9 +42,10 @@ class BLOB_EXPORT BlobStorageController {
void RemoveBlob(const GURL& url);
BlobData* GetBlobDataFromUrl(const GURL& url);
- // If there is any blob reference in the upload data, it will get resolved
- // and updated in place.
- void ResolveBlobReferencesInUploadData(net::UploadData* upload_data);
+ // If there is any blob reference in the resource request body, it will get
+ // resolved and updated in place.
+ void ResolveBlobReferencesInRequestBody(
+ webkit_glue::ResourceRequestBody* request_body);
private:
friend class ViewBlobInternalsJob;
diff --git a/webkit/blob/blob_storage_controller_unittest.cc b/webkit/blob/blob_storage_controller_unittest.cc
index ff98e22..48699a4 100644
--- a/webkit/blob/blob_storage_controller_unittest.cc
+++ b/webkit/blob/blob_storage_controller_unittest.cc
@@ -6,12 +6,12 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time.h"
-#include "net/base/upload_data.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/blob/blob_data.h"
#include "webkit/blob/blob_storage_controller.h"
+#include "webkit/glue/resource_request_body.h"
-using net::UploadData;
+using webkit_glue::ResourceRequestBody;
namespace webkit_blob {
@@ -76,7 +76,7 @@ TEST(BlobStorageControllerTest, RegisterBlobUrl) {
EXPECT_TRUE(!blob_data_found);
}
-TEST(BlobStorageControllerTest, ResolveBlobReferencesInUploadData) {
+TEST(BlobStorageControllerTest, ResolveBlobReferencesInRequestBody) {
// Setup blob data for testing.
base::Time time1, time2;
base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
@@ -102,7 +102,7 @@ TEST(BlobStorageControllerTest, ResolveBlobReferencesInUploadData) {
blob_storage_controller.CloneBlob(blob_url3, blob_url2);
// Setup upload data elements for comparison.
- net::UploadElement blob_element1, blob_element2;
+ ResourceRequestBody::Element blob_element1, blob_element2;
blob_element1.SetToBytes(
blob_data->items().at(0).data.c_str() +
static_cast<int>(blob_data->items().at(0).offset),
@@ -113,124 +113,131 @@ TEST(BlobStorageControllerTest, ResolveBlobReferencesInUploadData) {
blob_data->items().at(1).length,
blob_data->items().at(1).expected_modification_time);
- net::UploadElement upload_element1, upload_element2;
+ ResourceRequestBody::Element upload_element1, upload_element2;
upload_element1.SetToBytes("Hello", 5);
upload_element2.SetToFilePathRange(
FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2);
// Test no blob reference.
- scoped_refptr<UploadData> upload_data(new UploadData());
- upload_data->AppendBytes(
- &upload_element1.bytes().at(0),
- upload_element1.bytes().size());
- upload_data->AppendFileRange(
+ scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
+ request_body->AppendBytes(
+ upload_element1.bytes(),
+ upload_element1.bytes_length());
+ request_body->AppendFileRange(
upload_element2.file_path(),
upload_element2.file_range_offset(),
upload_element2.file_range_length(),
upload_element2.expected_file_modification_time());
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 2U);
- EXPECT_TRUE(upload_data->elements()->at(0) == upload_element1);
- EXPECT_TRUE(upload_data->elements()->at(1) == upload_element2);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 2U);
+ EXPECT_TRUE(request_body->elements()->at(0) == upload_element1);
+ EXPECT_TRUE(request_body->elements()->at(1) == upload_element2);
// Test having only one blob reference that refers to empty blob data.
- upload_data = new UploadData();
- upload_data->AppendBlob(blob_url0);
+ request_body = new ResourceRequestBody();
+ request_body->AppendBlob(blob_url0);
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 0U);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 0U);
// Test having only one blob reference.
- upload_data = new UploadData();
- upload_data->AppendBlob(blob_url1);
+ request_body = new ResourceRequestBody();
+ request_body->AppendBlob(blob_url1);
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 2U);
- EXPECT_TRUE(upload_data->elements()->at(0) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(1) == blob_element2);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 2U);
+ EXPECT_TRUE(request_body->elements()->at(0) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(1) == blob_element2);
// Test having one blob reference at the beginning.
- upload_data = new UploadData();
- upload_data->AppendBlob(blob_url1);
- upload_data->AppendBytes(
- &upload_element1.bytes().at(0),
- upload_element1.bytes().size());
- upload_data->AppendFileRange(
+ request_body = new ResourceRequestBody();
+ request_body->AppendBlob(blob_url1);
+ request_body->AppendBytes(
+ upload_element1.bytes(),
+ upload_element1.bytes_length());
+ request_body->AppendFileRange(
upload_element2.file_path(),
upload_element2.file_range_offset(),
upload_element2.file_range_length(),
upload_element2.expected_file_modification_time());
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 4U);
- EXPECT_TRUE(upload_data->elements()->at(0) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(1) == blob_element2);
- EXPECT_TRUE(upload_data->elements()->at(2) == upload_element1);
- EXPECT_TRUE(upload_data->elements()->at(3) == upload_element2);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 4U);
+ EXPECT_TRUE(request_body->elements()->at(0) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(1) == blob_element2);
+ EXPECT_TRUE(request_body->elements()->at(2) == upload_element1);
+ EXPECT_TRUE(request_body->elements()->at(3) == upload_element2);
// Test having one blob reference at the end.
- upload_data = new UploadData();
- upload_data->AppendBytes(
- &upload_element1.bytes().at(0),
- upload_element1.bytes().size());
- upload_data->AppendFileRange(
+ request_body = new ResourceRequestBody();
+ request_body->AppendBytes(
+ upload_element1.bytes(),
+ upload_element1.bytes_length());
+ request_body->AppendFileRange(
upload_element2.file_path(),
upload_element2.file_range_offset(),
upload_element2.file_range_length(),
upload_element2.expected_file_modification_time());
- upload_data->AppendBlob(blob_url1);
+ request_body->AppendBlob(blob_url1);
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 4U);
- EXPECT_TRUE(upload_data->elements()->at(0) == upload_element1);
- EXPECT_TRUE(upload_data->elements()->at(1) == upload_element2);
- EXPECT_TRUE(upload_data->elements()->at(2) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(3) == blob_element2);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 4U);
+ EXPECT_TRUE(request_body->elements()->at(0) == upload_element1);
+ EXPECT_TRUE(request_body->elements()->at(1) == upload_element2);
+ EXPECT_TRUE(request_body->elements()->at(2) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(3) == blob_element2);
// Test having one blob reference in the middle.
- upload_data = new UploadData();
- upload_data->AppendBytes(
- &upload_element1.bytes().at(0),
- upload_element1.bytes().size());
- upload_data->AppendBlob(blob_url1);
- upload_data->AppendFileRange(
+ request_body = new ResourceRequestBody();
+ request_body->AppendBytes(
+ upload_element1.bytes(),
+ upload_element1.bytes_length());
+ request_body->AppendBlob(blob_url1);
+ request_body->AppendFileRange(
upload_element2.file_path(),
upload_element2.file_range_offset(),
upload_element2.file_range_length(),
upload_element2.expected_file_modification_time());
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 4U);
- EXPECT_TRUE(upload_data->elements()->at(0) == upload_element1);
- EXPECT_TRUE(upload_data->elements()->at(1) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(2) == blob_element2);
- EXPECT_TRUE(upload_data->elements()->at(3) == upload_element2);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 4U);
+ EXPECT_TRUE(request_body->elements()->at(0) == upload_element1);
+ EXPECT_TRUE(request_body->elements()->at(1) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(2) == blob_element2);
+ EXPECT_TRUE(request_body->elements()->at(3) == upload_element2);
// Test having multiple blob references.
- upload_data = new UploadData();
- upload_data->AppendBlob(blob_url1);
- upload_data->AppendBytes(
- &upload_element1.bytes().at(0),
- upload_element1.bytes().size());
- upload_data->AppendBlob(blob_url2);
- upload_data->AppendBlob(blob_url3);
- upload_data->AppendFileRange(
+ request_body = new ResourceRequestBody();
+ request_body->AppendBlob(blob_url1);
+ request_body->AppendBytes(
+ upload_element1.bytes(),
+ upload_element1.bytes_length());
+ request_body->AppendBlob(blob_url2);
+ request_body->AppendBlob(blob_url3);
+ request_body->AppendFileRange(
upload_element2.file_path(),
upload_element2.file_range_offset(),
upload_element2.file_range_length(),
upload_element2.expected_file_modification_time());
- blob_storage_controller.ResolveBlobReferencesInUploadData(upload_data.get());
- ASSERT_EQ(upload_data->elements()->size(), 8U);
- EXPECT_TRUE(upload_data->elements()->at(0) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(1) == blob_element2);
- EXPECT_TRUE(upload_data->elements()->at(2) == upload_element1);
- EXPECT_TRUE(upload_data->elements()->at(3) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(4) == blob_element2);
- EXPECT_TRUE(upload_data->elements()->at(5) == blob_element1);
- EXPECT_TRUE(upload_data->elements()->at(6) == blob_element2);
- EXPECT_TRUE(upload_data->elements()->at(7) == upload_element2);
+ blob_storage_controller.ResolveBlobReferencesInRequestBody(
+ request_body.get());
+ ASSERT_EQ(request_body->elements()->size(), 8U);
+ EXPECT_TRUE(request_body->elements()->at(0) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(1) == blob_element2);
+ EXPECT_TRUE(request_body->elements()->at(2) == upload_element1);
+ EXPECT_TRUE(request_body->elements()->at(3) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(4) == blob_element2);
+ EXPECT_TRUE(request_body->elements()->at(5) == blob_element1);
+ EXPECT_TRUE(request_body->elements()->at(6) == blob_element2);
+ EXPECT_TRUE(request_body->elements()->at(7) == upload_element2);
}
} // namespace webkit_blob
diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h
index 70db933..e699574 100644
--- a/webkit/glue/resource_loader_bridge.h
+++ b/webkit/glue/resource_loader_bridge.h
@@ -41,6 +41,7 @@ class HttpResponseHeaders;
}
namespace webkit_glue {
+class ResourceRequestBody;
// Structure containing timing information for the request. It addresses
// http://groups.google.com/group/http-archive-specification/web/har-1-1-spec
@@ -348,32 +349,9 @@ class ResourceLoaderBridge {
// anybody can delete at any time, INCLUDING during processing of callbacks.
WEBKIT_GLUE_EXPORT virtual ~ResourceLoaderBridge();
- // Call this method before calling Start() to append a chunk of binary data
- // to the request body. May only be used with HTTP(S) POST requests.
- virtual void AppendDataToUpload(const char* data, int data_len) = 0;
-
- // Call this method before calling Start() to append the contents of a file
- // to the request body. May only be used with HTTP(S) POST requests.
- void AppendFileToUpload(const FilePath& file_path) {
- AppendFileRangeToUpload(file_path, 0, kuint64max, base::Time());
- }
-
- // Call this method before calling Start() to append the contents of a file
- // to the request body. May only be used with HTTP(S) POST requests.
- virtual void AppendFileRangeToUpload(
- const FilePath& file_path,
- uint64 offset,
- uint64 length,
- const base::Time& expected_modification_time) = 0;
-
- // Call this method before calling Start() to append the contents of a blob
- // to the request body. May only be used with HTTP(S) POST requests.
- virtual void AppendBlobToUpload(const GURL& blob_url) = 0;
-
- // Call this method before calling Start() to assign an upload identifier to
- // this request. This is used to enable caching of POST responses. A value
- // of 0 implies the unspecified identifier.
- virtual void SetUploadIdentifier(int64 identifier) = 0;
+ // Call this method before calling Start() to set the request body.
+ // May only be used with HTTP(S) POST requests.
+ virtual void SetRequestBody(ResourceRequestBody* request_body) = 0;
// Call this method to initiate the request. If this method succeeds, then
// the peer's methods will be called asynchronously to report various events.
diff --git a/webkit/glue/resource_request_body.cc b/webkit/glue/resource_request_body.cc
new file mode 100644
index 0000000..1cd10e8
--- /dev/null
+++ b/webkit/glue/resource_request_body.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/resource_request_body.h"
+
+#include "base/logging.h"
+#include "net/base/upload_data.h"
+
+namespace webkit_glue {
+
+ResourceRequestBody::Element::Element()
+ : type_(TYPE_BYTES),
+ bytes_start_(NULL),
+ bytes_length_(0),
+ file_range_offset_(0),
+ file_range_length_(kuint64max) {
+}
+
+ResourceRequestBody::Element::~Element() {}
+
+ResourceRequestBody::ResourceRequestBody() : identifier_(0) {}
+
+void ResourceRequestBody::AppendBytes(const char* bytes, int bytes_len) {
+ if (bytes_len > 0) {
+ elements_.push_back(Element());
+ elements_.back().SetToBytes(bytes, bytes_len);
+ }
+}
+
+void ResourceRequestBody::AppendFileRange(
+ const FilePath& file_path,
+ uint64 offset, uint64 length,
+ const base::Time& expected_modification_time) {
+ elements_.push_back(Element());
+ elements_.back().SetToFilePathRange(file_path, offset, length,
+ expected_modification_time);
+}
+
+void ResourceRequestBody::AppendBlob(const GURL& blob_url) {
+ elements_.push_back(Element());
+ elements_.back().SetToBlobUrl(blob_url);
+}
+
+net::UploadData* ResourceRequestBody::CreateUploadData() {
+ net::UploadData* upload_data = new net::UploadData;
+ // We attach 'this' to UploadData so that we do not need to copy
+ // bytes for TYPE_BYTES.
+ upload_data->SetUserData(
+ this, new base::UserDataAdapter<ResourceRequestBody>(this));
+ std::vector<net::UploadElement>* uploads =
+ upload_data->elements_mutable();
+ for (size_t i = 0; i < elements_.size(); ++i) {
+ const Element& element = elements_[i];
+ if (element.type() == TYPE_BYTES) {
+ uploads->push_back(net::UploadElement());
+ uploads->back().SetToSharedBytes(element.bytes(),
+ element.bytes_length());
+ continue;
+ }
+
+ DCHECK(element.type() == TYPE_FILE);
+ uploads->push_back(net::UploadElement());
+ uploads->back().SetToFilePathRange(
+ element.file_path(),
+ element.file_range_offset(),
+ element.file_range_length(),
+ element.expected_file_modification_time());
+ }
+ upload_data->set_identifier(identifier_);
+ return upload_data;
+}
+
+ResourceRequestBody::~ResourceRequestBody() {}
+
+} // namespace webkit_glue
diff --git a/webkit/glue/resource_request_body.h b/webkit/glue/resource_request_body.h
new file mode 100644
index 0000000..0b3ef0d
--- /dev/null
+++ b/webkit/glue/resource_request_body.h
@@ -0,0 +1,181 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_GLUE_RESOURCE_REQUEST_BODY_H_
+#define WEBKIT_GLUE_RESOURCE_REQUEST_BODY_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/supports_user_data.h"
+#include "base/time.h"
+#include "googleurl/src/gurl.h"
+#include "webkit/glue/webkit_glue_export.h"
+
+namespace net {
+class UploadData;
+}
+
+namespace webkit_glue {
+
+// A struct used to represent upload data. The data field is populated by
+// WebURLLoader from the data given as WebHTTPBody.
+// TODO(kinuko): This is basically a duplicate of net::UploadData but
+// with support for higher-level abstraction data. We should reduce the
+// code duplicate by sharing code for similar data structs:
+// ResourceRequestBody::Element and BlobData::Item.
+class WEBKIT_GLUE_EXPORT ResourceRequestBody
+ : public base::RefCounted<ResourceRequestBody>,
+ public base::SupportsUserData {
+ public:
+ enum Type {
+ TYPE_BYTES,
+ TYPE_FILE,
+ TYPE_BLOB,
+ };
+
+ class WEBKIT_GLUE_EXPORT Element {
+ public:
+ Element();
+ ~Element();
+
+ Type type() const { return type_; }
+ // Explicitly sets the type of this Element. Used during IPC
+ // marshalling.
+ void set_type(Type type) {
+ type_ = type;
+ }
+
+ const char* bytes() const { return bytes_start_ ? bytes_start_ : &buf_[0]; }
+ uint64 bytes_length() const { return buf_.size() + bytes_length_; }
+ const FilePath& file_path() const { return file_path_; }
+ uint64 file_range_offset() const { return file_range_offset_; }
+ uint64 file_range_length() const { return file_range_length_; }
+ // If NULL time is returned, we do not do the check.
+ const base::Time& expected_file_modification_time() const {
+ return expected_file_modification_time_;
+ }
+ const GURL& blob_url() const { return blob_url_; }
+
+ void SetToBytes(const char* bytes, int bytes_len) {
+ type_ = TYPE_BYTES;
+ buf_.assign(bytes, bytes + bytes_len);
+ }
+
+ // This does not copy the given data and the caller should make sure
+ // the data is secured somewhere else (e.g. by attaching the data
+ // using SetUserData).
+ void SetToSharedBytes(const char* bytes, int bytes_len) {
+ type_ = TYPE_BYTES;
+ bytes_start_ = bytes;
+ bytes_length_ = bytes_len;
+ }
+
+ void SetToFilePath(const FilePath& path) {
+ SetToFilePathRange(path, 0, kuint64max, base::Time());
+ }
+
+ // If expected_modification_time is NULL, we do not check for the file
+ // change. Also note that the granularity for comparison is time_t, not
+ // the full precision.
+ void SetToFilePathRange(const FilePath& path,
+ uint64 offset, uint64 length,
+ const base::Time& expected_modification_time) {
+ type_ = TYPE_FILE;
+ file_path_ = path;
+ file_range_offset_ = offset;
+ file_range_length_ = length;
+ expected_file_modification_time_ = expected_modification_time;
+ }
+
+ void SetToBlobUrl(const GURL& blob_url) {
+ type_ = TYPE_BLOB;
+ blob_url_ = blob_url;
+ }
+
+ private:
+ Type type_;
+ std::vector<char> buf_;
+ const char* bytes_start_;
+ uint64 bytes_length_;
+ FilePath file_path_;
+ uint64 file_range_offset_;
+ uint64 file_range_length_;
+ base::Time expected_file_modification_time_;
+ GURL blob_url_;
+ };
+
+ ResourceRequestBody();
+
+ void AppendBytes(const char* bytes, int bytes_len);
+ void AppendFileRange(const FilePath& file_path,
+ uint64 offset, uint64 length,
+ const base::Time& expected_modification_time);
+ void AppendBlob(const GURL& blob_url);
+
+ // Creates a new UploadData from this request body.
+ // At this stage the elements should not contain any TYPE_BLOB items
+ // (i.e. must have resolved them by ResolveBlobReferencesInUploadData).
+ // TODO(kinuko): Clean up this hack.
+ net::UploadData* CreateUploadData();
+
+ const std::vector<Element>* elements() const {
+ return &elements_;
+ }
+
+ std::vector<Element>* elements_mutable() {
+ return &elements_;
+ }
+
+ void swap_elements(std::vector<Element>* elements) {
+ elements_.swap(*elements);
+ }
+
+ // Identifies a particular upload instance, which is used by the cache to
+ // formulate a cache key. This value should be unique across browser
+ // sessions. A value of 0 is used to indicate an unspecified identifier.
+ void set_identifier(int64 id) { identifier_ = id; }
+ int64 identifier() const { return identifier_; }
+
+ private:
+ friend class base::RefCounted<ResourceRequestBody>;
+ virtual ~ResourceRequestBody();
+
+ std::vector<Element> elements_;
+ int64 identifier_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResourceRequestBody);
+};
+
+#if defined(UNIT_TEST)
+inline bool operator==(const ResourceRequestBody::Element& a,
+ const ResourceRequestBody::Element& b) {
+ if (a.type() != b.type())
+ return false;
+ if (a.type() == ResourceRequestBody::TYPE_BYTES)
+ return a.bytes_length() == b.bytes_length() &&
+ memcmp(a.bytes(), b.bytes(), b.bytes_length()) == 0;
+ if (a.type() == ResourceRequestBody::TYPE_FILE) {
+ return a.file_path() == b.file_path() &&
+ a.file_range_offset() == b.file_range_offset() &&
+ a.file_range_length() == b.file_range_length() &&
+ a.expected_file_modification_time() ==
+ b.expected_file_modification_time();
+ }
+ if (a.type() == ResourceRequestBody::TYPE_BLOB)
+ return a.blob_url() == b.blob_url();
+ return false;
+}
+
+inline bool operator!=(const ResourceRequestBody::Element& a,
+ const ResourceRequestBody::Element& b) {
+ return !(a == b);
+}
+#endif // defined(UNIT_TEST)
+
+} // namespace webkit_glue
+
+#endif // WEBKIT_GLUE_RESOURCE_REQUEST_BODY_H_
diff --git a/webkit/glue/resource_request_body_unittest.cc b/webkit/glue/resource_request_body_unittest.cc
new file mode 100644
index 0000000..897eb56
--- /dev/null
+++ b/webkit/glue/resource_request_body_unittest.cc
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/resource_request_body.h"
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/time.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/upload_data.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace webkit_glue {
+
+TEST(ResourceRequestBodyTest, CreateUploadDataTest) {
+ scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody;
+
+ const char kData[] = "123";
+ const FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc");
+ const uint64 kFileOffset = 10U;
+ const uint64 kFileLength = 100U;
+ const base::Time kFileTime = base::Time::FromDoubleT(999);
+ const int64 kIdentifier = 12345;
+
+ request_body->AppendBytes(kData, arraysize(kData) - 1);
+ request_body->AppendFileRange(FilePath(kFilePath),
+ kFileOffset, kFileLength, kFileTime);
+ request_body->set_identifier(kIdentifier);
+
+ scoped_refptr<net::UploadData> upload = request_body->CreateUploadData();
+
+ EXPECT_EQ(kIdentifier, upload->identifier());
+ ASSERT_EQ(request_body->elements()->size(), upload->elements()->size());
+
+ const net::UploadElement& e1 = upload->elements()->at(0);
+ EXPECT_EQ(net::UploadElement::TYPE_BYTES, e1.type());
+ EXPECT_EQ(kData, std::string(e1.bytes(), e1.bytes_length()));
+
+ const net::UploadElement& e2 = upload->elements()->at(1);
+ EXPECT_EQ(net::UploadElement::TYPE_FILE, e2.type());
+ EXPECT_EQ(kFilePath, e2.file_path().value());
+ EXPECT_EQ(kFileOffset, e2.file_range_offset());
+ EXPECT_EQ(kFileLength, e2.file_range_length());
+ EXPECT_EQ(kFileTime, e2.expected_file_modification_time());
+}
+
+} // namespace webkit_glue
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index ab23ee8..fa06cbd 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -378,6 +378,8 @@
'resource_fetcher.h',
'resource_loader_bridge.cc',
'resource_loader_bridge.h',
+ 'resource_request_body.cc',
+ 'resource_request_body.h',
'resource_type.cc',
'resource_type.h',
'scoped_clipboard_writer_glue.cc',
diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc
index 104795d..edc15424 100644
--- a/webkit/glue/weburlloader_impl.cc
+++ b/webkit/glue/weburlloader_impl.cc
@@ -32,6 +32,7 @@
#include "webkit/glue/ftp_directory_listing_response_delegate.h"
#include "webkit/glue/multipart_response_delegate.h"
#include "webkit/glue/resource_loader_bridge.h"
+#include "webkit/glue/resource_request_body.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webkitplatformsupport_impl.h"
#include "webkit/glue/weburlrequest_extradata_impl.h"
@@ -444,22 +445,24 @@ void WebURLLoaderImpl::Context::Start(
const WebHTTPBody& httpBody = request.httpBody();
size_t i = 0;
WebHTTPBody::Element element;
+ scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody;
while (httpBody.elementAt(i++, element)) {
switch (element.type) {
case WebHTTPBody::Element::TypeData:
if (!element.data.isEmpty()) {
// WebKit sometimes gives up empty data to append. These aren't
// necessary so we just optimize those out here.
- bridge_->AppendDataToUpload(
+ request_body->AppendBytes(
element.data.data(), static_cast<int>(element.data.size()));
}
break;
case WebHTTPBody::Element::TypeFile:
if (element.fileLength == -1) {
- bridge_->AppendFileToUpload(
- WebStringToFilePath(element.filePath));
+ request_body->AppendFileRange(
+ WebStringToFilePath(element.filePath),
+ 0, kuint64max, base::Time());
} else {
- bridge_->AppendFileRangeToUpload(
+ request_body->AppendFileRange(
WebStringToFilePath(element.filePath),
static_cast<uint64>(element.fileStart),
static_cast<uint64>(element.fileLength),
@@ -467,13 +470,14 @@ void WebURLLoaderImpl::Context::Start(
}
break;
case WebHTTPBody::Element::TypeBlob:
- bridge_->AppendBlobToUpload(GURL(element.blobURL));
+ request_body->AppendBlob(GURL(element.blobURL));
break;
default:
NOTREACHED();
}
}
- bridge_->SetUploadIdentifier(request.httpBody().identifier());
+ request_body->set_identifier(request.httpBody().identifier());
+ bridge_->SetRequestBody(request_body);
}
if (sync_load_response) {
diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
index e8caad4..6af385a 100644
--- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc
+++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc
@@ -68,6 +68,7 @@
#include "webkit/fileapi/file_system_dir_url_request_job.h"
#include "webkit/fileapi/file_system_url_request_job.h"
#include "webkit/glue/resource_loader_bridge.h"
+#include "webkit/glue/resource_request_body.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/tools/test_shell/simple_appcache_system.h"
#include "webkit/tools/test_shell/simple_file_system.h"
@@ -81,6 +82,7 @@
#endif
using webkit_glue::ResourceLoaderBridge;
+using webkit_glue::ResourceRequestBody;
using webkit_glue::ResourceResponseInfo;
using net::StaticCookiePolicy;
using net::HttpResponseHeaders;
@@ -279,7 +281,7 @@ struct RequestParams {
ResourceType::Type request_type;
int appcache_host_id;
bool download_to_file;
- scoped_refptr<net::UploadData> upload;
+ scoped_refptr<ResourceRequestBody> request_body;
};
// The interval for calls to RequestProxy::MaybeUpdateUploadProgress
@@ -415,10 +417,10 @@ class RequestProxy
void AsyncStart(RequestParams* params) {
// Might need to resolve the blob references in the upload data.
- if (params->upload) {
+ if (params->request_body) {
static_cast<TestShellRequestContext*>(g_request_context)->
- blob_storage_controller()->ResolveBlobReferencesInUploadData(
- params->upload.get());
+ blob_storage_controller()->ResolveBlobReferencesInRequestBody(
+ params->request_body.get());
}
request_.reset(new net::URLRequest(params->url, this, g_request_context));
@@ -431,7 +433,8 @@ class RequestProxy
headers.AddHeadersFromString(params->headers);
request_->SetExtraRequestHeaders(headers);
request_->set_load_flags(params->load_flags);
- request_->set_upload(params->upload.get());
+ if (params->request_body)
+ request_->set_upload(params->request_body->CreateUploadData());
SimpleAppCacheSystem::SetExtraRequestInfo(
request_.get(), params->appcache_host_id, params->request_type);
@@ -874,37 +877,10 @@ class ResourceLoaderBridgeImpl : public ResourceLoaderBridge {
// --------------------------------------------------------------------------
// ResourceLoaderBridge implementation:
- virtual void AppendDataToUpload(const char* data, int data_len) {
+ virtual void SetRequestBody(ResourceRequestBody* request_body) {
DCHECK(params_.get());
- if (!params_->upload)
- params_->upload = new net::UploadData();
- params_->upload->AppendBytes(data, data_len);
- }
-
- virtual void AppendFileRangeToUpload(
- const FilePath& file_path,
- uint64 offset,
- uint64 length,
- const base::Time& expected_modification_time) {
- DCHECK(params_.get());
- if (!params_->upload)
- params_->upload = new net::UploadData();
- params_->upload->AppendFileRange(file_path, offset, length,
- expected_modification_time);
- }
-
- virtual void AppendBlobToUpload(const GURL& blob_url) {
- DCHECK(params_.get());
- if (!params_->upload)
- params_->upload = new net::UploadData();
- params_->upload->AppendBlob(blob_url);
- }
-
- virtual void SetUploadIdentifier(int64 identifier) {
- DCHECK(params_.get());
- if (!params_->upload)
- params_->upload = new net::UploadData();
- params_->upload->set_identifier(identifier);
+ DCHECK(!params_->request_body);
+ params_->request_body = request_body;
}
virtual bool Start(Peer* peer) {
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 7a832b2..378cfd30 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -372,6 +372,7 @@
'../../glue/multipart_response_delegate_unittest.cc',
'../../glue/regular_expression_unittest.cc',
'../../glue/resource_fetcher_unittest.cc',
+ '../../glue/resource_request_body_unittest.cc',
'../../glue/unittest_test_server.h',
'../../glue/webcursor_unittest.cc',
'../../glue/webkit_glue_unittest.cc',