Skip to content

Commit fefe8b7

Browse files
elliotttJakeChampion
authored andcommitted
Support overrideContentLength on request and response init params
1 parent 4f39943 commit fefe8b7

File tree

5 files changed

+113
-1
lines changed

5 files changed

+113
-1
lines changed

runtime/js-compute-runtime/builtins/request-response.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1655,14 +1655,26 @@ JSObject *Request::create(JSContext *cx, JS::HandleObject requestInstance, JS::H
16551655
JS::RootedValue fastly_val(cx);
16561656
if (init_val.isObject()) {
16571657
JS::RootedObject init(cx, init_val.toObjectOrNull());
1658+
JS::RootedValue overrideContentLength(cx);
16581659
if (!JS_GetProperty(cx, init, "method", &method_val) ||
16591660
!JS_GetProperty(cx, init, "headers", &headers_val) ||
16601661
!JS_GetProperty(cx, init, "body", &body_val) ||
16611662
!JS_GetProperty(cx, init, "backend", &backend_val) ||
16621663
!JS_GetProperty(cx, init, "cacheOverride", &cache_override) ||
1663-
!JS_GetProperty(cx, init, "fastly", &fastly_val)) {
1664+
!JS_GetProperty(cx, init, "fastly", &fastly_val) ||
1665+
!JS_GetProperty(cx, init, "overrideContentLength", &overrideContentLength)) {
16641666
return nullptr;
16651667
}
1668+
1669+
if (overrideContentLength.isBoolean() && overrideContentLength.toBoolean()) {
1670+
auto res = request_handle.set_framing_headers_mode(
1671+
host_api::FramingHeadersMode::ManuallyFromHeaders);
1672+
if (auto *err = res.to_err()) {
1673+
HANDLE_ERROR(cx, *err);
1674+
return nullptr;
1675+
}
1676+
}
1677+
16661678
} else if (!init_val.isNullOrUndefined()) {
16671679
JS_ReportErrorLatin1(cx, "Request constructor: |init| parameter can't be converted to "
16681680
"a dictionary");
@@ -2643,6 +2655,7 @@ bool Response::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
26432655
JS::RootedValue statusText_val(cx);
26442656
JS::RootedString statusText(cx, JS_GetEmptyString(cx));
26452657
JS::RootedValue headers_val(cx);
2658+
host_api::FramingHeadersMode mode{host_api::FramingHeadersMode::Automatic};
26462659

26472660
if (init_val.isObject()) {
26482661
JS::RootedObject init(cx, init_val.toObjectOrNull());
@@ -2687,6 +2700,16 @@ bool Response::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
26872700
statusText = JS_NewStringCopyZ(cx, status_text.c_str());
26882701
}
26892702

2703+
JS::RootedValue overrideContentLength(cx);
2704+
if (!JS_GetProperty(cx, init, "overrideContentLength", &overrideContentLength)) {
2705+
return false;
2706+
}
2707+
2708+
// `overrideContentLength: true` indicates that we want to set the framing mode manually.
2709+
if (overrideContentLength.isBoolean() && overrideContentLength.toBoolean()) {
2710+
mode = host_api::FramingHeadersMode::ManuallyFromHeaders;
2711+
}
2712+
26902713
} else if (!init_val.isNullOrUndefined()) {
26912714
JS_ReportErrorLatin1(cx, "Response constructor: |init| parameter can't be converted to "
26922715
"a dictionary");
@@ -2727,6 +2750,14 @@ bool Response::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
27272750
}
27282751

27292752
auto response_handle = response_handle_res.unwrap();
2753+
if (mode != host_api::FramingHeadersMode::Automatic) {
2754+
auto res = response_handle.set_framing_headers_mode(mode);
2755+
if (auto *err = res.to_err()) {
2756+
HANDLE_ERROR(cx, *err);
2757+
return false;
2758+
}
2759+
}
2760+
27302761
auto body = make_res.unwrap();
27312762
JS::RootedObject responseInstance(cx, JS_NewObjectForConstructor(cx, &class_, args));
27322763
JS::RootedObject response(

runtime/js-compute-runtime/host_interface/component/fastly_world_adapter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,13 @@ bool fastly_compute_at_edge_http_req_header_values_get(
398398
return true;
399399
}
400400

401+
bool fastly_compute_at_edge_http_req_framing_headers_mode_set(
402+
fastly_compute_at_edge_http_req_request_handle_t h,
403+
fastly_compute_at_edge_http_req_framing_headers_mode_t mode,
404+
fastly_compute_at_edge_http_req_error_t *err) {
405+
return convert_result(fastly::req_framing_headers_mode_set(h, mode), err);
406+
}
407+
401408
bool fastly_compute_at_edge_http_req_header_insert(
402409
fastly_compute_at_edge_http_types_request_handle_t h, fastly_world_string_t *name,
403410
fastly_world_string_t *value, fastly_compute_at_edge_types_error_t *err) {
@@ -701,6 +708,13 @@ bool fastly_compute_at_edge_http_resp_version_get(
701708
return true;
702709
}
703710

711+
bool fastly_compute_at_edge_http_resp_framing_headers_mode_set(
712+
fastly_compute_at_edge_http_resp_response_handle_t h,
713+
fastly_compute_at_edge_http_resp_framing_headers_mode_t mode,
714+
fastly_compute_at_edge_http_resp_error_t *err) {
715+
return convert_result(fastly::resp_framing_headers_mode_set(h, mode), err);
716+
}
717+
704718
bool fastly_compute_at_edge_http_resp_send_downstream(
705719
fastly_compute_at_edge_http_types_response_handle_t h,
706720
fastly_compute_at_edge_http_types_body_handle_t b, bool streaming,

runtime/js-compute-runtime/host_interface/fastly.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ WASM_IMPORT("fastly_http_req", "version_set")
239239
int req_version_set(fastly_compute_at_edge_http_types_request_handle_t req_handle,
240240
uint32_t version);
241241

242+
WASM_IMPORT("fastly_http_req", "framing_headers_mode_set")
243+
int req_framing_headers_mode_set(fastly_compute_at_edge_http_types_request_handle_t req_handle,
244+
uint32_t mode);
245+
242246
WASM_IMPORT("fastly_http_req", "send")
243247
int req_send(fastly_compute_at_edge_http_types_request_handle_t req_handle,
244248
fastly_compute_at_edge_http_types_body_handle_t body_handle, const char *backend,
@@ -330,6 +334,10 @@ WASM_IMPORT("fastly_http_resp", "status_set")
330334
int resp_status_set(fastly_compute_at_edge_http_types_response_handle_t resp_handle,
331335
uint16_t status);
332336

337+
WASM_IMPORT("fastly_http_resp", "framing_headers_mode_set")
338+
int resp_framing_headers_mode_set(fastly_compute_at_edge_http_types_response_handle_t resp_handle,
339+
uint32_t mode);
340+
333341
// Module fastly_dictionary
334342
WASM_IMPORT("fastly_dictionary", "open")
335343
int dictionary_open(const char *name, size_t name_len,

runtime/js-compute-runtime/host_interface/host_api.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,30 @@ Result<Void> HttpReq::cache_override(CacheOverrideTag tag, std::optional<uint32_
736736
return res;
737737
}
738738

739+
Result<Void> HttpReq::set_framing_headers_mode(FramingHeadersMode mode) {
740+
Result<Void> res;
741+
742+
fastly_compute_at_edge_http_req_framing_headers_mode_t m;
743+
744+
switch (mode) {
745+
case FramingHeadersMode::Automatic:
746+
m = FASTLY_COMPUTE_AT_EDGE_HTTP_TYPES_FRAMING_HEADERS_MODE_AUTOMATIC;
747+
break;
748+
case FramingHeadersMode::ManuallyFromHeaders:
749+
m = FASTLY_COMPUTE_AT_EDGE_HTTP_TYPES_FRAMING_HEADERS_MODE_MANUALLY_FROM_HEADERS;
750+
break;
751+
}
752+
753+
fastly_compute_at_edge_types_error_t err;
754+
if (!fastly_compute_at_edge_http_req_framing_headers_mode_set(this->handle, m, &err)) {
755+
res.emplace_err(err);
756+
} else {
757+
res.emplace();
758+
}
759+
760+
return res;
761+
}
762+
739763
Result<HostBytes> HttpReq::downstream_client_ip_addr() {
740764
Result<HostBytes> res;
741765

@@ -919,6 +943,30 @@ Result<Void> HttpResp::send_downstream(HttpBody body, bool streaming) {
919943
return res;
920944
}
921945

946+
Result<Void> HttpResp::set_framing_headers_mode(FramingHeadersMode mode) {
947+
Result<Void> res;
948+
949+
fastly_compute_at_edge_http_resp_framing_headers_mode_t m;
950+
951+
switch (mode) {
952+
case FramingHeadersMode::Automatic:
953+
m = FASTLY_COMPUTE_AT_EDGE_HTTP_TYPES_FRAMING_HEADERS_MODE_AUTOMATIC;
954+
break;
955+
case FramingHeadersMode::ManuallyFromHeaders:
956+
m = FASTLY_COMPUTE_AT_EDGE_HTTP_TYPES_FRAMING_HEADERS_MODE_MANUALLY_FROM_HEADERS;
957+
break;
958+
}
959+
960+
fastly_compute_at_edge_types_error_t err;
961+
if (!fastly_compute_at_edge_http_resp_framing_headers_mode_set(this->handle, m, &err)) {
962+
res.emplace_err(err);
963+
} else {
964+
res.emplace();
965+
}
966+
967+
return res;
968+
}
969+
922970
bool HttpResp::is_valid() const { return this->handle != HttpResp::invalid; }
923971

924972
Result<fastly_compute_at_edge_http_types_http_version_t> HttpResp::get_version() const {

runtime/js-compute-runtime/host_interface/host_api.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ struct CacheOverrideTag final {
402402
void set_pci();
403403
};
404404

405+
enum class FramingHeadersMode : uint8_t {
406+
Automatic,
407+
ManuallyFromHeaders,
408+
};
409+
405410
struct Request;
406411

407412
class HttpReq final : public HttpBase {
@@ -468,6 +473,9 @@ class HttpReq final : public HttpBase {
468473
std::optional<uint32_t> stale_while_revalidate,
469474
std::optional<std::string_view> surrogate_key);
470475

476+
/// Set the framing headers mode for this request.
477+
Result<Void> set_framing_headers_mode(FramingHeadersMode mode);
478+
471479
bool is_valid() const override;
472480

473481
Result<HttpVersion> get_version() const override;
@@ -501,6 +509,9 @@ class HttpResp final : public HttpBase {
501509
/// Immediately begin sending this response to the downstream client.
502510
Result<Void> send_downstream(HttpBody body, bool streaming);
503511

512+
/// Set the framing headers mode for this response.
513+
Result<Void> set_framing_headers_mode(FramingHeadersMode mode);
514+
504515
bool is_valid() const override;
505516

506517
Result<HttpVersion> get_version() const override;

0 commit comments

Comments
 (0)