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(
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() {}
void ChromeBlobStorageContext::DeleteOnCorrectThread() const {
......
......@@ -70,6 +70,10 @@ class CONTENT_EXPORT ChromeBlobStorageContext
URLLoaderFactoryForToken(BrowserContext* browser_context,
blink::mojom::BlobURLTokenPtr token);
// Must be called on the UI thread.
static blink::mojom::BlobPtr GetBlobPtr(BrowserContext* browser_context,
const std::string& uuid);
protected:
virtual ~ChromeBlobStorageContext();
......
......@@ -348,6 +348,14 @@ BrowserContext::BlobContextGetter BrowserContext::GetBlobStorageContext(
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
void BrowserContext::DeliverPushMessage(
BrowserContext* browser_context,
......
......@@ -20,6 +20,7 @@
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
#include "services/service_manager/embedder/embedded_service_info.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#if !defined(OS_ANDROID)
#include "content/public/browser/zoom_level_delegate.h"
......@@ -147,6 +148,14 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
static BlobContextGetter GetBlobStorageContext(
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
// |origin| and |service_worker_registration_id|.
static void DeliverPushMessage(
......
......@@ -32,6 +32,7 @@ include_rules = [
"+skia/ext/image_operations.h",
"+third_party/leveldatabase",
"+third_party/re2",
"+third_party/blink/public/mojom",
"+third_party/blink/public/platform",
"+third_party/blink/public/web",
"+third_party/zlib/google",
......
......@@ -7,57 +7,21 @@
#include <limits>
#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_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,
const std::string& blob_uuid,
BlobReadCallback callback)
: callback_(callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
GURL blob_url = GURL(std::string("blob:uuid/") + blob_uuid);
DCHECK(blob_url.is_valid());
: BlobReader(
content::BrowserContext::GetBlobPtr(browser_context, blob_uuid),
std::move(callback)) {}
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("blob_reader", R"(
semantics {
sender: "BlobReader"
description:
"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(blink::mojom::BlobPtr blob, BlobReadCallback callback)
: callback_(std::move(callback)), blob_(std::move(blob)), binding_(this) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
blob_.set_connection_error_handler(
base::BindOnce(&BlobReader::Failed, base::Unretained(this)));
}
BlobReader::~BlobReader() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); }
......@@ -68,28 +32,56 @@ void BlobReader::SetByteRange(int64_t offset, int64_t length) {
CHECK_GT(length, 0);
CHECK_LE(offset, std::numeric_limits<int64_t>::max() - length);
net::HttpRequestHeaders headers;
headers.SetHeader(
net::HttpRequestHeaders::kRange,
base::StringPrintf("bytes=%" PRId64 "-%" PRId64, offset,
offset + length - 1));
fetcher_->SetExtraRequestHeaders(headers.ToString());
read_range_ = Range{offset, length};
}
void BlobReader::Start() {
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::OnURLFetchComplete(const net::URLFetcher* source) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
std::unique_ptr<std::string> response(new std::string);
int64_t first = 0, last = 0, length = 0;
source->GetResponseAsString(response.get());
if (source->GetResponseHeaders())
source->GetResponseHeaders()->GetContentRangeFor206(&first, &last, &length);
callback_.Run(std::move(response), length);
void BlobReader::OnCalculatedSize(uint64_t total_size,
uint64_t expected_content_size) {
blob_length_ = total_size;
if (data_complete_)
Succeeded();
}
void BlobReader::OnDataAvailable(const void* data, size_t num_bytes) {
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;
}
......@@ -12,32 +12,31 @@
#include "base/callback.h"
#include "base/macros.h"
#include "net/base/io_buffer.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "url/gurl.h"
namespace content {
class BrowserContext;
}
namespace net {
class URLFetcher;
}
// This class may only be used from the UI thread.
class BlobReader : public net::URLFetcherDelegate {
// This class may only be used from the UI thread. It self-deletes when finished
// reading.
class BlobReader : public blink::mojom::BlobReaderClient,
public mojo::DataPipeDrainer::Client {
public:
// |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()|.
// |blob_total_size| is -1 if it cannot be determined.
typedef base::Callback<void(std::unique_ptr<std::string> blob_data,
int64_t blob_total_size)>
typedef base::OnceCallback<void(std::unique_ptr<std::string> blob_data,
int64_t blob_total_size)>
BlobReadCallback;
BlobReader(content::BrowserContext* browser_context,
const std::string& blob_uuid,
BlobReadCallback callback);
BlobReader(blink::mojom::BlobPtr blob, BlobReadCallback callback);
~BlobReader() override;
void SetByteRange(int64_t offset, int64_t length);
......@@ -45,11 +44,32 @@ class BlobReader : public net::URLFetcherDelegate {
void Start();
private:
// Overridden from net::URLFetcherDelegate.
void OnURLFetchComplete(const net::URLFetcher* source) override;
// blink::mojom::BlobReaderClient:
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_;
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);
};
......
......@@ -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_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_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="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"/>
......
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