Make sure Blob refcounts/lifetime work for cache and fetch APIs.
Pass a mojo BlobPtr in addition to the uuid in all the IPCs/mojo calls
for the cache and fetch APIs to make sure the blobs stay alive long
enough. Since the cache and fetch APIs largely pass around their parameters
in a copyable struct (mostly passed by const reference) this also required
introduction of a storage::BlobHandle type, a ref-counted wrapper around
a BlobPtr.
The BlobPtr passed along in IPCs/mojo messages isn't actually used for
anything other than lifetime management at this point. The browser side
code still uses the UUID to actually look up the blob and get its data.
Also add service worker and fetch tests to the mojo blobs virtual test
suite to make sure this all works correctly.
Bug: 740744
Change-Id: I6bfcda977cd605099bd6c04d9f079ce7783b43f4
Reviewed-on: https://chromium-review.googlesource.com/567549
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Takeshi Yoshino <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Reviewed-by: Daniel Murphy <[email protected]>
Commit-Queue: Marijn Kruisselbrink <[email protected]>
Cr-Commit-Position: refs/heads/master@{#491140}
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 4c0aba4f..30cfb1e4 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1925,6 +1925,7 @@
crbug.com/626703 external/wpt/secure-contexts/shared-worker-insecure-first.https.html [ Timeout ]
crbug.com/626703 external/wpt/secure-contexts/shared-worker-secure-first.https.html [ Timeout ]
crbug.com/626703 external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
+crbug.com/626703 virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
crbug.com/626703 external/wpt/streams/readable-streams/general.html [ Failure Timeout ]
crbug.com/626703 external/wpt/svg/linking/reftests/href-filter-element.html [ Failure ]
crbug.com/626703 external/wpt/wasm/wasm_indexeddb_test.html [ Timeout ]
@@ -2265,6 +2266,7 @@
crbug.com/658997 external/wpt/service-workers/service-worker/clients-matchall-client-types.https.html [ Skip ]
crbug.com/658997 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/clients-matchall-client-types.https.html [ Skip ]
crbug.com/658997 virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/clients-matchall-client-types.https.html [ Skip ]
+crbug.com/658997 virtual/mojo-blobs/external/wpt/service-workers/service-worker/clients-matchall-client-types.https.html [ Skip ]
crbug.com/435547 http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ]
crbug.com/435547 virtual/mojo-loading/http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ]
@@ -2414,19 +2416,23 @@
crbug.com/602693 external/wpt/service-workers/service-worker/fetch-frame-resource.https.html [ Timeout ]
crbug.com/602693 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-frame-resource.https.html [ Timeout ]
crbug.com/602693 virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-frame-resource.https.html [ Timeout ]
+crbug.com/602693 virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-frame-resource.https.html [ Timeout ]
# This test requires a special browser flag and seems not suitable for a wpt test, see bug.
crbug.com/691944 external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
crbug.com/691944 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
crbug.com/691944 virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
+crbug.com/691944 virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
# These tests (erroneously) see a platform-specific User-Agent header
crbug.com/595993 external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
crbug.com/595993 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
crbug.com/595993 virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
+crbug.com/595993 virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
crbug.com/595993 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
crbug.com/595993 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
crbug.com/595993 virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
+crbug.com/595993 virtual/mojo-blobs/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
crbug.com/619427 [ Mac Linux ] fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ]
@@ -2775,10 +2781,13 @@
# Importing 'fetch' tests from WPT.
crbug.com/705490 external/wpt/fetch/api/basic/error-after-response.html [ Timeout Pass ]
+crbug.com/705490 virtual/mojo-blobs/external/wpt/fetch/api/basic/error-after-response.html [ Timeout Pass ]
# Non-deterministic output, as the failing subtests dump timestamps.
crbug.com/705490 external/wpt/fetch/api/request/request-cache-reload.html [ Failure ]
crbug.com/705490 external/wpt/fetch/api/request/request-cache-no-store.html [ Failure ]
+crbug.com/705490 virtual/mojo-blobs/external/wpt/fetch/api/request/request-cache-reload.html [ Failure ]
+crbug.com/705490 virtual/mojo-blobs/external/wpt/fetch/api/request/request-cache-no-store.html [ Failure ]
# This test has device ID strings in failure messages which change on every test run.
crbug.com/679742 external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html [ Failure ]
@@ -2799,6 +2808,7 @@
crbug.com/688486 external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Failure Pass ]
crbug.com/688486 virtual/off-main-thread-fetch/external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Failure Pass ]
crbug.com/688486 virtual/service-worker-script-streaming/external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Failure Pass ]
+crbug.com/688486 virtual/mojo-blobs/external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Failure Pass ]
# Sheriff failures 2017-02-21
crbug.com/73609 http/tests/media/video-play-stall.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index 3fda57e..42799f6 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -565,6 +565,16 @@
},
{
"prefix": "mojo-blobs",
+ "base": "external/wpt/fetch",
+ "args": ["--enable-features=MojoBlobs"]
+ },
+ {
+ "prefix": "mojo-blobs",
+ "base": "external/wpt/service-workers",
+ "args": ["--enable-features=MojoBlobs"]
+ },
+ {
+ "prefix": "mojo-blobs",
"base": "fast/files",
"args": ["--enable-features=MojoBlobs"]
}
diff --git a/third_party/WebKit/LayoutTests/virtual/mojo-blobs/external/wpt/fetch/README.txt b/third_party/WebKit/LayoutTests/virtual/mojo-blobs/external/wpt/fetch/README.txt
new file mode 100644
index 0000000..a507250
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/mojo-blobs/external/wpt/fetch/README.txt
@@ -0,0 +1 @@
+This directory is for testing blobs with mojo.
diff --git a/third_party/WebKit/LayoutTests/virtual/mojo-blobs/external/wpt/service-workers/README.txt b/third_party/WebKit/LayoutTests/virtual/mojo-blobs/external/wpt/service-workers/README.txt
new file mode 100644
index 0000000..a507250
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/mojo-blobs/external/wpt/service-workers/README.txt
@@ -0,0 +1 @@
+This directory is for testing blobs with mojo.
diff --git a/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp b/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp
index d602c49f4..8de74fd 100644
--- a/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp
+++ b/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp
@@ -44,9 +44,14 @@
if (blob_handle) {
DCHECK_NE(UINT64_MAX, blob_handle->size());
if (blob_handle->GetType() != mime_type_) {
+ storage::mojom::blink::BlobPtr blob_clone = blob_handle->CloneBlobPtr();
// A new BlobDataHandle is created to override the Blob's type.
+ // TODO(mek): It might be cleaner to create a new blob (referencing the
+ // old blob) rather than just a new BlobDataHandle with mime type not
+ // matching the type of the underlying blob.
client_->DidFetchDataLoadedBlobHandle(BlobDataHandle::Create(
- blob_handle->Uuid(), mime_type_, blob_handle->size()));
+ blob_handle->Uuid(), mime_type_, blob_handle->size(),
+ blob_clone.PassInterface()));
} else {
client_->DidFetchDataLoadedBlobHandle(std::move(blob_handle));
}
diff --git a/third_party/WebKit/Source/platform/blob/BlobData.cpp b/third_party/WebKit/Source/platform/blob/BlobData.cpp
index 0848cd0d..3419935a 100644
--- a/third_party/WebKit/Source/platform/blob/BlobData.cpp
+++ b/third_party/WebKit/Source/platform/blob/BlobData.cpp
@@ -412,6 +412,19 @@
}
}
+BlobDataHandle::BlobDataHandle(const String& uuid,
+ const String& type,
+ long long size,
+ storage::mojom::blink::BlobPtrInfo blob_info)
+ : uuid_(uuid.IsolatedCopy()),
+ type_(IsValidBlobType(type) ? type.IsolatedCopy() : ""),
+ size_(size),
+ is_single_unknown_size_file_(false),
+ blob_info_(std::move(blob_info)) {
+ DCHECK(RuntimeEnabledFeatures::MojoBlobsEnabled());
+ DCHECK(blob_info_.is_valid());
+}
+
BlobDataHandle::~BlobDataHandle() {
if (!RuntimeEnabledFeatures::MojoBlobsEnabled())
BlobRegistry::RemoveBlobDataRef(uuid_);
@@ -419,6 +432,8 @@
BlobPtr BlobDataHandle::CloneBlobPtr() {
MutexLocker locker(blob_info_mutex_);
+ if (!blob_info_.is_valid())
+ return nullptr;
BlobPtr blob, blob_clone;
blob.Bind(std::move(blob_info_));
blob->Clone(MakeRequest(&blob_clone));
diff --git a/third_party/WebKit/Source/platform/blob/BlobData.h b/third_party/WebKit/Source/platform/blob/BlobData.h
index b9bb7a8..070287c2 100644
--- a/third_party/WebKit/Source/platform/blob/BlobData.h
+++ b/third_party/WebKit/Source/platform/blob/BlobData.h
@@ -241,6 +241,18 @@
return AdoptRef(new BlobDataHandle(uuid, type, size));
}
+ static PassRefPtr<BlobDataHandle> Create(
+ const String& uuid,
+ const String& type,
+ long long size,
+ storage::mojom::blink::BlobPtrInfo blob_info) {
+ if (blob_info.is_valid()) {
+ return AdoptRef(
+ new BlobDataHandle(uuid, type, size, std::move(blob_info)));
+ }
+ return AdoptRef(new BlobDataHandle(uuid, type, size));
+ }
+
String Uuid() const { return uuid_.IsolatedCopy(); }
String GetType() const { return type_.IsolatedCopy(); }
unsigned long long size() const { return size_; }
@@ -249,12 +261,16 @@
~BlobDataHandle();
+ storage::mojom::blink::BlobPtr CloneBlobPtr();
+
private:
BlobDataHandle();
BlobDataHandle(std::unique_ptr<BlobData>, long long size);
BlobDataHandle(const String& uuid, const String& type, long long size);
-
- storage::mojom::blink::BlobPtr CloneBlobPtr();
+ BlobDataHandle(const String& uuid,
+ const String& type,
+ long long size,
+ storage::mojom::blink::BlobPtrInfo);
const String uuid_;
const String type_;
diff --git a/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp b/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp
index c4469a2..0897ffb7 100644
--- a/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebServiceWorkerRequest.cpp
@@ -103,8 +103,20 @@
return private_->headers_;
}
-void WebServiceWorkerRequest::SetBlob(const WebString& uuid, long long size) {
- private_->blob_data_handle = BlobDataHandle::Create(uuid, String(), size);
+void WebServiceWorkerRequest::SetBlob(const WebString& uuid,
+ long long size,
+ mojo::ScopedMessagePipeHandle blob_pipe) {
+ SetBlob(uuid, size,
+ storage::mojom::blink::BlobPtrInfo(
+ std::move(blob_pipe), storage::mojom::blink::Blob::Version_));
+}
+
+void WebServiceWorkerRequest::SetBlob(
+ const WebString& uuid,
+ long long size,
+ storage::mojom::blink::BlobPtrInfo blob_info) {
+ private_->blob_data_handle =
+ BlobDataHandle::Create(uuid, String(), size, std::move(blob_info));
}
PassRefPtr<BlobDataHandle> WebServiceWorkerRequest::GetBlobDataHandle() const {
diff --git a/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp b/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
index 87b555fb..57b3e70 100644
--- a/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebServiceWorkerResponse.cpp
@@ -111,8 +111,14 @@
header_visitor->VisitHeader(i->key, i->value);
}
-void WebServiceWorkerResponse::SetBlob(const WebString& uuid, uint64_t size) {
- private_->blob_data_handle = BlobDataHandle::Create(uuid, String(), size);
+void WebServiceWorkerResponse::SetBlob(
+ const WebString& uuid,
+ uint64_t size,
+ mojo::ScopedMessagePipeHandle blob_pipe) {
+ private_->blob_data_handle = BlobDataHandle::Create(
+ uuid, String(), size,
+ storage::mojom::blink::BlobPtrInfo(
+ std::move(blob_pipe), storage::mojom::blink::Blob::Version_));
}
WebString WebServiceWorkerResponse::BlobUUID() const {
@@ -127,6 +133,14 @@
return private_->blob_data_handle->size();
}
+mojo::ScopedMessagePipeHandle WebServiceWorkerResponse::CloneBlobPtr() const {
+ if (!private_->blob_data_handle)
+ return mojo::ScopedMessagePipeHandle();
+ return private_->blob_data_handle->CloneBlobPtr()
+ .PassInterface()
+ .PassHandle();
+}
+
void WebServiceWorkerResponse::SetError(WebServiceWorkerResponseError error) {
private_->error = error;
}
diff --git a/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.cpp b/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.cpp
index 4fee6c7d..aa67d0c 100644
--- a/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.cpp
+++ b/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.cpp
@@ -450,6 +450,20 @@
}
// static
+storage::mojom::blink::BlobPtr StructTraits<
+ blink::mojom::FetchAPIRequestDataView,
+ blink::WebServiceWorkerRequest>::blob(const blink::WebServiceWorkerRequest&
+ request) {
+ if (request.GetBlobDataHandle()) {
+ storage::mojom::blink::BlobPtr result =
+ request.GetBlobDataHandle()->CloneBlobPtr();
+ return result;
+ }
+
+ return nullptr;
+}
+
+// static
WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView,
blink::WebServiceWorkerRequest>::
integrity(const blink::WebServiceWorkerRequest& request) {
@@ -475,6 +489,7 @@
WTF::String method;
WTF::HashMap<WTF::String, WTF::String> headers;
WTF::String blobUuid;
+ storage::mojom::blink::BlobPtr blob;
blink::Referrer referrer;
blink::WebURLRequest::FetchCredentialsMode credentialsMode;
blink::WebURLRequest::FetchRedirectMode redirectMode;
@@ -499,7 +514,8 @@
out->SetMethod(method);
for (const auto& pair : headers)
out->SetHeader(pair.key, pair.value);
- out->SetBlob(blobUuid, static_cast<long long>(data.blob_size()));
+ out->SetBlob(blobUuid, static_cast<long long>(data.blob_size()),
+ data.TakeBlob<storage::mojom::blink::BlobPtr>().PassInterface());
out->SetReferrer(referrer.referrer, static_cast<blink::WebReferrerPolicy>(
referrer.referrer_policy));
out->SetCredentialsMode(credentialsMode);
diff --git a/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.h b/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.h
index 1a683a9..a28b1e5c 100644
--- a/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.h
+++ b/third_party/WebKit/Source/platform/mojo/FetchAPIRequestStructTraits.h
@@ -104,6 +104,9 @@
static uint64_t blob_size(const blink::WebServiceWorkerRequest&);
+ static storage::mojom::blink::BlobPtr blob(
+ const blink::WebServiceWorkerRequest&);
+
static const blink::Referrer& referrer(const blink::WebServiceWorkerRequest&);
static blink::WebURLRequest::FetchCredentialsMode credentials_mode(
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index 6f00a75..273c677 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -754,6 +754,7 @@
"//device/bluetooth/public/interfaces",
"//device/screen_orientation/public/interfaces",
"//mojo/common:common_custom_types",
+ "//storage/public/interfaces",
"//ui/gfx/geometry/mojo",
"//url/mojo:url_mojom_gurl",
"//url/mojo:url_mojom_origin",
diff --git a/third_party/WebKit/public/platform/DEPS b/third_party/WebKit/public/platform/DEPS
index 8ae4b91..33ab0a6 100644
--- a/third_party/WebKit/public/platform/DEPS
+++ b/third_party/WebKit/public/platform/DEPS
@@ -25,6 +25,7 @@
"+public/platform",
"-public/web",
"+services/service_manager/public/interfaces",
+ "+storage/public/interfaces",
"+third_party/skia",
"+ui/gfx",
"+url",
diff --git a/third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom b/third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom
index 8101cf0..aa65290 100644
--- a/third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom
+++ b/third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom
@@ -5,6 +5,7 @@
module blink.mojom;
import "third_party/WebKit/public/platform/referrer.mojom";
+import "storage/public/interfaces/blobs.mojom";
import "url/mojo/url.mojom";
// The mode associated with a request.
@@ -111,6 +112,7 @@
map<string, string> headers;
string? blob_uuid;
uint64 blob_size;
+ storage.mojom.Blob? blob;
Referrer referrer;
FetchCredentialsMode credentials_mode;
FetchRedirectMode redirect_mode;
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h
index d862d3a..638f260 100644
--- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h
+++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRequest.h
@@ -5,6 +5,7 @@
#ifndef WebServiceWorkerRequest_h
#define WebServiceWorkerRequest_h
+#include "mojo/public/cpp/system/message_pipe.h"
#include "public/platform/WebCommon.h"
#include "public/platform/WebPrivatePtr.h"
#include "public/platform/WebReferrerPolicy.h"
@@ -18,6 +19,7 @@
#include "platform/weborigin/Referrer.h"
#include "platform/wtf/Forward.h"
#include "platform/wtf/text/StringHash.h"
+#include "storage/public/interfaces/blobs.mojom-blink.h" // nogncheck
#endif
namespace blink {
@@ -56,7 +58,9 @@
void VisitHTTPHeaderFields(WebHTTPHeaderVisitor*) const;
- void SetBlob(const WebString& uuid, long long size);
+ void SetBlob(const WebString& uuid,
+ long long size,
+ mojo::ScopedMessagePipeHandle);
void SetReferrer(const WebString&, WebReferrerPolicy);
WebURL ReferrerUrl() const;
@@ -96,6 +100,9 @@
const HTTPHeaderMap& Headers() const;
PassRefPtr<BlobDataHandle> GetBlobDataHandle() const;
const Referrer& GetReferrer() const;
+ void SetBlob(const WebString& uuid,
+ long long size,
+ storage::mojom::blink::BlobPtrInfo);
#endif
private:
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
index 33f5b31..298ae356 100644
--- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
+++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerResponse.h
@@ -6,6 +6,7 @@
#define WebServiceWorkerResponse_h
#include "base/time/time.h"
+#include "mojo/public/cpp/system/message_pipe.h"
#include "public/platform/WebCommon.h"
#include "public/platform/WebPrivatePtr.h"
#include "public/platform/WebString.h"
@@ -67,10 +68,14 @@
WebString GetHeader(const WebString& key) const;
void VisitHTTPHeaderFields(WebHTTPHeaderVisitor*) const;
- void SetBlob(const WebString& uuid, uint64_t size);
+ void SetBlob(const WebString& uuid,
+ uint64_t size,
+ mojo::ScopedMessagePipeHandle);
WebString BlobUUID() const;
uint64_t BlobSize() const;
+ mojo::ScopedMessagePipeHandle CloneBlobPtr() const;
+
// Provides a more detailed error when status() is zero.
void SetError(WebServiceWorkerResponseError);
WebServiceWorkerResponseError GetError() const;