Skip to content
File

Blob: src/workerd/api/cache.h

cpp147 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#pragma once
6 
7#include "http.h"
8 
9#include <workerd/jsg/jsg.h>
10 
11namespace workerd::api {
12 
13// =======================================================================================
14// Cache
15 
16struct CacheQueryOptions {
17 // By default, Cache.match() and Cache.delete() will return undefined/false if passed a non-GET
18 // request. Setting `ignoreMethod` to true disables this behavior; Cache.match() and
19 // Cache.delete() will treat any request as a GET request.
20 jsg::Optional<bool> ignoreMethod;
21 
22 // Our cache does not support matching without query parameters at match time. Users can still
23 // remove query parameters before put()ing the Request/Response pair, if they wish.
24 jsg::WontImplement ignoreSearch;
25 
26 // Historically, Cloudflare has not supported the Vary header because it's easy to blow up your
27 // cache keys. Customers can now implement this with workers by modifying cache keys as they see
28 // fit based on any arbitrary parameter (User-Agent, Content-Encoding, etc.).
29 jsg::WontImplement ignoreVary;
30 
31 // Only used in CacheStorage::match(), which we won't implement.
32 jsg::WontImplement cacheName;
33 
34 JSG_STRUCT(ignoreMethod, ignoreSearch, ignoreVary, cacheName);
35};
36 
37class Cache: public jsg::Object {
38 public:
39 explicit Cache(kj::Maybe<kj::String> cacheName);
40 
41 jsg::Unimplemented add(Request::Info request);
42 jsg::Unimplemented addAll(kj::Array<Request::Info> requests);
43 
44 jsg::Promise<jsg::Optional<jsg::Ref<Response>>> match(jsg::Lock& js,
45 Request::Info request,
46 jsg::Optional<CacheQueryOptions> options,
47 CompatibilityFlags::Reader flags);
48 
49 jsg::Promise<void> put(jsg::Lock& js,
50 Request::Info request,
51 jsg::Ref<Response> response,
52 CompatibilityFlags::Reader flags);
53 
54 jsg::Promise<bool> delete_(jsg::Lock& js,
55 Request::Info request,
56 jsg::Optional<CacheQueryOptions> options,
57 CompatibilityFlags::Reader flags);
58 
59 // Our cache does not support one-to-many matching, so this is not possible to implement.
60 jsg::WontImplement matchAll(jsg::Optional<Request::Info>, jsg::Optional<CacheQueryOptions>) {
61 return {};
62 }
63 
64 // Our cache does not support cache item enumeration, so this is not possible to implement.
65 jsg::WontImplement keys(jsg::Optional<Request::Info>, jsg::Optional<CacheQueryOptions>) {
66 return {};
67 }
68 
69 JSG_RESOURCE_TYPE(Cache) {
70 JSG_METHOD(add);
71 JSG_METHOD(addAll);
72 JSG_METHOD_NAMED(delete, delete_);
73 JSG_METHOD(match);
74 JSG_METHOD(put);
75 JSG_METHOD(matchAll);
76 JSG_METHOD(keys);
77 
78 JSG_TS_OVERRIDE({
79 delete(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<boolean>;
80 match(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<Response | undefined>;
81 put(request: RequestInfo | URL, response: Response): Promise<void>;
82 });
83 }
84 
85 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const {
86 tracker.trackField("cacheName", cacheName);
87 }
88 
89 private:
90 kj::Maybe<kj::String> cacheName;
91 
92 kj::Own<kj::HttpClient> getHttpClient(IoContext& context,
93 kj::Maybe<kj::String> cfBlobJson,
94 TraceContext& traceContext,
95 bool enableCompatFlags);
96};
97 
98// =======================================================================================
99// CacheStorage
100 
101class CacheStorage: public jsg::Object {
102 public:
103 CacheStorage(jsg::Lock& js);
104 
105 jsg::Promise<jsg::Ref<Cache>> open(jsg::Lock& js, kj::String cacheName);
106 
107 jsg::Ref<Cache> getDefault() {
108 return default_.addRef();
109 }
110 
111 // Our cache does not support namespace enumeration, so none of these are possible to implement.
112 
113 jsg::WontImplement match(Request::Info, jsg::Optional<CacheQueryOptions>) {
114 return {};
115 }
116 jsg::WontImplement has(kj::String) {
117 return {};
118 }
119 jsg::WontImplement delete_(kj::String) {
120 return {};
121 }
122 jsg::WontImplement keys() {
123 return {};
124 }
125 
126 JSG_RESOURCE_TYPE(CacheStorage) {
127 JSG_METHOD(open);
128 JSG_METHOD_NAMED(delete, delete_);
129 JSG_METHOD(match);
130 JSG_METHOD(has);
131 JSG_METHOD(keys);
132 
133 JSG_READONLY_INSTANCE_PROPERTY(default, getDefault);
134 }
135 
136 void visitForMemoryInfo(jsg::MemoryTracker& tracker) const {
137 tracker.trackField("default", default_);
138 }
139 
140 private:
141 jsg::Ref<Cache> default_;
142};
143 
144#define EW_CACHE_ISOLATE_TYPES api::CacheStorage, api::Cache, api::CacheQueryOptions
145 
146} // namespace workerd::api