Skip to content

Commit 753ec18

Browse files
author
Jake Champion
committed
when using implicit dynamic backends - reuse an already existing backend if one exists for the host being requested
1 parent e093be2 commit 753ec18

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

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

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#include <charconv>
21
#include <cctype>
2+
#include <charconv>
33
#include <iostream>
44
#include <optional>
55
#include <string>
@@ -48,9 +48,9 @@ bool isValidHost(std::string_view host) {
4848
std::string_view hostname = host.substr(0, pos);
4949

5050
// hostnames can not be longer than 253 characters
51-
// This is because a hostname is represented as a series of labels, and is terminated by a label of length zero.
52-
// A label consists of a length octet followed by that number of octets representing the name itself.
53-
// https://www.rfc-editor.org/rfc/rfc1035#section-3.3
51+
// This is because a hostname is represented as a series of labels, and is terminated by a label
52+
// of length zero. A label consists of a length octet followed by that number of octets
53+
// representing the name itself. https://www.rfc-editor.org/rfc/rfc1035#section-3.3
5454
// https://www.rfc-editor.org/rfc/rfc2181#section-11
5555
if (hostname.length() > 253) {
5656
return false;
@@ -64,7 +64,7 @@ bool isValidHost(std::string_view host) {
6464

6565
auto labels = split(hostname, '.');
6666

67-
for (auto label:labels) {
67+
for (auto label : labels) {
6868
// Each label in a hostname can not be longer than 63 characters
6969
// https://www.rfc-editor.org/rfc/rfc2181#section-11
7070
if (label.length() > 63) {
@@ -89,7 +89,8 @@ bool isValidHost(std::string_view host) {
8989
return false;
9090
}
9191
int value;
92-
const std::from_chars_result result = std::from_chars(port.data(), port.data() + port.size(), value);
92+
const std::from_chars_result result =
93+
std::from_chars(port.data(), port.data() + port.size(), value);
9394
if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range) {
9495
return false;
9596
}
@@ -346,11 +347,6 @@ bool Backend::set_target(JSContext *cx, JSObject *backend, JS::HandleValue targe
346347
}
347348

348349
JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
349-
JS::RootedObject backend(cx,
350-
JS_NewObjectWithGivenProto(cx, &Backend::class_, Backend::proto_obj));
351-
if (!backend) {
352-
return nullptr;
353-
}
354350
JS::RootedValue request_url(cx, RequestOrResponse::url(request));
355351
auto url_string = encode(cx, request_url);
356352
if (!url_string.data) {
@@ -363,12 +359,37 @@ JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
363359
return nullptr;
364360
}
365361
const jsurl::SpecSlice slice = jsurl::host(url);
362+
std::string aaa((char *)slice.data, slice.len);
366363
auto nameStr = JS_NewStringCopyN(cx, (char *)slice.data, slice.len);
367364
if (!nameStr) {
368365
return nullptr;
369366
}
367+
368+
// Check if we already constructed an implicit dynamic backend for this host.
369+
bool found;
370+
JS::RootedValue alreadyBuiltBackend(cx);
371+
if (!JS_HasProperty(cx, Backend::backends, aaa.c_str(), &found)) {
372+
return nullptr;
373+
}
374+
if (found) {
375+
if (!JS_GetProperty(cx, Backend::backends, aaa.c_str(), &alreadyBuiltBackend)) {
376+
return nullptr;
377+
}
378+
JS::RootedObject backend(cx, &alreadyBuiltBackend.toObject());
379+
return backend;
380+
}
381+
382+
auto backendInstance = JS_NewObjectWithGivenProto(cx, &Backend::class_, Backend::proto_obj);
383+
if (!backendInstance) {
384+
return nullptr;
385+
}
386+
JS::RootedValue backendVal(cx, JS::ObjectValue(*backendInstance));
387+
JS::RootedObject backend(cx, backendInstance);
388+
if (!backend) {
389+
return nullptr;
390+
}
391+
370392
JS::RootedValue name(cx, JS::StringValue(nameStr));
371-
// The backend name provided was too long; please keep it to <255
372393
if (!Backend::set_name(cx, backend, name)) {
373394
return nullptr;
374395
}
@@ -388,6 +409,9 @@ JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
388409
if (result.isErr()) {
389410
return nullptr;
390411
} else {
412+
if (!JS_SetProperty(cx, Backend::backends, aaa.c_str(), backendVal)) {
413+
return nullptr;
414+
}
391415
return backend;
392416
}
393417
}
@@ -710,6 +734,11 @@ bool Backend::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
710734
}
711735

712736
bool Backend::init_class(JSContext *cx, JS::HandleObject global) {
737+
JS::RootedObject backends(cx, JS_NewPlainObject(cx));
738+
if (!backends) {
739+
return false;
740+
}
741+
Backend::backends.init(cx, backends);
713742
return BuiltinImpl<Backend>::init_class_impl(cx, global);
714743
}
715744

c-dependencies/js-compute-runtime/builtins/backend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class Backend : public BuiltinImpl<Backend> {
3030
static const JSFunctionSpec methods[];
3131
static const JSPropertySpec properties[];
3232

33+
inline static JS::PersistentRootedObject backends;
34+
3335
static JSString *name(JSContext *cx, JSObject *self);
3436
static JS::Result<mozilla::Ok> register_dynamic_backend(JSContext *cx, JS::HandleObject request);
3537
static JSObject *create(JSContext *cx, JS::HandleObject request);

integration-tests/js-compute/fixtures/dynamic-backend/bin/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ routes.set('/', () => {
4747
if (error) { return error }
4848
return pass()
4949
});
50+
routes.set("/implicit-dynamic-backend/dynamic-backends-enabled-called-twice", async () => {
51+
fastly.allowDynamicBackends = true;
52+
let error = await assertResolves(() => fetch('https://httpbin.org/headers'));
53+
if (error) { return error }
54+
error = await assertResolves(() => fetch('https://httpbin.org/headers'));
55+
if (error) { return error }
56+
return pass()
57+
});
5058
}
5159

5260
// explicit dynamic backend

0 commit comments

Comments
 (0)