@@ -54,6 +54,7 @@ JS::PersistentRooted<JSString *> Fastly::defaultBackend;
5454bool allowDynamicBackendsCalled = false ;
5555bool Fastly::allowDynamicBackends = true ;
5656bool ENABLE_EXPERIMENTAL_HTTP_CACHE = false ;
57+ ReusableSandboxOptions Fastly::reusableSandboxOptions{};
5758
5859bool Fastly::dump (JSContext *cx, unsigned argc, JS::Value *vp) {
5960 JS::CallArgs args = CallArgsFromVp (argc, vp);
@@ -682,6 +683,86 @@ bool Fastly::allowDynamicBackends_set(JSContext *cx, unsigned argc, JS::Value *v
682683 return true ;
683684}
684685
686+ bool Fastly::setReusableSandboxOptions (JSContext *cx, unsigned argc, JS::Value *vp) {
687+ JS::CallArgs args = CallArgsFromVp (argc, vp);
688+ if (Fastly::reusableSandboxOptions.frozen ()) {
689+ JS_ReportErrorUTF8 (cx, " Reusable sandbox options can only be set at initialization time" );
690+ return false ;
691+ }
692+ if (!args.requireAtLeast (cx, " fastly.setReusableSandboxOptions" , 1 )) {
693+ return false ;
694+ }
695+ JS::HandleValue options_value = args.get (0 );
696+ if (!options_value.isObject ()) {
697+ JS_ReportErrorUTF8 (cx, " Options parameter must be an object" );
698+ return false ;
699+ }
700+ RootedObject options_obj (cx, &options_value.toObject ());
701+
702+ auto get_non_negative_int = [cx, &options_obj](const char * prop_name, bool * defined , int32_t * out_value) -> bool {
703+ RootedValue val (cx);
704+ if (!JS_GetProperty (cx, options_obj, prop_name, &val)) {
705+ return false ;
706+ }
707+ if (val.isUndefined ()) {
708+ *defined = false ;
709+ return true ;
710+ }
711+ *defined = true ;
712+ if (!val.isInt32 ()) {
713+ JS_ReportErrorUTF8 (cx, " %s option must be an integer" , prop_name);
714+ return false ;
715+ }
716+ int32_t int_val = val.toInt32 ();
717+ if (int_val < 0 ) {
718+ JS_ReportErrorUTF8 (cx, " %s option must be a non-negative integer" , prop_name);
719+ return false ;
720+ }
721+ *out_value = int_val;
722+ return true ;
723+ };
724+
725+ bool defined = false ;
726+ int32_t max_requests;
727+ if (get_non_negative_int (" maxRequests" , &defined , &max_requests)) {
728+ if (defined ) {
729+ Fastly::reusableSandboxOptions.set_max_requests (max_requests);
730+ }
731+ } else {
732+ return false ;
733+ }
734+
735+ int32_t between_request_timeout_ms;
736+ if (get_non_negative_int (" betweenRequestTimeoutMs" , &defined , &between_request_timeout_ms)) {
737+ if (defined ) {
738+ Fastly::reusableSandboxOptions.set_between_request_timeout (std::chrono::milliseconds (between_request_timeout_ms));
739+ }
740+ } else {
741+ return false ;
742+ }
743+
744+ int32_t max_memory_mib;
745+ if (get_non_negative_int (" maxMemoryMiB" , &defined , &max_memory_mib)) {
746+ if (defined ) {
747+ Fastly::reusableSandboxOptions.set_max_memory_mib (max_memory_mib);
748+ }
749+ } else {
750+ return false ;
751+ }
752+
753+ int32_t sandbox_timeout_ms;
754+ if (get_non_negative_int (" sandboxTimeoutMs" , &defined , &sandbox_timeout_ms)) {
755+ if (defined ) {
756+ Fastly::reusableSandboxOptions.set_sandbox_timeout (std::chrono::milliseconds (sandbox_timeout_ms));
757+ }
758+ } else {
759+ return false ;
760+ }
761+
762+ args.rval ().setUndefined ();
763+ return true ;
764+ }
765+
685766const JSPropertySpec Fastly::properties[] = {
686767 JS_PSG (" env" , env_get, JSPROP_ENUMERATE),
687768 JS_PSGS (" baseURL" , baseURL_get, baseURL_set, JSPROP_ENUMERATE),
@@ -731,6 +812,7 @@ bool install(api::Engine *engine) {
731812 JS_FN (" includeBytes" , Fastly::includeBytes, 1 , JSPROP_ENUMERATE),
732813 JS_FN (" createFanoutHandoff" , Fastly::createFanoutHandoff, 2 , JSPROP_ENUMERATE),
733814 JS_FN (" createWebsocketHandoff" , Fastly::createWebsocketHandoff, 2 , JSPROP_ENUMERATE),
815+ JS_FN (" setReusableSandboxOptions" , Fastly::setReusableSandboxOptions, 1 , JSPROP_ENUMERATE),
734816 ENABLE_EXPERIMENTAL_HIGH_RESOLUTION_TIME_METHODS ? nowfn : end,
735817 end};
736818
@@ -830,6 +912,17 @@ bool install(api::Engine *engine) {
830912 allow_dynamic_backends_val)) {
831913 return false ;
832914 }
915+ auto set_reusable_sandbox_options =
916+ JS_NewFunction (engine->cx (), &Fastly::setReusableSandboxOptions, 1 , 0 ,
917+ " setReusableSandboxOptions" );
918+ RootedObject set_reusable_sandbox_options_obj (engine->cx (),
919+ JS_GetFunctionObject (set_reusable_sandbox_options));
920+ RootedValue set_reusable_sandbox_options_val (
921+ engine->cx (), ObjectValue (*set_reusable_sandbox_options_obj));
922+ if (!JS_SetProperty (engine->cx (), experimental, " setReusableSandboxOptions" ,
923+ set_reusable_sandbox_options_val)) {
924+ return false ;
925+ }
833926 RootedString version_str (
834927 engine->cx (), JS_NewStringCopyN (engine->cx (), RUNTIME_VERSION, strlen (RUNTIME_VERSION)));
835928 RootedValue version_str_val (engine->cx (), StringValue (version_str));
0 commit comments