Skip to content

Commit

Permalink
cache override implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Dec 11, 2024
1 parent 3035e85 commit c60b2e7
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 1 deletion.
92 changes: 92 additions & 0 deletions runtime/fastly/builtins/cache-override.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,26 @@ void CacheOverride::set_pci(JSObject *self, bool pci) {
JS::SetReservedSlot(self, CacheOverride::Slots::PCI, JS::BooleanValue(pci));
}

JS::Value CacheOverride::beforeSend(JSObject *self) {
MOZ_ASSERT(is_instance(self));
return JS::GetReservedSlot(self, Slots::BeforeSend);
}

void CacheOverride::set_beforeSend(JSObject *self, JSObject *fn) {
MOZ_ASSERT(is_instance(self));
JS::SetReservedSlot(self, Slots::BeforeSend, JS::ObjectValue(*fn));
}

JS::Value CacheOverride::afterSend(JSObject *self) {
MOZ_ASSERT(is_instance(self));
return JS::GetReservedSlot(self, Slots::AfterSend);
}

void CacheOverride::set_afterSend(JSObject *self, JSObject *fn) {
MOZ_ASSERT(is_instance(self));
JS::SetReservedSlot(self, Slots::AfterSend, JS::ObjectValue(*fn));
}

host_api::CacheOverrideTag CacheOverride::abi_tag(JSObject *self) {
host_api::CacheOverrideTag tag;

Expand Down Expand Up @@ -285,6 +305,64 @@ bool CacheOverride::pci_set(JSContext *cx, JS::HandleObject self, JS::HandleValu
return true;
}

bool CacheOverride::before_send_get(JSContext *cx, JS::HandleObject self,
JS::MutableHandleValue rval) {
if (self == proto_obj) {
return api::throw_error(cx, api::Errors::WrongReceiver, "beforeSend get", "CacheOverride");
}
rval.set(CacheOverride::beforeSend(self));
return true;
}

bool CacheOverride::before_send_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
JS::MutableHandleValue rval) {
if (self == proto_obj) {
return api::throw_error(cx, api::Errors::WrongReceiver, "beforeSend set", "CacheOverride");
}
if (!CacheOverride::ensure_override(cx, self, "beforeSend"))
return false;
if (val.isUndefined()) {
JS::SetReservedSlot(self, Slots::BeforeSend, val);
} else if (!val.isObject() || !JS::IsCallable(&val.toObject())) {
JS_ReportErrorUTF8(cx, "CacheOverride: beforeSend must be a function");
return false;
} else {
CacheOverride::set_beforeSend(self, &val.toObject());
}

rval.set(CacheOverride::beforeSend(self));
return true;
}

bool CacheOverride::after_send_get(JSContext *cx, JS::HandleObject self,
JS::MutableHandleValue rval) {
if (self == proto_obj) {
return api::throw_error(cx, api::Errors::WrongReceiver, "afterSend get", "CacheOverride");
}
rval.set(CacheOverride::afterSend(self));
return true;
}

bool CacheOverride::after_send_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
JS::MutableHandleValue rval) {
if (self == proto_obj) {
return api::throw_error(cx, api::Errors::WrongReceiver, "afterSend set", "CacheOverride");
}
if (!CacheOverride::ensure_override(cx, self, "afterSend"))
return false;
if (val.isUndefined()) {
JS::SetReservedSlot(self, Slots::AfterSend, val);
} else if (!val.isObject() || !JS::IsCallable(&val.toObject())) {
JS_ReportErrorUTF8(cx, "CacheOverride: afterSend must be a function");
return false;
} else {
CacheOverride::set_afterSend(self, &val.toObject());
}

rval.set(CacheOverride::afterSend(self));
return true;
}

template <auto accessor_fn>
bool CacheOverride::accessor_get(JSContext *cx, unsigned argc, JS::Value *vp) {
METHOD_HEADER(0)
Expand All @@ -308,6 +386,10 @@ const JSPropertySpec CacheOverride::properties[] = {
JS_PSGS("surrogateKey", accessor_get<surrogate_key_get>, accessor_set<surrogate_key_set>,
JSPROP_ENUMERATE),
JS_PSGS("pci", accessor_get<pci_get>, accessor_set<pci_set>, JSPROP_ENUMERATE),
JS_PSGS("beforeSend", accessor_get<before_send_get>, accessor_set<before_send_set>,
JSPROP_ENUMERATE),
JS_PSGS("afterSend", accessor_get<after_send_get>, accessor_set<after_send_set>,
JSPROP_ENUMERATE),
JS_STRING_SYM_PS(toStringTag, "CacheOverride", JSPROP_READONLY),
JS_PS_END};

Expand Down Expand Up @@ -345,6 +427,16 @@ bool CacheOverride::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
if (!JS_GetProperty(cx, override_init, "pci", &val) || !pci_set(cx, self, val, &val)) {
return false;
}

if (!JS_GetProperty(cx, override_init, "beforeSend", &val) ||
!before_send_set(cx, self, val, &val)) {
return false;
}

if (!JS_GetProperty(cx, override_init, "afterSend", &val) ||
!after_send_set(cx, self, val, &val)) {
return false;
}
}

args.rval().setObject(*self);
Expand Down
15 changes: 14 additions & 1 deletion runtime/fastly/builtins/cache-override.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ class CacheOverride : public builtins::BuiltinImpl<CacheOverride> {
//
// `PCI` is interpreted as a boolean, and a flag gets set in the hostcall's
// `tag` parameter if `PCI` is true.
enum Slots { Mode, TTL, SWR, SurrogateKey, PCI, Count };
//
// `BeforeSend` and `AfterSend` are function callbacks that can be set
// to execute before and after sending the request.
enum Slots { Mode, TTL, SWR, SurrogateKey, PCI, BeforeSend, AfterSend, Count };

enum class CacheOverrideMode { None, Pass, Override };

Expand All @@ -44,6 +47,10 @@ class CacheOverride : public builtins::BuiltinImpl<CacheOverride> {
static JSObject *clone(JSContext *cx, JS::HandleObject self);
static JS::Value pci(JSObject *self);
static void set_pci(JSObject *self, bool pci);
static JS::Value beforeSend(JSObject *self);
static void set_beforeSend(JSObject *self, JSObject *fn);
static JS::Value afterSend(JSObject *self);
static void set_afterSend(JSObject *self, JSObject *fn);
static CacheOverrideMode mode(JSObject *self);
static void set_mode(JSObject *self, CacheOverride::CacheOverrideMode mode);
static bool mode_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval);
Expand All @@ -61,6 +68,12 @@ class CacheOverride : public builtins::BuiltinImpl<CacheOverride> {
static bool pci_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval);
static bool pci_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
JS::MutableHandleValue rval);
static bool before_send_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval);
static bool before_send_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
JS::MutableHandleValue rval);
static bool after_send_get(JSContext *cx, JS::HandleObject self, JS::MutableHandleValue rval);
static bool after_send_set(JSContext *cx, JS::HandleObject self, JS::HandleValue val,
JS::MutableHandleValue rval);
template <auto accessor_fn> static bool accessor_get(JSContext *cx, unsigned argc, JS::Value *vp);
template <auto accessor_fn> static bool accessor_set(JSContext *cx, unsigned argc, JS::Value *vp);

Expand Down

0 comments on commit c60b2e7

Please sign in to comment.