Commit aba8000c authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Add a DataElement::TYPE_RAW_FILE type that contains a file handle.

This, or something like it, will eventually need to replace TYPE_FILE
(Which just contains a path) in order to sandbox the network service
process.

Bug: 777879
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I8c67e828288443cbfc15aa774c1b97aa2f22ef29
Reviewed-on: https://chromium-review.googlesource.com/773238
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#518390}
parent 9984945d
......@@ -170,6 +170,7 @@ void BlobDispatcherHost::OnRegisterBlob(
// originally created by other processes? If so, is that cool?
break;
}
case storage::DataElement::TYPE_RAW_FILE:
case storage::DataElement::TYPE_UNKNOWN:
case storage::DataElement::TYPE_DATA_PIPE:
case storage::DataElement::TYPE_DISK_CACHE_ENTRY: {
......
......@@ -111,6 +111,7 @@ std::unique_ptr<net::UploadDataStream> UploadDataStreamBuilder::Build(
case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
CHECK(false) << "Should never be reached";
break;
case ResourceRequestBody::Element::TYPE_RAW_FILE:
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_DATA_PIPE:
......
......@@ -453,6 +453,7 @@ void WriteResourceRequestBody(const ResourceRequestBody& request_body,
WriteInteger(blink::WebHTTPBody::Element::kTypeBlob, obj);
WriteStdString(element.blob_uuid(), obj);
break;
case ResourceRequestBody::Element::TYPE_RAW_FILE:
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
default:
......@@ -744,6 +745,7 @@ void WriteResourceRequestBody(const ResourceRequestBody& request_body,
case ResourceRequestBody::Element::TYPE_BLOB:
data_element->set_blob_uuid(element.blob_uuid());
break;
case ResourceRequestBody::Element::TYPE_RAW_FILE:
case ResourceRequestBody::Element::TYPE_BYTES_DESCRIPTION:
case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY:
case ResourceRequestBody::Element::TYPE_DATA_PIPE:
......
......@@ -4,7 +4,10 @@
#include "content/common/resource_messages.h"
#include "base/files/file.h"
#include "base/files/platform_file.h"
#include "ipc/ipc_mojo_param_traits.h"
#include "ipc/ipc_platform_file.h"
#include "net/base/load_timing_info.h"
#include "net/http/http_response_headers.h"
......@@ -154,6 +157,16 @@ void ParamTraits<storage::DataElement>::Write(base::Pickle* m,
WriteParam(m, p.expected_modification_time());
break;
}
case storage::DataElement::TYPE_RAW_FILE: {
WriteParam(
m, IPC::GetPlatformFileForTransit(p.file().GetPlatformFile(),
false /* close_source_handle */));
WriteParam(m, p.path());
WriteParam(m, p.offset());
WriteParam(m, p.length());
WriteParam(m, p.expected_modification_time());
break;
}
case storage::DataElement::TYPE_FILE_FILESYSTEM: {
WriteParam(m, p.filesystem_url());
WriteParam(m, p.offset());
......@@ -224,6 +237,27 @@ bool ParamTraits<storage::DataElement>::Read(const base::Pickle* m,
expected_modification_time);
return true;
}
case storage::DataElement::TYPE_RAW_FILE: {
IPC::PlatformFileForTransit platform_file_for_transit;
if (!ReadParam(m, iter, &platform_file_for_transit))
return false;
base::File file = PlatformFileForTransitToFile(platform_file_for_transit);
base::FilePath file_path;
if (!ReadParam(m, iter, &file_path))
return false;
uint64_t offset;
if (!ReadParam(m, iter, &offset))
return false;
uint64_t length;
if (!ReadParam(m, iter, &length))
return false;
base::Time expected_modification_time;
if (!ReadParam(m, iter, &expected_modification_time))
return false;
r->SetToFileRange(std::move(file), file_path, offset, length,
expected_modification_time);
return true;
}
case storage::DataElement::TYPE_FILE_FILESYSTEM: {
GURL file_system_url;
uint64_t offset, length;
......
......@@ -15,6 +15,7 @@ include_rules = [
"+content/public/common/network_service.mojom.h",
"+content/public/common/referrer.h",
"+content/public/common/resource_request.h",
"+content/public/common/resource_request_body.h",
"+content/public/common/resource_response.h",
"+content/public/common/url_constants.h",
"+content/public/common/url_loader.mojom.h",
......
......@@ -6,6 +6,7 @@
#include <string>
#include "base/files/file.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/task_scheduler/post_task.h"
......@@ -15,6 +16,8 @@
#include "content/network/network_context.h"
#include "content/network/network_service_impl.h"
#include "content/public/common/referrer.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_request_body.h"
#include "content/public/common/resource_response.h"
#include "content/public/common/url_loader_factory.mojom.h"
#include "mojo/public/cpp/system/simple_watcher.h"
......@@ -140,6 +143,31 @@ class FileElementReader : public net::UploadFileElementReader {
DISALLOW_COPY_AND_ASSIGN(FileElementReader);
};
class RawFileElementReader : public net::UploadFileElementReader {
public:
RawFileElementReader(ResourceRequestBody* resource_request_body,
base::TaskRunner* task_runner,
const ResourceRequestBody::Element& element)
: net::UploadFileElementReader(
task_runner,
// TODO(mmenke): Is duplicating this necessary?
element.file().Duplicate(),
element.path(),
element.offset(),
element.length(),
element.expected_modification_time()),
resource_request_body_(resource_request_body) {
DCHECK_EQ(ResourceRequestBody::Element::TYPE_RAW_FILE, element.type());
}
~RawFileElementReader() override {}
private:
scoped_refptr<ResourceRequestBody> resource_request_body_;
DISALLOW_COPY_AND_ASSIGN(RawFileElementReader);
};
// A subclass of net::UploadElementReader to read data pipes.
class DataPipeElementReader : public net::UploadElementReader {
public:
......@@ -247,6 +275,10 @@ std::unique_ptr<net::UploadDataStream> CreateUploadDataStream(
element_readers.push_back(std::make_unique<FileElementReader>(
body, file_task_runner, element));
break;
case ResourceRequestBody::Element::TYPE_RAW_FILE:
element_readers.push_back(std::make_unique<RawFileElementReader>(
body, file_task_runner, element));
break;
case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM:
CHECK(false) << "Should never be reached";
break;
......
......@@ -2,26 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <limits>
#include <list>
#include <memory>
#include <string>
#include "base/compiler_specific.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/network/network_context.h"
#include "content/network/url_loader.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_request_body.h"
#include "content/public/test/controllable_http_response.h"
#include "content/public/test/test_url_loader_client.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/cpp/system/wait.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_sniffer.h"
#include "net/base/net_errors.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/url_request/url_request_failed_job.h"
......@@ -32,6 +43,7 @@
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_status.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace content {
......@@ -177,7 +189,8 @@ class URLLoaderTest : public testing::Test {
DCHECK(!ran_);
mojom::URLLoaderPtr loader;
ResourceRequest request = CreateResourceRequest("GET", resource_type_, url);
ResourceRequest request = CreateResourceRequest(
!request_body_ ? "GET" : "POST", resource_type_, url);
uint32_t options = mojom::kURLLoadOptionNone;
if (send_ssl_)
options |= mojom::kURLLoadOptionSendSSLInfo;
......@@ -186,6 +199,9 @@ class URLLoaderTest : public testing::Test {
if (add_custom_accept_header_)
request.headers.SetHeader("accept", "custom/*");
if (request_body_)
request.request_body = request_body_;
URLLoader loader_impl(context(), mojo::MakeRequest(&loader), options,
request, false, client_.CreateInterfacePtr(),
TRAFFIC_ANNOTATION_FOR_TESTS, 0);
......@@ -208,9 +224,7 @@ class URLLoaderTest : public testing::Test {
}
void LoadAndCompareFile(const std::string& path) {
base::FilePath file;
PathService::Get(content::DIR_TEST_DATA, &file);
file = file.AppendASCII(path);
base::FilePath file = GetTestFilePath(path);
std::string expected;
if (!base::ReadFileToString(file, &expected)) {
......@@ -276,6 +290,23 @@ class URLLoaderTest : public testing::Test {
TestURLLoaderClient* client() { return &client_; }
void DestroyContext() { context_.reset(); }
// Returns the path of the requested file in the test data directory.
base::FilePath GetTestFilePath(const std::string& file_name) {
base::FilePath file_path;
PathService::Get(DIR_TEST_DATA, &file_path);
return file_path.AppendASCII(file_name);
}
base::File OpenFileForUpload(const base::FilePath& file_path) {
int open_flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
#if defined(OS_WIN)
open_flags |= base::File::FLAG_ASYNC;
#endif // defined(OS_WIN)
base::File file(file_path, open_flags);
EXPECT_TRUE(file.IsValid());
return file;
}
// Configure how Load() works.
void set_sniff() {
DCHECK(!ran_);
......@@ -293,6 +324,9 @@ class URLLoaderTest : public testing::Test {
DCHECK(!ran_);
resource_type_ = type;
}
void set_request_body(scoped_refptr<ResourceRequestBody> request_body) {
request_body_ = request_body;
}
// Convenience methods after calling Load();
std::string mime_type() const {
......@@ -378,10 +412,14 @@ class URLLoaderTest : public testing::Test {
base::test::ScopedTaskEnvironment scoped_task_environment_;
net::EmbeddedTestServer test_server_;
std::unique_ptr<NetworkContext> context_;
// Options applied the created request in Load().
bool sniff_ = false;
bool send_ssl_ = false;
bool add_custom_accept_header_ = false;
ResourceType resource_type_ = RESOURCE_TYPE_MAIN_FRAME;
scoped_refptr<ResourceRequestBody> request_body_;
// Used to ensure that methods are called either before or after a request is
// made, since the test fixture is meant to be used only once.
bool ran_ = false;
......@@ -907,4 +945,111 @@ TEST_F(URLLoaderTest, DoNotOverrideAcceptHeader) {
EXPECT_EQ(it->second, "custom/*");
}
TEST_F(URLLoaderTest, UploadBytes) {
const std::string kRequestBody = "Request Body";
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
request_body->AppendBytes(kRequestBody.c_str(), kRequestBody.length());
set_request_body(std::move(request_body));
std::string response_body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
EXPECT_EQ(kRequestBody, response_body);
}
TEST_F(URLLoaderTest, UploadFile) {
base::FilePath file_path = GetTestFilePath("simple_page.html");
std::string expected_body;
ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
<< "File not found: " << file_path.value();
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
request_body->AppendFileRange(
file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
set_request_body(std::move(request_body));
std::string response_body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
EXPECT_EQ(expected_body, response_body);
}
TEST_F(URLLoaderTest, UploadFileWithRange) {
base::FilePath file_path = GetTestFilePath("simple_page.html");
std::string expected_body;
ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
<< "File not found: " << file_path.value();
expected_body = expected_body.substr(1, expected_body.size() - 2);
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
request_body->AppendFileRange(file_path, 1, expected_body.size(),
base::Time());
set_request_body(std::move(request_body));
std::string response_body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
EXPECT_EQ(expected_body, response_body);
}
TEST_F(URLLoaderTest, UploadRawFile) {
base::FilePath file_path = GetTestFilePath("simple_page.html");
std::string expected_body;
ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
<< "File not found: " << file_path.value();
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
request_body->AppendRawFileRange(
OpenFileForUpload(file_path), GetTestFilePath("should_be_ignored"), 0,
std::numeric_limits<uint64_t>::max(), base::Time());
set_request_body(std::move(request_body));
std::string response_body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
EXPECT_EQ(expected_body, response_body);
}
TEST_F(URLLoaderTest, UploadRawFileWithRange) {
base::FilePath file_path = GetTestFilePath("simple_page.html");
std::string expected_body;
ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
<< "File not found: " << file_path.value();
expected_body = expected_body.substr(1, expected_body.size() - 2);
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
request_body->AppendRawFileRange(OpenFileForUpload(file_path),
GetTestFilePath("should_be_ignored"), 1,
expected_body.size(), base::Time());
set_request_body(std::move(request_body));
std::string response_body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
EXPECT_EQ(expected_body, response_body);
}
// TODO(mmenke): Test using a data pipe to upload data.
TEST_F(URLLoaderTest, UploadDoubleRawFile) {
base::FilePath file_path = GetTestFilePath("simple_page.html");
std::string expected_body;
ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
<< "File not found: " << file_path.value();
scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
request_body->AppendRawFileRange(
OpenFileForUpload(file_path), GetTestFilePath("should_be_ignored"), 0,
std::numeric_limits<uint64_t>::max(), base::Time());
request_body->AppendRawFileRange(
OpenFileForUpload(file_path), GetTestFilePath("should_be_ignored"), 0,
std::numeric_limits<uint64_t>::max(), base::Time());
set_request_body(std::move(request_body));
std::string response_body;
EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
EXPECT_EQ(expected_body + expected_body, response_body);
}
} // namespace content
......@@ -54,6 +54,17 @@ void ResourceRequestBody::AppendFileRange(
expected_modification_time);
}
void ResourceRequestBody::AppendRawFileRange(
base::File file,
const base::FilePath& file_path,
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time) {
elements_.push_back(Element());
elements_.back().SetToFileRange(std::move(file), file_path, offset, length,
expected_modification_time);
}
void ResourceRequestBody::AppendBlob(const std::string& uuid) {
elements_.push_back(Element());
elements_.back().SetToBlob(uuid);
......
......@@ -10,6 +10,8 @@
#include <string>
#include <vector>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
......@@ -54,6 +56,13 @@ class CONTENT_EXPORT ResourceRequestBody
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time);
// Appends the specified part of |file|. If |length| extends beyond the end of
// the file, it will be set to the end of the file.
void AppendRawFileRange(base::File file,
const base::FilePath& file_path,
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time);
void AppendBlob(const std::string& uuid);
void AppendFileSystemFileRange(const GURL& url,
......
......@@ -368,6 +368,7 @@ void BlobTransportController::GetDescriptions(
base::Time::FromDoubleT(item.expected_modification_time));
break;
}
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_DISK_CACHE_ENTRY:
case DataElement::TYPE_BYTES_DESCRIPTION:
case DataElement::TYPE_DATA_PIPE:
......
......@@ -10,6 +10,7 @@
#include <memory>
#include <utility>
#include "base/files/file.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "base/strings/string_number_conversions.h"
......@@ -83,6 +84,7 @@ void BlobDataBuilder::AppendIPCDataElement(const DataElement& ipc_data) {
// BlobStorageContext.
AppendBlob(ipc_data.blob_uuid(), ipc_data.offset(), ipc_data.length());
break;
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_BYTES_DESCRIPTION:
case DataElement::TYPE_UNKNOWN:
case DataElement::TYPE_DISK_CACHE_ENTRY: // This type can't be sent by IPC.
......
......@@ -662,6 +662,7 @@ std::unique_ptr<FileStreamReader> BlobReader::CreateFileStreamReader(
? storage::kMaximumLength
: item.length() - additional_offset,
item.expected_modification_time());
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_BLOB:
case DataElement::TYPE_BYTES:
case DataElement::TYPE_BYTES_DESCRIPTION:
......
......@@ -75,6 +75,7 @@ void RecordBlobItemSizeStats(const DataElement& input_element) {
UMA_HISTOGRAM_COUNTS_1M("Storage.BlobItemSize.CacheEntry",
(length - input_element.offset()) / 1024);
break;
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_DATA_PIPE:
case DataElement::TYPE_UNKNOWN:
NOTREACHED();
......@@ -369,6 +370,7 @@ BlobStorageContext::BlobSlice::BlobSlice(const BlobEntry& source,
source_item->disk_cache_side_stream_index());
break;
}
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_BLOB:
case DataElement::TYPE_DATA_PIPE:
case DataElement::TYPE_UNKNOWN:
......@@ -793,6 +795,7 @@ void BlobStorageContext::FinishBuilding(BlobEntry* entry) {
copy.dest_item->set_item(std::move(new_item));
break;
}
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_UNKNOWN:
case DataElement::TYPE_BLOB:
case DataElement::TYPE_BYTES_DESCRIPTION:
......
......@@ -282,6 +282,7 @@ void ViewBlobInternalsJob::GenerateHTMLForBlobData(
case DataElement::TYPE_DATA_PIPE:
AddHTMLListItem(kType, "data pipe", out);
break;
case DataElement::TYPE_RAW_FILE:
case DataElement::TYPE_UNKNOWN:
NOTREACHED();
break;
......
......@@ -36,6 +36,19 @@ void DataElement::SetToFilePathRange(
expected_modification_time_ = expected_modification_time;
}
void DataElement::SetToFileRange(base::File file,
const base::FilePath& path,
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time) {
type_ = TYPE_RAW_FILE;
file_ = std::move(file);
path_ = path;
offset_ = offset;
length_ = length;
expected_modification_time_ = expected_modification_time;
}
void DataElement::SetToBlobRange(const std::string& blob_uuid,
uint64_t offset,
uint64_t length) {
......@@ -70,6 +83,10 @@ void DataElement::SetToDataPipe(mojo::ScopedDataPipeConsumerHandle handle,
data_pipe_size_getter_ = std::move(size_getter);
}
base::File DataElement::ReleaseFile() {
return std::move(file_);
}
mojo::ScopedDataPipeConsumerHandle DataElement::ReleaseDataPipe(
blink::mojom::SizeGetterPtr* size_getter) {
if (size_getter)
......@@ -95,6 +112,10 @@ void PrintTo(const DataElement& x, std::ostream* os) {
*os << "TYPE_FILE, path: " << x.path().AsUTF8Unsafe()
<< ", expected_modification_time: " << x.expected_modification_time();
break;
case DataElement::TYPE_RAW_FILE:
*os << "TYPE_RAW_FILE, path: " << x.path().AsUTF8Unsafe()
<< ", expected_modification_time: " << x.expected_modification_time();
break;
case DataElement::TYPE_BLOB:
*os << "TYPE_BLOB, uuid: " << x.blob_uuid();
break;
......@@ -127,6 +148,9 @@ bool operator==(const DataElement& a, const DataElement& b) {
case DataElement::TYPE_FILE:
return a.path() == b.path() &&
a.expected_modification_time() == b.expected_modification_time();
case DataElement::TYPE_RAW_FILE:
return a.path() == b.path() &&
a.expected_modification_time() == b.expected_modification_time();
case DataElement::TYPE_BLOB:
return a.blob_uuid() == b.blob_uuid();
case DataElement::TYPE_FILE_FILESYSTEM:
......
......@@ -9,10 +9,12 @@
#include <stdint.h>
#include <limits>
#include <memory>
#include <ostream>
#include <string>
#include <vector>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
......@@ -32,14 +34,23 @@ class STORAGE_COMMON_EXPORT DataElement {
enum Type {
TYPE_UNKNOWN = -1,
TYPE_BYTES,
// Only used with BlobStorageMsg_StartBuildingBlob
// Only used for Upload with Network Service as of now:
TYPE_DATA_PIPE,
TYPE_RAW_FILE,
// Only used for Blob:
TYPE_BYTES_DESCRIPTION,
TYPE_FILE,
TYPE_BLOB, // Used in ResourceDispatcherHost path.
TYPE_DISK_CACHE_ENTRY, // Only used by CacheStorage
TYPE_FILE_FILESYSTEM,
TYPE_DISK_CACHE_ENTRY,
TYPE_DATA_PIPE, // Used in Network Service path.
// Commonly used for Blob, and also for Upload when Network Service is
// disabled:
TYPE_BLOB, // Used old IPC codepath only.
TYPE_FILE,
// Commonly used in every case:
TYPE_BYTES,
};
DataElement();
......@@ -53,6 +64,7 @@ class STORAGE_COMMON_EXPORT DataElement {
Type type() const { return type_; }
const char* bytes() const { return bytes_ ? bytes_ : buf_.data(); }
const base::FilePath& path() const { return path_; }
const base::File& file() const { return file_; }
const GURL& filesystem_url() const { return filesystem_url_; }
const std::string& blob_uuid() const { return blob_uuid_; }
const mojo::DataPipeConsumerHandle& data_pipe() const {
......@@ -137,6 +149,16 @@ class STORAGE_COMMON_EXPORT DataElement {
uint64_t length,
const base::Time& expected_modification_time);
// Sets TYPE_RAW_FILE data with range. |file| must be open for asynchronous
// reading on Windows. It's recommended it also be opened with
// File::FLAG_DELETE_ON_CLOSE, since there's often no way to wait on the
// consumer to close the file.
void SetToFileRange(base::File file,
const base::FilePath& path,
uint64_t offset,
uint64_t length,
const base::Time& expected_modification_time);
// Sets TYPE_BLOB data with range.
void SetToBlobRange(const std::string& blob_uuid,
uint64_t offset,
......@@ -155,6 +177,10 @@ class STORAGE_COMMON_EXPORT DataElement {
void SetToDataPipe(mojo::ScopedDataPipeConsumerHandle handle,
blink::mojom::SizeGetterPtr size_getter);
// Takes ownership of the File, if this is of TYPE_RAW_FILE. The file is open
// for reading (asynchronous reading on Windows).
base::File ReleaseFile();
mojo::ScopedDataPipeConsumerHandle ReleaseDataPipe(
blink::mojom::SizeGetterPtr* size_getter);
......@@ -165,7 +191,8 @@ class STORAGE_COMMON_EXPORT DataElement {
Type type_;
std::vector<char> buf_; // For TYPE_BYTES.
const char* bytes_; // For TYPE_BYTES.
base::FilePath path_; // For TYPE_FILE.
base::FilePath path_; // For TYPE_FILE and TYPE_RAW_FILE.
base::File file_; // For TYPE_RAW_FILE.
GURL filesystem_url_; // For TYPE_FILE_FILESYSTEM.
std::string blob_uuid_;
mojo::ScopedDataPipeConsumerHandle data_pipe_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment