Commit 9e073a82 authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

[Blobs] Refactor extensions BlobReader to no longer use blob URLs.

Instead just read the blob through the mojom Blob interface directly.
For now still relying on blob UUIDs, but ultimately code calling into
this should already have a BlobPtr rather than having to ever look it
up from a UUID.

Bug: 701851
Change-Id: If267c750368cc4a43d52d239b8462cc65d7214bb
Reviewed-on: https://chromium-review.googlesource.com/1101899Reviewed-by: default avatarKen Rockot <rockot@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568063}
parent b445a420
...@@ -197,6 +197,26 @@ ChromeBlobStorageContext::URLLoaderFactoryForToken( ...@@ -197,6 +197,26 @@ ChromeBlobStorageContext::URLLoaderFactoryForToken(
std::move(blob_url_loader_factory_ptr)); std::move(blob_url_loader_factory_ptr));
} }
// static
blink::mojom::BlobPtr ChromeBlobStorageContext::GetBlobPtr(
BrowserContext* browser_context,
const std::string& uuid) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
blink::mojom::BlobPtr blob_ptr;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
[](scoped_refptr<ChromeBlobStorageContext> context,
blink::mojom::BlobRequest request, const std::string& uuid) {
auto handle = context->context()->GetBlobDataFromUUID(uuid);
if (handle)
storage::BlobImpl::Create(std::move(handle), std::move(request));
},
base::WrapRefCounted(GetFor(browser_context)), MakeRequest(&blob_ptr),
uuid));
return blob_ptr;
}
ChromeBlobStorageContext::~ChromeBlobStorageContext() {} ChromeBlobStorageContext::~ChromeBlobStorageContext() {}
void ChromeBlobStorageContext::DeleteOnCorrectThread() const { void ChromeBlobStorageContext::DeleteOnCorrectThread() const {
......
...@@ -70,6 +70,10 @@ class CONTENT_EXPORT ChromeBlobStorageContext ...@@ -70,6 +70,10 @@ class CONTENT_EXPORT ChromeBlobStorageContext
URLLoaderFactoryForToken(BrowserContext* browser_context, URLLoaderFactoryForToken(BrowserContext* browser_context,
blink::mojom::BlobURLTokenPtr token); blink::mojom::BlobURLTokenPtr token);
// Must be called on the UI thread.
static blink::mojom::BlobPtr GetBlobPtr(BrowserContext* browser_context,
const std::string& uuid);
protected: protected:
virtual ~ChromeBlobStorageContext(); virtual ~ChromeBlobStorageContext();
......
...@@ -348,6 +348,14 @@ BrowserContext::BlobContextGetter BrowserContext::GetBlobStorageContext( ...@@ -348,6 +348,14 @@ BrowserContext::BlobContextGetter BrowserContext::GetBlobStorageContext(
chrome_blob_context); chrome_blob_context);
} }
// static
blink::mojom::BlobPtr BrowserContext::GetBlobPtr(
BrowserContext* browser_context,
const std::string& uuid) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return ChromeBlobStorageContext::GetBlobPtr(browser_context, uuid);
}
// static // static
void BrowserContext::DeliverPushMessage( void BrowserContext::DeliverPushMessage(
BrowserContext* browser_context, BrowserContext* browser_context,
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "net/url_request/url_request_interceptor.h" #include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_job_factory.h"
#include "services/service_manager/embedder/embedded_service_info.h" #include "services/service_manager/embedder/embedded_service_info.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
#include "content/public/browser/zoom_level_delegate.h" #include "content/public/browser/zoom_level_delegate.h"
...@@ -147,6 +148,14 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData { ...@@ -147,6 +148,14 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
static BlobContextGetter GetBlobStorageContext( static BlobContextGetter GetBlobStorageContext(
BrowserContext* browser_context); BrowserContext* browser_context);
// Returns a mojom::BlobPtr for a specific blob. If no blob exists with the
// given UUID, the BlobPtr pipe will close.
// This method should be called on the UI thread.
// TODO(mek): Blob UUIDs should be entirely internal to the blob system, so
// eliminate this method in favor of just passing around the BlobPtr directly.
static blink::mojom::BlobPtr GetBlobPtr(BrowserContext* browser_context,
const std::string& uuid);
// Delivers a push message with |data| to the Service Worker identified by // Delivers a push message with |data| to the Service Worker identified by
// |origin| and |service_worker_registration_id|. // |origin| and |service_worker_registration_id|.
static void DeliverPushMessage( static void DeliverPushMessage(
......
...@@ -32,6 +32,7 @@ include_rules = [ ...@@ -32,6 +32,7 @@ include_rules = [
"+skia/ext/image_operations.h", "+skia/ext/image_operations.h",
"+third_party/leveldatabase", "+third_party/leveldatabase",
"+third_party/re2", "+third_party/re2",
"+third_party/blink/public/mojom",
"+third_party/blink/public/platform", "+third_party/blink/public/platform",
"+third_party/blink/public/web", "+third_party/blink/public/web",
"+third_party/zlib/google", "+third_party/zlib/google",
......
...@@ -7,57 +7,21 @@ ...@@ -7,57 +7,21 @@
#include <limits> #include <limits>
#include <utility> #include <utility>
#include "base/format_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
BlobReader::BlobReader(content::BrowserContext* browser_context, BlobReader::BlobReader(content::BrowserContext* browser_context,
const std::string& blob_uuid, const std::string& blob_uuid,
BlobReadCallback callback) BlobReadCallback callback)
: callback_(callback) { : BlobReader(
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); content::BrowserContext::GetBlobPtr(browser_context, blob_uuid),
GURL blob_url = GURL(std::string("blob:uuid/") + blob_uuid); std::move(callback)) {}
DCHECK(blob_url.is_valid());
net::NetworkTrafficAnnotationTag traffic_annotation = BlobReader::BlobReader(blink::mojom::BlobPtr blob, BlobReadCallback callback)
net::DefineNetworkTrafficAnnotation("blob_reader", R"( : callback_(std::move(callback)), blob_(std::move(blob)), binding_(this) {
semantics { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
sender: "BlobReader" blob_.set_connection_error_handler(
description: base::BindOnce(&BlobReader::Failed, base::Unretained(this)));
"Blobs are used for a variety of use cases, and are basically "
"immutable blocks of data. See https://chromium.googlesource.com/"
"chromium/src/+/master/storage/browser/blob/README.md for an "
"explanation of blobs and their implementation in Chrome. These "
"can be created by scripts in a website, web platform features, or "
"internally in the browser."
trigger:
"Request for reading the contents of a blob."
data:
"A reference to a Blob, File, or CacheStorage entry created from "
"script, a web platform feature, or browser internals."
destination: LOCAL
}
policy {
cookies_allowed: NO
setting: "This feature cannot be disabled by settings."
policy_exception_justification:
"Not implemented. This is a local data fetch request and has no "
"network activity."
})");
fetcher_ = net::URLFetcher::Create(blob_url, net::URLFetcher::GET, this,
traffic_annotation);
fetcher_->SetRequestContext(
content::BrowserContext::GetDefaultStoragePartition(browser_context)
->GetURLRequestContext());
} }
BlobReader::~BlobReader() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); } BlobReader::~BlobReader() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); }
...@@ -68,28 +32,56 @@ void BlobReader::SetByteRange(int64_t offset, int64_t length) { ...@@ -68,28 +32,56 @@ void BlobReader::SetByteRange(int64_t offset, int64_t length) {
CHECK_GT(length, 0); CHECK_GT(length, 0);
CHECK_LE(offset, std::numeric_limits<int64_t>::max() - length); CHECK_LE(offset, std::numeric_limits<int64_t>::max() - length);
net::HttpRequestHeaders headers; read_range_ = Range{offset, length};
headers.SetHeader(
net::HttpRequestHeaders::kRange,
base::StringPrintf("bytes=%" PRId64 "-%" PRId64, offset,
offset + length - 1));
fetcher_->SetExtraRequestHeaders(headers.ToString());
} }
void BlobReader::Start() { void BlobReader::Start() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
fetcher_->Start(); mojo::ScopedDataPipeProducerHandle producer_handle;
mojo::ScopedDataPipeConsumerHandle consumer_handle;
MojoResult result =
CreateDataPipe(nullptr, &producer_handle, &consumer_handle);
if (result != MOJO_RESULT_OK) {
Failed();
return;
}
blink::mojom::BlobReaderClientPtr client_ptr;
binding_.Bind(MakeRequest(&client_ptr));
if (read_range_) {
blob_->ReadRange(read_range_->offset, read_range_->length,
std::move(producer_handle), std::move(client_ptr));
} else {
blob_->ReadAll(std::move(producer_handle), std::move(client_ptr));
}
data_pipe_drainer_ =
std::make_unique<mojo::DataPipeDrainer>(this, std::move(consumer_handle));
} }
// Overridden from net::URLFetcherDelegate. void BlobReader::OnCalculatedSize(uint64_t total_size,
void BlobReader::OnURLFetchComplete(const net::URLFetcher* source) { uint64_t expected_content_size) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); blob_length_ = total_size;
std::unique_ptr<std::string> response(new std::string); if (data_complete_)
int64_t first = 0, last = 0, length = 0; Succeeded();
source->GetResponseAsString(response.get()); }
if (source->GetResponseHeaders())
source->GetResponseHeaders()->GetContentRangeFor206(&first, &last, &length); void BlobReader::OnDataAvailable(const void* data, size_t num_bytes) {
callback_.Run(std::move(response), length); if (!blob_data_)
blob_data_ = std::make_unique<std::string>();
blob_data_->append(static_cast<const char*>(data), num_bytes);
}
void BlobReader::OnDataComplete() {
data_complete_ = true;
if (blob_length_)
Succeeded();
}
void BlobReader::Failed() {
std::move(callback_).Run(std::make_unique<std::string>(), 0);
delete this;
}
void BlobReader::Succeeded() {
std::move(callback_).Run(std::move(blob_data_), *blob_length_);
delete this; delete this;
} }
...@@ -12,32 +12,31 @@ ...@@ -12,32 +12,31 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "net/base/io_buffer.h" #include "mojo/public/cpp/bindings/binding.h"
#include "net/url_request/url_fetcher_delegate.h" #include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "net/url_request/url_request.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace content { namespace content {
class BrowserContext; class BrowserContext;
} }
namespace net { // This class may only be used from the UI thread. It self-deletes when finished
class URLFetcher; // reading.
} class BlobReader : public blink::mojom::BlobReaderClient,
public mojo::DataPipeDrainer::Client {
// This class may only be used from the UI thread.
class BlobReader : public net::URLFetcherDelegate {
public: public:
// |blob_data| contains the portion of the Blob requested. |blob_total_size| // |blob_data| contains the portion of the Blob requested. |blob_total_size|
// is the total size of the Blob, and may be larger than |blob_data->size()|. // is the total size of the Blob, and may be larger than |blob_data->size()|.
// |blob_total_size| is -1 if it cannot be determined. // |blob_total_size| is -1 if it cannot be determined.
typedef base::Callback<void(std::unique_ptr<std::string> blob_data, typedef base::OnceCallback<void(std::unique_ptr<std::string> blob_data,
int64_t blob_total_size)> int64_t blob_total_size)>
BlobReadCallback; BlobReadCallback;
BlobReader(content::BrowserContext* browser_context, BlobReader(content::BrowserContext* browser_context,
const std::string& blob_uuid, const std::string& blob_uuid,
BlobReadCallback callback); BlobReadCallback callback);
BlobReader(blink::mojom::BlobPtr blob, BlobReadCallback callback);
~BlobReader() override; ~BlobReader() override;
void SetByteRange(int64_t offset, int64_t length); void SetByteRange(int64_t offset, int64_t length);
...@@ -45,11 +44,32 @@ class BlobReader : public net::URLFetcherDelegate { ...@@ -45,11 +44,32 @@ class BlobReader : public net::URLFetcherDelegate {
void Start(); void Start();
private: private:
// Overridden from net::URLFetcherDelegate. // blink::mojom::BlobReaderClient:
void OnURLFetchComplete(const net::URLFetcher* source) override; void OnCalculatedSize(uint64_t total_size,
uint64_t expected_content_size) override;
void OnComplete(int32_t status, uint64_t data_length) override {}
// mojo::DataPipeDrainer:
void OnDataAvailable(const void* data, size_t num_bytes) override;
void OnDataComplete() override;
void Failed();
void Succeeded();
BlobReadCallback callback_; BlobReadCallback callback_;
std::unique_ptr<net::URLFetcher> fetcher_; blink::mojom::BlobPtr blob_;
struct Range {
uint64_t offset;
uint64_t length;
};
base::Optional<Range> read_range_;
mojo::Binding<blink::mojom::BlobReaderClient> binding_;
std::unique_ptr<mojo::DataPipeDrainer> data_pipe_drainer_;
base::Optional<uint64_t> blob_length_;
std::unique_ptr<std::string> blob_data_;
bool data_complete_ = false;
DISALLOW_COPY_AND_ASSIGN(BlobReader); DISALLOW_COPY_AND_ASSIGN(BlobReader);
}; };
......
...@@ -28,7 +28,7 @@ Refer to README.md for content description and update process. ...@@ -28,7 +28,7 @@ Refer to README.md for content description and update process.
<item id="blink_extension_resource_loader" hash_code="84165821" type="0" content_hash_code="3695143" os_list="linux,windows" file_path="content/renderer/loader/web_url_loader_impl.cc"/> <item id="blink_extension_resource_loader" hash_code="84165821" type="0" content_hash_code="3695143" os_list="linux,windows" file_path="content/renderer/loader/web_url_loader_impl.cc"/>
<item id="blink_resource_loader" hash_code="101845102" type="0" content_hash_code="75331172" os_list="linux,windows" file_path="content/renderer/loader/web_url_loader_impl.cc"/> <item id="blink_resource_loader" hash_code="101845102" type="0" content_hash_code="75331172" os_list="linux,windows" file_path="content/renderer/loader/web_url_loader_impl.cc"/>
<item id="blob_read" hash_code="112303907" type="0" content_hash_code="135449692" os_list="linux,windows" file_path="storage/browser/blob/blob_url_request_job_factory.cc"/> <item id="blob_read" hash_code="112303907" type="0" content_hash_code="135449692" os_list="linux,windows" file_path="storage/browser/blob/blob_url_request_job_factory.cc"/>
<item id="blob_reader" hash_code="5154306" type="0" content_hash_code="39702178" os_list="linux,windows" file_path="extensions/browser/blob_reader.cc"/> <item id="blob_reader" hash_code="5154306" type="0" deprecated="2018-06-14" content_hash_code="39702178" file_path="extensions/browser/blob_reader.cc"/>
<item id="bluetooth_socket" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows" file_path="device/bluetooth/bluetooth_socket_net.cc"/> <item id="bluetooth_socket" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows" file_path="device/bluetooth/bluetooth_socket_net.cc"/>
<item id="brandcode_config" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/> <item id="brandcode_config" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/>
<item id="captive_portal_service" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows" file_path="chrome/browser/captive_portal/captive_portal_service.cc"/> <item id="captive_portal_service" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows" file_path="chrome/browser/captive_portal/captive_portal_service.cc"/>
......
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