1
- #include < charconv>
2
1
#include < cctype>
2
+ #include < charconv>
3
3
#include < iostream>
4
4
#include < optional>
5
5
#include < string>
@@ -48,9 +48,9 @@ bool isValidHost(std::string_view host) {
48
48
std::string_view hostname = host.substr (0 , pos);
49
49
50
50
// 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
54
54
// https://www.rfc-editor.org/rfc/rfc2181#section-11
55
55
if (hostname.length () > 253 ) {
56
56
return false ;
@@ -64,7 +64,7 @@ bool isValidHost(std::string_view host) {
64
64
65
65
auto labels = split (hostname, ' .' );
66
66
67
- for (auto label: labels) {
67
+ for (auto label : labels) {
68
68
// Each label in a hostname can not be longer than 63 characters
69
69
// https://www.rfc-editor.org/rfc/rfc2181#section-11
70
70
if (label.length () > 63 ) {
@@ -89,7 +89,8 @@ bool isValidHost(std::string_view host) {
89
89
return false ;
90
90
}
91
91
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);
93
94
if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range) {
94
95
return false ;
95
96
}
@@ -346,11 +347,6 @@ bool Backend::set_target(JSContext *cx, JSObject *backend, JS::HandleValue targe
346
347
}
347
348
348
349
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
- }
354
350
JS::RootedValue request_url (cx, RequestOrResponse::url (request));
355
351
auto url_string = encode (cx, request_url);
356
352
if (!url_string.data ) {
@@ -363,12 +359,37 @@ JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
363
359
return nullptr ;
364
360
}
365
361
const jsurl::SpecSlice slice = jsurl::host (url);
362
+ std::string aaa ((char *)slice.data , slice.len );
366
363
auto nameStr = JS_NewStringCopyN (cx, (char *)slice.data , slice.len );
367
364
if (!nameStr) {
368
365
return nullptr ;
369
366
}
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
+
370
392
JS::RootedValue name (cx, JS::StringValue (nameStr));
371
- // The backend name provided was too long; please keep it to <255
372
393
if (!Backend::set_name (cx, backend, name)) {
373
394
return nullptr ;
374
395
}
@@ -388,6 +409,9 @@ JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
388
409
if (result.isErr ()) {
389
410
return nullptr ;
390
411
} else {
412
+ if (!JS_SetProperty (cx, Backend::backends, aaa.c_str (), backendVal)) {
413
+ return nullptr ;
414
+ }
391
415
return backend;
392
416
}
393
417
}
@@ -710,6 +734,11 @@ bool Backend::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
710
734
}
711
735
712
736
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);
713
742
return BuiltinImpl<Backend>::init_class_impl (cx, global);
714
743
}
715
744
0 commit comments