Skip to content

Commit d345b57

Browse files
Implement fastly.env.get as a way to read environment variables (#50)
C@E [exposes various pieces of information about the service and host as environment variables](https://developer.fastly.com/reference/compute/ecp-env/). This patch adds an official way to read those variables. The patch also removes the previous, undocumented way this information was exposed, as more discussion lead to the consensus that this approach makes more sense.
1 parent e695e99 commit d345b57

File tree

1 file changed

+43
-70
lines changed

1 file changed

+43
-70
lines changed

c-dependencies/js-compute-runtime/js-compute-builtins.cpp

+43-70
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,35 @@ namespace Logger {
424424
}
425425
}
426426

427+
namespace Env {
428+
bool env_get(JSContext* cx, unsigned argc, Value* vp) {
429+
CallArgs args = CallArgsFromVp(argc, vp);
430+
if (!args.requireAtLeast(cx, "fastly.env.get", 1))
431+
return false;
432+
433+
size_t var_name_len;
434+
UniqueChars var_name_chars = encode(cx, args[0], &var_name_len);
435+
if (!var_name_chars) {
436+
return false;
437+
}
438+
RootedString env_var(cx, JS_NewStringCopyZ(cx, getenv(var_name_chars.get())));
439+
if (!env_var) return false;
440+
441+
args.rval().setString(env_var);
442+
return true;
443+
}
444+
445+
const JSFunctionSpec methods[] = {
446+
JS_FN("get", env_get, 1, 0),
447+
JS_FS_END};
448+
449+
JSObject* create(JSContext* cx) {
450+
RootedObject env(cx, JS_NewPlainObject(cx));
451+
if (!env || !JS_DefineFunctions(cx, env, methods)) return nullptr;
452+
return env;
453+
}
454+
}
455+
427456
namespace URL {
428457
bool is_instance(JS::Value);
429458
JSObject* create(JSContext* cx, SpecString url_str, const JSUrl* base = nullptr);
@@ -436,6 +465,11 @@ namespace Fastly {
436465

437466
static bool debug_logging_enabled = false;
438467

468+
static PersistentRooted<JSObject*> env;
469+
470+
static PersistentRooted<JSObject*> baseURL;
471+
static PersistentRooted<JSString*> defaultBackend;
472+
439473
bool dump(JSContext* cx, unsigned argc, Value* vp) {
440474
CallArgs args = CallArgsFromVp(argc, vp);
441475
if (!args.requireAtLeast(cx, __func__, 1))
@@ -543,8 +577,11 @@ namespace Fastly {
543577
JS_FS_END
544578
};
545579

546-
static PersistentRooted<JSObject*> baseURL;
547-
static PersistentRooted<JSString*> defaultBackend;
580+
bool env_get(JSContext* cx, unsigned argc, Value* vp) {
581+
CallArgs args = CallArgsFromVp(argc, vp);
582+
args.rval().setObject(*env);
583+
return true;
584+
}
548585

549586
bool baseURL_get(JSContext* cx, unsigned argc, Value* vp) {
550587
CallArgs args = CallArgsFromVp(argc, vp);
@@ -587,6 +624,7 @@ namespace Fastly {
587624
}
588625

589626
const JSPropertySpec properties[] = {
627+
JS_PSG("env", env_get, JSPROP_ENUMERATE),
590628
JS_PSGS("baseURL", baseURL_get, baseURL_set, JSPROP_ENUMERATE),
591629
JS_PSGS("defaultBackend", defaultBackend_get, defaultBackend_set, JSPROP_ENUMERATE),
592630
JS_PS_END};
@@ -595,7 +633,10 @@ namespace Fastly {
595633
RootedObject fastly(cx, JS_NewPlainObject(cx));
596634
if (!fastly) return false;
597635

636+
env.init(cx, Env::create(cx));
637+
if (!env) return false;
598638
baseURL.init(cx);
639+
defaultBackend.init(cx);
599640

600641
if (!JS_DefineProperty(cx, global, "fastly", fastly, 0)) return false;
601642
return JS_DefineFunctions(cx, fastly, methods) &&
@@ -3157,56 +3198,6 @@ namespace ClientInfo {
31573198
}
31583199
}
31593200

3160-
namespace ServiceInfo {
3161-
namespace Slots { enum {
3162-
Count
3163-
};};
3164-
3165-
static constexpr char ENV_CACHE_GENERATION[] = "FASTLY_CACHE_GENERATION";
3166-
static constexpr char ENV_CUSTOMER_ID[] = "FASTLY_CUSTOMER_ID";
3167-
static constexpr char ENV_HOSTNAME[] = "FASTLY_HOSTNAME";
3168-
static constexpr char ENV_POP[] = "FASTLY_POP";
3169-
static constexpr char ENV_REGION[] = "FASTLY_REGION";
3170-
static constexpr char ENV_SERVICE_ID[] = "FASTLY_SERVICE_ID";
3171-
static constexpr char ENV_SERVICE_VERSION[] = "FASTLY_SERVICE_VERSION";
3172-
static constexpr char ENV_TRACE_ID[] = "FASTLY_TRACE_ID";
3173-
3174-
const unsigned ctor_length = 0;
3175-
3176-
bool check_receiver(JSContext* cx, HandleObject self, const char* method_name);
3177-
3178-
template<const char* var_name>
3179-
bool env_var_get(JSContext* cx, unsigned argc, Value* vp) {
3180-
METHOD_HEADER(0)
3181-
3182-
RootedString env_var(cx, JS_NewStringCopyZ(cx, getenv(var_name)));
3183-
if (!env_var) return false;
3184-
3185-
args.rval().setString(env_var);
3186-
return true;
3187-
}
3188-
3189-
const JSFunctionSpec methods[] = {
3190-
JS_FS_END};
3191-
3192-
const JSPropertySpec properties[] = {
3193-
JS_PSG("cacheGeneration", env_var_get<ENV_CACHE_GENERATION>, 0),
3194-
JS_PSG("customerId", env_var_get<ENV_CUSTOMER_ID>, 0),
3195-
JS_PSG("hostname", env_var_get<ENV_HOSTNAME>, 0),
3196-
JS_PSG("pop", env_var_get<ENV_POP>, 0),
3197-
JS_PSG("region", env_var_get<ENV_REGION>, 0),
3198-
JS_PSG("serviceId", env_var_get<ENV_SERVICE_ID>, 0),
3199-
JS_PSG("serviceVersion", env_var_get<ENV_SERVICE_VERSION>, 0),
3200-
JS_PSG("traceId", env_var_get<ENV_TRACE_ID>, 0),
3201-
JS_PS_END};
3202-
3203-
CLASS_BOILERPLATE_NO_CTOR(ServiceInfo)
3204-
3205-
JSObject* create(JSContext* cx) {
3206-
return JS_NewObjectWithGivenProto(cx, &class_, proto_obj);
3207-
}
3208-
}
3209-
32103201

32113202
namespace FetchEvent {
32123203
namespace Slots { enum {
@@ -3216,7 +3207,6 @@ namespace FetchEvent {
32163207
PendingPromiseCount,
32173208
DecPendingPromiseCountFunc,
32183209
ClientInfo,
3219-
ServiceInfo,
32203210
Count
32213211
};};
32223212

@@ -3272,22 +3262,6 @@ static PersistentRooted<JSObject*> INSTANCE;
32723262
return true;
32733263
}
32743264

3275-
bool service_get(JSContext* cx, unsigned argc, Value* vp) {
3276-
METHOD_HEADER(0)
3277-
RootedValue serviceInfo(cx, JS::GetReservedSlot(self, Slots::ServiceInfo));
3278-
3279-
if (serviceInfo.isUndefined()) {
3280-
RootedObject obj(cx, ServiceInfo::create(cx));
3281-
if (!obj)
3282-
return false;
3283-
serviceInfo.setObject(*obj);
3284-
JS::SetReservedSlot(self, Slots::ServiceInfo, serviceInfo);
3285-
}
3286-
3287-
args.rval().set(serviceInfo);
3288-
return true;
3289-
}
3290-
32913265
static JSObject* prepare_downstream_request(JSContext* cx) {
32923266
return Request::create(cx, RequestHandle { INVALID_HANDLE },
32933267
BodyHandle { INVALID_HANDLE }, true);
@@ -3682,7 +3656,6 @@ static PersistentRooted<JSObject*> INSTANCE;
36823656

36833657
const JSPropertySpec properties[] = {
36843658
JS_PSG("client", client_get, 0),
3685-
JS_PSG("service", service_get, 0),
36863659
JS_PSG("request", request_get, 0),
36873660
JS_PS_END};
36883661

0 commit comments

Comments
 (0)