Commit 71566833 authored by Kenichi Ishibashi's avatar Kenichi Ishibashi Committed by Commit Bot

Introduce ServiceWorkerResourceReader mojo interface

This CL adds ServiceWorkerResourceReader which will be used by
browser/embedders to read a service worker script from storage after
ServiceWorkerStorage is migrated to the storage service. It is created
via ServiceWorkerStorageControl::CreateResourceReader().

This CL only adds ReadResponseHead() method. Subsequent CLs will add
methods to read the content of service worker script and metadata
(V8 code cache).

Following naming convention in content/browser/appcache/,
service_worker_resource_writer_impl.{cc,h} are renamed to
service_worker_resource_ops.{cc,h}

Bug: 1055677
Change-Id: I7ae13a667ad733a1d8c3657f932f420d4f1be3fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2132559Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMakoto Shimazu <shimazu@chromium.org>
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756576}
parent b84f57a4
......@@ -30,6 +30,15 @@ enum ServiceWorkerStorageOriginState {
kDelete,
};
// An interface that reads a service worker script (resource) to storage.
interface ServiceWorkerResourceReader {
// Reads the response head of the resource associated with this reader.
ReadResponseHead() =>
(int32 status, network.mojom.URLResponseHead response_head);
// TODO(crbug.com/1055677): Add ways to read the content and the metadata of
// the script.
};
// An interface that writes a service worker script (resource) to storage.
interface ServiceWorkerResourceWriter {
// Writes the response head to storage.
......@@ -74,6 +83,9 @@ interface ServiceWorkerStorageControl {
// is disabled.
GetNewResourceId() => (int64 resource_id);
// Creates a resource reader for the given |resource_id|.
CreateResourceReader(int64 resource_id,
pending_receiver<ServiceWorkerResourceReader> reader);
// Creates a resource writer for the given |resource_id|.
CreateResourceWriter(int64 resource_id,
pending_receiver<ServiceWorkerResourceWriter> writer);
......
......@@ -1732,8 +1732,8 @@ jumbo_source_set("browser") {
"service_worker/service_worker_registry.h",
"service_worker/service_worker_request_handler.cc",
"service_worker/service_worker_request_handler.h",
"service_worker/service_worker_resource_writer_impl.cc",
"service_worker/service_worker_resource_writer_impl.h",
"service_worker/service_worker_resource_ops.cc",
"service_worker/service_worker_resource_ops.h",
"service_worker/service_worker_script_cache_map.cc",
"service_worker/service_worker_script_cache_map.h",
"service_worker/service_worker_script_loader_factory.cc",
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/service_worker/service_worker_resource_writer_impl.h"
#include "content/browser/service_worker/service_worker_resource_ops.h"
#include "content/browser/service_worker/service_worker_loader_helpers.h"
......@@ -37,8 +37,60 @@ BigIOBuffer::~BigIOBuffer() {
size_ = 0UL;
}
void DidReadInfo(
scoped_refptr<HttpResponseInfoIOBuffer> buffer,
ServiceWorkerResourceReaderImpl::ReadResponseHeadCallback callback,
int status) {
DCHECK(buffer);
const net::HttpResponseInfo* http_info = buffer->http_info.get();
if (!http_info) {
DCHECK_LT(status, 0);
std::move(callback).Run(status, /*response_head=*/nullptr);
return;
}
// URLResponseHead fields filled here are the same as
// ServiceWorkerUtils::CreateResourceResponseHeadAndMetadata(). Once
// https://crbug.com/1060076 is done CreateResourceResponseHeadAndMetadata()
// will be removed, but we still need HttpResponseInfo -> URLResponseHead
// conversion to restore a response from the storage.
// TODO(bashi): Remove the above comment ater the issue is closed.
auto head = network::mojom::URLResponseHead::New();
head->request_time = http_info->request_time;
head->response_time = http_info->response_time;
head->headers = http_info->headers;
head->headers->GetMimeType(&head->mime_type);
head->headers->GetCharset(&head->charset);
head->content_length = buffer->response_data_size;
head->was_fetched_via_spdy = http_info->was_fetched_via_spdy;
head->was_alpn_negotiated = http_info->was_alpn_negotiated;
head->connection_info = http_info->connection_info;
head->alpn_negotiated_protocol = http_info->alpn_negotiated_protocol;
head->remote_endpoint = http_info->remote_endpoint;
head->cert_status = http_info->ssl_info.cert_status;
head->ssl_info = http_info->ssl_info;
std::move(callback).Run(status, std::move(head));
}
} // namespace
ServiceWorkerResourceReaderImpl::ServiceWorkerResourceReaderImpl(
std::unique_ptr<ServiceWorkerResponseReader> reader)
: reader_(std::move(reader)) {
DCHECK(reader_);
}
ServiceWorkerResourceReaderImpl::~ServiceWorkerResourceReaderImpl() = default;
void ServiceWorkerResourceReaderImpl::ReadResponseHead(
ReadResponseHeadCallback callback) {
auto buffer = base::MakeRefCounted<HttpResponseInfoIOBuffer>();
HttpResponseInfoIOBuffer* raw_buffer = buffer.get();
reader_->ReadInfo(raw_buffer, base::BindOnce(&DidReadInfo, std::move(buffer),
std::move(callback)));
}
ServiceWorkerResourceWriterImpl::ServiceWorkerResourceWriterImpl(
std::unique_ptr<ServiceWorkerResponseWriter> writer)
: writer_(std::move(writer)) {
......
......@@ -2,14 +2,39 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_RESOURCE_WRITER_IMPL_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_RESOURCE_WRITER_IMPL_H_
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_RESOURCE_OPS_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_RESOURCE_OPS_H_
#include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
namespace content {
// The implementation of storage::mojom::ServiceWorkerResourceReader.
// Currently this class is an adaptor that uses ServiceWorkerResponseReader
// internally.
// TODO(crbug.com/1055677): Fork the implementation of
// ServiceWorkerResponseReader and stop using it.
class ServiceWorkerResourceReaderImpl
: public storage::mojom::ServiceWorkerResourceReader {
public:
explicit ServiceWorkerResourceReaderImpl(
std::unique_ptr<ServiceWorkerResponseReader> reader);
ServiceWorkerResourceReaderImpl(const ServiceWorkerResourceReaderImpl&) =
delete;
ServiceWorkerResourceReaderImpl& operator=(
const ServiceWorkerResourceReaderImpl&) = delete;
~ServiceWorkerResourceReaderImpl() override;
private:
// storage::mojom::ServiceWorkerResourceReader implementations:
void ReadResponseHead(ReadResponseHeadCallback callback) override;
const std::unique_ptr<ServiceWorkerResponseReader> reader_;
};
// The implementation of storage::mojom::ServiceWorkerResourceWriter.
// Currently this class is an adaptor that uses ServiceWorkerResponseWriter
// internally.
......@@ -40,4 +65,4 @@ class ServiceWorkerResourceWriterImpl
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_RESOURCE_WRITER_IMPL_H_
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_RESOURCE_OPS_H_
......@@ -4,7 +4,7 @@
#include "content/browser/service_worker/service_worker_storage_control_impl.h"
#include "content/browser/service_worker/service_worker_resource_writer_impl.h"
#include "content/browser/service_worker/service_worker_resource_ops.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
......@@ -111,6 +111,15 @@ void ServiceWorkerStorageControlImpl::GetNewResourceId(
storage_->GetNewResourceId(std::move(callback));
}
void ServiceWorkerStorageControlImpl::CreateResourceReader(
int64_t resource_id,
mojo::PendingReceiver<storage::mojom::ServiceWorkerResourceReader> reader) {
DCHECK_NE(resource_id, blink::mojom::kInvalidServiceWorkerResourceId);
mojo::MakeSelfOwnedReceiver(std::make_unique<ServiceWorkerResourceReaderImpl>(
storage_->CreateResponseReader(resource_id)),
std::move(reader));
}
void ServiceWorkerStorageControlImpl::CreateResourceWriter(
int64_t resource_id,
mojo::PendingReceiver<storage::mojom::ServiceWorkerResourceWriter> writer) {
......
......@@ -53,6 +53,10 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl
const GURL& origin,
DeleteRegistrationCallback callback) override;
void GetNewResourceId(GetNewResourceIdCallback callback) override;
void CreateResourceReader(
int64_t resource_id,
mojo::PendingReceiver<storage::mojom::ServiceWorkerResourceReader> reader)
override;
void CreateResourceWriter(
int64_t resource_id,
mojo::PendingReceiver<storage::mojom::ServiceWorkerResourceWriter> writer)
......
......@@ -13,6 +13,8 @@
#include "content/public/test/test_utils.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/navigation_preload_state.mojom.h"
......@@ -24,6 +26,20 @@ using FindRegistrationResult =
namespace {
int ReadResponseHead(storage::mojom::ServiceWorkerResourceReader* reader,
network::mojom::URLResponseHeadPtr& out_response_head) {
int return_value;
base::RunLoop loop;
reader->ReadResponseHead(base::BindLambdaForTesting(
[&](int result, network::mojom::URLResponseHeadPtr response_head) {
return_value = result;
out_response_head = std::move(response_head);
loop.Quit();
}));
loop.Run();
return return_value;
}
int WriteResponseHead(storage::mojom::ServiceWorkerResourceWriter* writer,
network::mojom::URLResponseHeadPtr response_head) {
int return_value;
......@@ -163,10 +179,18 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
return return_value;
}
mojo::Remote<storage::mojom::ServiceWorkerResourceReader>
CreateResourceReader(int64_t resource_id) {
mojo::Remote<storage::mojom::ServiceWorkerResourceReader> reader;
storage()->CreateResourceReader(resource_id,
reader.BindNewPipeAndPassReceiver());
return reader;
}
mojo::Remote<storage::mojom::ServiceWorkerResourceWriter>
CreateNewResourceWriter() {
CreateResourceWriter(int64_t resource_id) {
mojo::Remote<storage::mojom::ServiceWorkerResourceWriter> writer;
storage()->CreateResourceWriter(GetNewResourceId(),
storage()->CreateResourceWriter(resource_id,
writer.BindNewPipeAndPassReceiver());
return writer;
}
......@@ -277,12 +301,20 @@ TEST_F(ServiceWorkerStorageControlImplTest, StoreAndDeleteRegistration) {
}
}
// Tests that writing a service worker script succeeds.
TEST_F(ServiceWorkerStorageControlImplTest, WriteResource) {
// Tests that writing/reading a service worker script succeed.
TEST_F(ServiceWorkerStorageControlImplTest, WriteAndReadResource) {
LazyInitializeForTest();
// Create a SSLInfo to write/read.
net::SSLInfo ssl_info = net::SSLInfo();
ssl_info.cert =
net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
ASSERT_TRUE(ssl_info.is_valid());
int64_t resource_id = GetNewResourceId();
mojo::Remote<storage::mojom::ServiceWorkerResourceWriter> writer =
CreateNewResourceWriter();
CreateResourceWriter(resource_id);
// Write a response head.
{
......@@ -292,23 +324,40 @@ TEST_F(ServiceWorkerStorageControlImplTest, WriteResource) {
"HTTP/1.1 200 OK\n"
"Content-Type: application/javascript\n"));
response_head->headers->GetMimeType(&response_head->mime_type);
response_head->ssl_info = ssl_info;
int result = WriteResponseHead(writer.get(), std::move(response_head));
ASSERT_GT(result, 0);
}
const std::string kData("/* script body */");
int data_size = kData.size();
// Write content.
{
const std::string kData("/* script body */");
mojo_base::BigBuffer data(base::as_bytes(base::make_span(kData)));
int data_size = data.size();
int result = WriteResponseData(writer.get(), std::move(data));
ASSERT_EQ(data_size, result);
}
// TODO(crbug.com/1055677): Read the resource and check the response head and
// content.
mojo::Remote<storage::mojom::ServiceWorkerResourceReader> reader =
CreateResourceReader(resource_id);
// Read the response head.
{
network::mojom::URLResponseHeadPtr response_head;
int result = ReadResponseHead(reader.get(), response_head);
ASSERT_GT(result, 0);
EXPECT_EQ(response_head->mime_type, "application/javascript");
EXPECT_EQ(response_head->content_length, data_size);
EXPECT_TRUE(response_head->ssl_info->is_valid());
EXPECT_EQ(response_head->ssl_info->cert->serial_number(),
ssl_info.cert->serial_number());
}
// TODO(crbug.com/1055677): Read and check the content of the resource.
}
} // namespace content
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