Skip to content

Commit

Permalink
Gate prototypes behind compatability flag for cache: no-store
Browse files Browse the repository at this point in the history
  • Loading branch information
AdityaAtulTewari committed Jul 26, 2024
1 parent 982d8c7 commit 2faac4f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 34 deletions.
127 changes: 99 additions & 28 deletions src/workerd/api/http-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export default {

export const inspect = {
async test(ctrl, env, ctx) {
const cacheEnabled = env.cacheEnabled === "true"
// Check URL with duplicate search param keys
const url = new URL("http://user:pass@placeholder:8787/path?a=1&a=2&b=3");
assert.strictEqual(util.inspect(url),
Expand Down Expand Up @@ -124,7 +125,8 @@ export const inspect = {
body: "message",
headers: { "Content-Type": "text/plain" }
});
assert.strictEqual(util.inspect(request),
if(cacheEnabled) {
assert.strictEqual(util.inspect(request),
`Request {
cache: undefined,
keepalive: false,
Expand All @@ -144,7 +146,29 @@ export const inspect = {
[length]: 7n
}
}`
);
);
} else {
assert.strictEqual(util.inspect(request),
`Request {
keepalive: false,
integrity: '',
cf: undefined,
signal: AbortSignal { reason: undefined, aborted: false, onabort: null },
fetcher: null,
redirect: 'follow',
headers: Headers(1) { 'content-type' => 'text/plain', [immutable]: false },
url: 'http://placeholder',
method: 'POST',
bodyUsed: false,
body: ReadableStream {
locked: false,
[state]: 'readable',
[supportsBYOB]: true,
[length]: 7n
}
}`
);
}

// Check response with immutable headers
const response = await env.SERVICE.fetch("http://placeholder/not-found");
Expand Down Expand Up @@ -208,43 +232,90 @@ export const inspect = {
};

export const cacheMode = {
async test() {
assert.strictEqual("cache" in Request.prototype, false);
async test(ctrl, env, ctx) {
const cacheEnabled = env.cacheEnabled === "true";
assert.strictEqual("cache" in Request.prototype, cacheEnabled);
{
const req = new Request('https://example.org', { });
assert.strictEqual(req.cache, undefined);
}
{
assert.throws(() => {
new Request('https://example.org', { cache: 'no-store' });
}, {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
if(!cacheEnabled) {
assert.throws(() => {
new Request('https://example.org', { cache: 'no-store' });
}, {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
} else {
const req = new Request('https://example.org', { cache: 'no-store' });
assert.strictEqual(req.cache, 'no-store');
}
}
{
assert.throws(() => {
new Request('https://example.org', { cache: 'no-cache' });
}, {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
if(!cacheEnabled) {
assert.throws(() => {
new Request('https://example.org', { cache: 'no-cache' });
}, {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
} else {
const req = new Request('https://example.org', { cache: 'no-cache' });
assert.strictEqual(req.cache, 'no-cache');
}
}
{
assert.throws(() => {
new Request('https://example.org', { cache: 'unsupported' });
}, {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
if(!cacheEnabled) {
assert.throws(() => {
new Request('https://example.org', { cache: 'unsupported' });
}, {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
} else {
assert.throws(() => {
new Request('https://example.org', { cache: 'unsupported' });
}, {
name: 'TypeError',
message: "Unsupported cache mode: unsupported",
});

}
}
{
await assert.rejects((async () => {
await fetch('http://example.org', { cache: 'no-transform' });
})(), {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
if(!cacheEnabled) {
await assert.rejects((async () => {
await fetch('http://example.org', { cache: 'no-cache' });
})(), {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
} else {
await assert.rejects((async () => {
await fetch('http://example.org', { cache: 'no-cache' });
})(), {
name: 'TypeError',
message: "Unsupported cache mode: no-cache",
});
}
}
{
if(!cacheEnabled) {
await assert.rejects((async () => {
await fetch('http://example.org', { cache: 'no-transform' });
})(), {
name: 'Error',
message: "The 'cache' field on 'RequestInitializerDict' is not implemented.",
});
} else {
await assert.rejects((async () => {
await fetch('http://example.org', { cache: 'no-transform' });
})(), {
name: 'TypeError',
message: "Unsupported cache mode: no-transform",
});
}
}
}
}
17 changes: 15 additions & 2 deletions src/workerd/api/http-test.wd-test
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@ const unitTests :Workerd.Config = (
( name = "worker", esModule = embed "http-test.js" )
],
bindings = [
( name = "SERVICE", service = "http-test" )
( name = "SERVICE", service = "http-test" ),
( name = "cacheEnabled", text = "false" ),
],
compatibilityDate = "2023-08-01",
compatibilityFlags = ["nodejs_compat", "service_binding_extra_handlers", "cache_option_enabled"],
compatibilityFlags = ["nodejs_compat", "service_binding_extra_handlers", "cache_option_disabled"],
)
),
( name = "http-test-cache-option-enabled",
worker = (
modules = [
( name = "worker-cache-enabled", esModule = embed "http-test.js" )
],
bindings = [
( name = "SERVICE", service = "http-test-cache-option-enabled" ),
( name = "cacheEnabled", text = "true" ),
],
compatibilityDate = "2023-08-01",
compatibilityFlags = ["nodejs_compat", "service_binding_extra_handlers", "cache_option_enabled"],
))
],
);
7 changes: 4 additions & 3 deletions src/workerd/api/http.c++
Original file line number Diff line number Diff line change
Expand Up @@ -1076,9 +1076,8 @@ jsg::Ref<Request> Request::constructor(
}

KJ_IF_SOME(c, initDict.cache) {
JSG_REQUIRE(FeatureFlags::get(js).getCacheOptionEnabled(), TypeError, kj::str(
"Unsupported cache mode: ", c,
"\nYou may need to enable the cache_option_enabled compatability flag."));
JSG_REQUIRE(FeatureFlags::get(js).getCacheOptionEnabled(), Error, kj::str(
"The 'cache' field on 'RequestInitializerDict' is not implemented."));
cacheMode = getCacheModeFromName(c);
}

Expand Down Expand Up @@ -1811,6 +1810,8 @@ jsg::Promise<jsg::Ref<Response>> fetchImplNoOutputLock(
// Currently, the only cache mode we support is undefined, but we will soon support
// no-cache and no-store. These additional modes will be hidden behind an autogate.
if (jsRequest->getCacheMode() != Request::CacheMode::NONE) {
JSG_REQUIRE(FeatureFlags::get(js).getCacheOptionEnabled(), Error, kj::str(
+ "The 'cache' field on 'RequestInitializerDict' is not implemented."));
return js.rejectedPromise<jsg::Ref<Response>>(
js.typeError(kj::str("Unsupported cache mode: ",
KJ_ASSERT_NONNULL(jsRequest->getCache(js)))));
Expand Down
4 changes: 3 additions & 1 deletion src/workerd/api/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,9 @@ class Request: public Body {
// JSG_READONLY_PROTOTYPE_PROPERTY(credentials, getCredentials);
JSG_READONLY_PROTOTYPE_PROPERTY(integrity, getIntegrity);
JSG_READONLY_PROTOTYPE_PROPERTY(keepalive, getKeepalive);
JSG_READONLY_PROTOTYPE_PROPERTY(cache, getCache);
if(flags.getCacheOptionEnabled()) {
JSG_READONLY_PROTOTYPE_PROPERTY(cache, getCache);
}

JSG_TS_OVERRIDE(<CfHostMetadata = unknown, Cf = CfProperties<CfHostMetadata>> {
constructor(input: RequestInfo<CfProperties>, init?: RequestInit<Cf>);
Expand Down

0 comments on commit 2faac4f

Please sign in to comment.