blob: f5957824baeee252ff9f2e9917cb8a1431d6ca9e [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_WEB_PACKAGE_PREFETCHED_SIGNED_EXCHANGE_CACHE_H_
#define CONTENT_BROWSER_WEB_PACKAGE_PREFETCHED_SIGNED_EXCHANGE_CACHE_H_
#include <map>
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/common/prefetched_signed_exchange_info.mojom.h"
#include "net/base/hash_value.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "url/gurl.h"
namespace net {
struct SHA256HashValue;
} // namespace net
namespace network {
struct URLLoaderCompletionStatus;
} // namespace network
namespace storage {
class BlobDataHandle;
} // namespace storage
namespace content {
class NavigationLoaderInterceptor;
// PrefetchedSignedExchangeCache keeps prefetched and verified signed
// exchanges.
class CONTENT_EXPORT PrefetchedSignedExchangeCache
: public base::RefCountedThreadSafe<PrefetchedSignedExchangeCache> {
public:
class CONTENT_EXPORT Entry {
public:
Entry();
~Entry();
const GURL& outer_url() const { return outer_url_; }
const network::mojom::URLResponseHeadPtr& outer_response() const {
return outer_response_;
}
const std::unique_ptr<const net::SHA256HashValue>& header_integrity()
const {
return header_integrity_;
}
const GURL& inner_url() const { return inner_url_; }
const network::mojom::URLResponseHeadPtr& inner_response() const {
return inner_response_;
}
const std::unique_ptr<const network::URLLoaderCompletionStatus>&
completion_status() const {
return completion_status_;
}
const std::unique_ptr<const storage::BlobDataHandle>& blob_data_handle()
const {
return blob_data_handle_;
}
base::Time signature_expire_time() const { return signature_expire_time_; }
void SetOuterUrl(const GURL& outer_url);
void SetOuterResponse(network::mojom::URLResponseHeadPtr outer_response);
void SetHeaderIntegrity(
std::unique_ptr<const net::SHA256HashValue> header_integrity);
void SetInnerUrl(const GURL& inner_url);
void SetInnerResponse(network::mojom::URLResponseHeadPtr inner_response);
void SetCompletionStatus(
std::unique_ptr<const network::URLLoaderCompletionStatus>
completion_status);
void SetBlobDataHandle(
std::unique_ptr<const storage::BlobDataHandle> blob_data_handle);
void SetSignatureExpireTime(const base::Time& signature_expire_time);
std::unique_ptr<const Entry> Clone() const;
private:
GURL outer_url_;
network::mojom::URLResponseHeadPtr outer_response_;
std::unique_ptr<const net::SHA256HashValue> header_integrity_;
GURL inner_url_;
network::mojom::URLResponseHeadPtr inner_response_;
std::unique_ptr<const network::URLLoaderCompletionStatus>
completion_status_;
std::unique_ptr<const storage::BlobDataHandle> blob_data_handle_;
base::Time signature_expire_time_;
DISALLOW_COPY_AND_ASSIGN(Entry);
};
// A test observer to monitor the cache entry.
class TestObserver : public base::CheckedObserver {
public:
virtual void OnStored(PrefetchedSignedExchangeCache* cache,
const GURL& outer_url) = 0;
};
using EntryMap = std::map<GURL /* outer_url */, std::unique_ptr<const Entry>>;
PrefetchedSignedExchangeCache();
void Store(std::unique_ptr<const Entry> cached_exchange);
void Clear();
std::unique_ptr<NavigationLoaderInterceptor> MaybeCreateInterceptor(
const GURL& outer_url);
const EntryMap& GetExchanges();
void RecordHistograms();
// Adds/removes test observers.
void AddObserverForTesting(TestObserver* observer);
void RemoveObserverForTesting(const TestObserver* observer);
private:
friend class base::RefCountedThreadSafe<PrefetchedSignedExchangeCache>;
~PrefetchedSignedExchangeCache();
// Returns PrefetchedSignedExchangeInfo of entries in |exchanges_| which are
// not expired and which are declared in the "allowed-alt-sxg" link header of
// |main_exchange|'s inner response and which outer URL's origin is same as
// the origin of |main_exchange|'s outer URL. Note that this method erases
// expired entries in |exchanges_|.
std::vector<mojom::PrefetchedSignedExchangeInfoPtr> GetInfoListForNavigation(
const Entry& main_exchange,
const base::Time& now);
EntryMap exchanges_;
base::ObserverList<TestObserver> test_observers_;
DISALLOW_COPY_AND_ASSIGN(PrefetchedSignedExchangeCache);
};
} // namespace content
#endif // CONTENT_BROWSER_WEB_PACKAGE_PREFETCHED_SIGNED_EXCHANGE_CACHE_H_