Skip to content

Commit 2021237

Browse files
elliotttJakeChampion
authored andcommitted
Migrate Headers to the host_api
1 parent 99f8354 commit 2021237

File tree

4 files changed

+252
-74
lines changed

4 files changed

+252
-74
lines changed

c-dependencies/js-compute-runtime/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ CFLAGS += --sysroot=$(WASI_SDK)/share/wasi-sysroot
9393

9494
# Includes for compiling c++
9595
INCLUDES := -I$(FSM_SRC)
96-
INCLUDES += -I$(FSM_SRC)/c-at-e-world
9796
INCLUDES += -I$(SM_SRC)/include
9897
INCLUDES += -I$(BUILD)/openssl/include
9998

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

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "builtins/headers.h"
22
#include "builtins/request-response.h"
3-
#include "c-at-e-world/c_at_e_world.h"
43
#include "core/sequence.hpp"
4+
#include "host_interface/host_api.h"
55
#include "js-compute-builtins.h"
66

77
#include "js/Conversions.h"
@@ -243,28 +243,19 @@ bool append_header_value_to_map(JSContext *cx, JS::HandleObject self,
243243

244244
bool get_header_names_from_handle(JSContext *cx, uint32_t handle, Headers::Mode mode,
245245
JS::HandleObject backing_map) {
246-
JS::RootedString name(cx);
247-
JS::RootedValue name_val(cx);
248-
char *buf = static_cast<char *>(JS_malloc(cx, HOSTCALL_BUFFER_LEN));
249-
250-
bool ok;
251-
fastly_list_string_t ret;
252-
fastly_error_t err;
253-
if (mode == Headers::Mode::ProxyToRequest) {
254-
ok = fastly_http_req_header_names_get(handle, &ret, &err);
255-
} else {
256-
ok = fastly_http_resp_header_names_get(handle, &ret, &err);
257-
}
258246

259-
if (!ok) {
260-
HANDLE_ERROR(cx, err);
261-
JS_free(cx, buf);
247+
auto names = mode == Headers::Mode::ProxyToRequest ? HttpReq{handle}.get_header_names()
248+
: HttpResp{handle}.get_header_names();
249+
if (auto *err = names.to_err()) {
250+
HANDLE_ERROR(cx, *err);
262251
return false;
263252
}
264253

265-
for (size_t i = 0; i < ret.len; i++) {
266-
name = JS_NewStringCopyN(cx, ret.ptr[i].ptr, ret.ptr[i].len);
267-
JS_free(cx, ret.ptr[i].ptr);
254+
JS::RootedString name(cx);
255+
JS::RootedValue name_val(cx);
256+
for (auto &str : names.unwrap()) {
257+
// TODO: can `name` take ownership of the buffer here instead?
258+
name = JS_NewStringCopyN(cx, str.ptr.get(), str.len);
268259
if (!name) {
269260
return false;
270261
}
@@ -273,8 +264,6 @@ bool get_header_names_from_handle(JSContext *cx, uint32_t handle, Headers::Mode
273264
JS::MapSet(cx, backing_map, name_val, JS::NullHandleValue);
274265
}
275266

276-
JS_free(cx, buf);
277-
JS_free(cx, ret.ptr);
278267
return true;
279268
}
280269

@@ -284,41 +273,37 @@ bool retrieve_value_for_header_from_handle(JSContext *cx, JS::HandleObject self,
284273
MOZ_ASSERT(mode != Headers::Mode::Standalone);
285274
uint32_t handle = get_handle(self);
286275

287-
c_at_e_world_string_t str;
288276
JS::RootedString name_str(cx, name.toString());
289-
JS::UniqueChars name_chars = encode(cx, name_str, &str.len);
290-
str.ptr = name_chars.get();
291-
292-
fastly_option_list_string_t ret;
277+
size_t len;
278+
JS::UniqueChars name_chars = ::encode(cx, name_str, &len);
279+
std::string_view hdr{name_chars.get(), len};
293280

294-
bool ok;
295-
fastly_error_t err;
296-
if (mode == Headers::Mode::ProxyToRequest) {
297-
ok = fastly_http_req_header_values_get(handle, &str, &ret, &err);
298-
} else {
299-
ok = fastly_http_resp_header_values_get(handle, &str, &ret, &err);
300-
}
281+
auto ret = mode == Headers::Mode::ProxyToRequest ? HttpReq{handle}.get_header_values(hdr)
282+
: HttpResp{handle}.get_header_values(hdr);
301283

302-
if (!ok) {
303-
HANDLE_ERROR(cx, err);
284+
if (auto *err = ret.to_err()) {
285+
HANDLE_ERROR(cx, *err);
304286
return false;
305287
}
306288

307-
if (!ret.is_some)
289+
auto &values = ret.unwrap();
290+
if (!values.has_value()) {
308291
return true;
292+
}
309293

310294
JS::RootedString val_str(cx);
311-
for (size_t i = 0; i < ret.val.len; i++) {
312-
val_str = JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(ret.val.ptr[i].ptr, ret.val.ptr[i].len));
313-
JS_free(cx, ret.val.ptr[i].ptr);
314-
if (!val_str)
295+
for (auto &str : values.value()) {
296+
val_str = JS_NewStringCopyUTF8N(cx, JS::UTF8Chars(str.ptr.get(), str.len));
297+
if (!val_str) {
315298
return false;
299+
}
300+
316301
value.setString(val_str);
317-
if (!append_header_value_to_map(cx, self, name, value))
302+
if (!append_header_value_to_map(cx, self, name, value)) {
318303
return false;
304+
}
319305
}
320306

321-
JS_free(cx, ret.val.ptr);
322307
return true;
323308
}
324309

@@ -467,27 +452,25 @@ bool Headers::append_header_value(JSContext *cx, JS::HandleObject self, JS::Hand
467452

468453
auto mode = get_mode(self);
469454
if (mode != Headers::Mode::Standalone) {
470-
auto *op = mode == Headers::Mode::ProxyToRequest ? fastly_http_req_header_append
471-
: fastly_http_resp_header_append;
472-
std::string_view name(name_chars.get(), name_len);
455+
auto handle = get_handle(self);
456+
std::string_view name{name_chars.get(), name_len};
457+
std::string_view value(value_chars.get(), value_len);
473458
if (name == "set-cookie") {
474-
std::string_view value(value_chars.get(), value_len);
475-
auto values = splitCookiesString(value);
476-
for (auto value : values) {
477-
c_at_e_world_string_t name = {name_chars.get(), name_len};
478-
c_at_e_world_string_t val = {const_cast<char *>(value.data()), value.length()};
479-
fastly_error_t err;
480-
if (!op(get_handle(self), &name, &val, &err)) {
481-
HANDLE_ERROR(cx, err);
459+
for (auto value : splitCookiesString(value)) {
460+
auto res = mode == Headers::Mode::ProxyToRequest
461+
? HttpReq{handle}.append_header(name, value)
462+
: HttpResp{handle}.append_header(name, value);
463+
if (auto *err = res.to_err()) {
464+
HANDLE_ERROR(cx, *err);
482465
return false;
483466
}
484467
}
485468
} else {
486-
c_at_e_world_string_t name = {name_chars.get(), name_len};
487-
c_at_e_world_string_t val = {value_chars.get(), value_len};
488-
fastly_error_t err;
489-
if (!op(get_handle(self), &name, &val, &err)) {
490-
HANDLE_ERROR(cx, err);
469+
auto res = mode == Headers::Mode::ProxyToRequest
470+
? HttpReq{handle}.append_header(name, value)
471+
: HttpResp{handle}.append_header(name, value);
472+
if (auto *err = res.to_err()) {
473+
HANDLE_ERROR(cx, *err);
491474
return false;
492475
}
493476
}
@@ -591,13 +574,13 @@ bool Headers::set(JSContext *cx, unsigned argc, JS::Value *vp) {
591574

592575
auto mode = get_mode(self);
593576
if (mode != Mode::Standalone) {
594-
auto *op = mode == Mode::ProxyToRequest ? fastly_http_req_header_insert
595-
: fastly_http_resp_header_insert;
596-
c_at_e_world_string_t name = {name_chars.get(), name_len};
597-
c_at_e_world_string_t val = {value_chars.get(), value_len};
598-
fastly_error_t err;
599-
if (!op(get_handle(self), &name, &val, &err)) {
600-
HANDLE_ERROR(cx, err);
577+
auto handle = get_handle(self);
578+
std::string_view name{name_chars.get(), name_len};
579+
std::string_view val{value_chars.get(), value_len};
580+
auto res = mode == Mode::ProxyToRequest ? HttpReq{handle}.insert_header(name, val)
581+
: HttpResp{handle}.insert_header(name, val);
582+
if (auto *err = res.to_err()) {
583+
HANDLE_ERROR(cx, *err);
601584
return false;
602585
}
603586
}
@@ -681,12 +664,12 @@ bool Headers::delete_(JSContext *cx, unsigned argc, JS::Value *vp) {
681664

682665
auto mode = get_mode(self);
683666
if (mode != Headers::Mode::Standalone) {
684-
auto *op = mode == Mode::ProxyToRequest ? fastly_http_req_header_remove
685-
: fastly_http_resp_header_remove;
686-
c_at_e_world_string_t name = {name_chars.get(), name_len};
687-
fastly_error_t err;
688-
if (!op(get_handle(self), &name, &err)) {
689-
HANDLE_ERROR(cx, err);
667+
auto handle = get_handle(self);
668+
std::string_view name{name_chars.get(), name_len};
669+
auto res = mode == Mode::ProxyToRequest ? HttpReq{handle}.remove_header(name)
670+
: HttpResp{handle}.remove_header(name);
671+
if (auto *err = res.to_err()) {
672+
HANDLE_ERROR(cx, *err);
690673
return false;
691674
}
692675
}

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

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <algorithm>
22

3-
#include "c_at_e_world.h"
3+
#include "c-at-e-world/c_at_e_world.h"
4+
#include "core/allocator.h"
45
#include "host_interface/host_api.h"
56

67
Result<HttpBody> HttpBody::make() {
@@ -88,3 +89,129 @@ Result<Void> HttpBody::close() {
8889

8990
return res;
9091
}
92+
93+
namespace {
94+
95+
template <auto header_names_get>
96+
Result<std::vector<HostString>> generic_get_header_names(auto handle) {
97+
Result<std::vector<HostString>> res;
98+
99+
fastly_list_string_t ret;
100+
fastly_error_t err;
101+
if (!header_names_get(handle, &ret, &err)) {
102+
res.emplace_err(err);
103+
} else {
104+
std::vector<HostString> names;
105+
106+
for (int i = 0; i < ret.len; i++) {
107+
names.emplace_back(HostString{ret.ptr[i]});
108+
}
109+
110+
// Free the vector of string pointers, but leave the individual strings alone.
111+
cabi_free(ret.ptr);
112+
113+
res.emplace(std::move(names));
114+
}
115+
116+
return res;
117+
}
118+
119+
template <auto header_values_get>
120+
Result<std::optional<std::vector<HostString>>> generic_get_header_values(auto handle,
121+
std::string_view name) {
122+
Result<std::optional<std::vector<HostString>>> res;
123+
124+
c_at_e_world_string_t hdr{const_cast<char *>(name.data()), name.size()};
125+
fastly_option_list_string_t ret;
126+
fastly_error_t err;
127+
if (!header_values_get(handle, &hdr, &ret, &err)) {
128+
res.emplace_err(err);
129+
} else {
130+
131+
if (ret.is_some) {
132+
std::vector<HostString> names;
133+
134+
for (int i = 0; i < ret.val.len; i++) {
135+
names.emplace_back(HostString{ret.val.ptr[i]});
136+
}
137+
138+
// Free the vector of string pointers, but leave the individual strings alone.
139+
cabi_free(ret.val.ptr);
140+
141+
res.emplace(std::move(names));
142+
} else {
143+
res.emplace(std::nullopt);
144+
}
145+
}
146+
147+
return res;
148+
}
149+
150+
template <auto header_op>
151+
Result<Void> generic_header_op(auto handle, std::string_view name, std::string_view value) {
152+
Result<Void> res;
153+
154+
c_at_e_world_string_t hdr{const_cast<char *>(name.data()), name.size()};
155+
c_at_e_world_string_t val{const_cast<char *>(value.data()), value.size()};
156+
fastly_error_t err;
157+
if (!header_op(handle, &hdr, &val, &err)) {
158+
res.emplace_err(err);
159+
}
160+
161+
return res;
162+
}
163+
164+
template <auto remove_header>
165+
Result<Void> generic_header_remove(auto handle, std::string_view name) {
166+
Result<Void> res;
167+
168+
c_at_e_world_string_t hdr{const_cast<char *>(name.data()), name.size()};
169+
fastly_error_t err;
170+
if (!remove_header(handle, &hdr, &err)) {
171+
res.emplace_err(err);
172+
}
173+
174+
return res;
175+
}
176+
177+
} // namespace
178+
179+
Result<std::vector<HostString>> HttpReq::get_header_names() {
180+
return generic_get_header_names<fastly_http_req_header_names_get>(this->handle);
181+
}
182+
183+
Result<std::optional<std::vector<HostString>>> HttpReq::get_header_values(std::string_view name) {
184+
return generic_get_header_values<fastly_http_req_header_values_get>(this->handle, name);
185+
}
186+
187+
Result<Void> HttpReq::insert_header(std::string_view name, std::string_view value) {
188+
return generic_header_op<fastly_http_req_header_insert>(this->handle, name, value);
189+
}
190+
191+
Result<Void> HttpReq::append_header(std::string_view name, std::string_view value) {
192+
return generic_header_op<fastly_http_req_header_append>(this->handle, name, value);
193+
}
194+
195+
Result<Void> HttpReq::remove_header(std::string_view name) {
196+
return generic_header_remove<fastly_http_req_header_remove>(this->handle, name);
197+
}
198+
199+
Result<std::vector<HostString>> HttpResp::get_header_names() {
200+
return generic_get_header_names<fastly_http_resp_header_names_get>(this->handle);
201+
}
202+
203+
Result<std::optional<std::vector<HostString>>> HttpResp::get_header_values(std::string_view name) {
204+
return generic_get_header_values<fastly_http_resp_header_values_get>(this->handle, name);
205+
}
206+
207+
Result<Void> HttpResp::insert_header(std::string_view name, std::string_view value) {
208+
return generic_header_op<fastly_http_resp_header_insert>(this->handle, name, value);
209+
}
210+
211+
Result<Void> HttpResp::append_header(std::string_view name, std::string_view value) {
212+
return generic_header_op<fastly_http_resp_header_append>(this->handle, name, value);
213+
}
214+
215+
Result<Void> HttpResp::remove_header(std::string_view name) {
216+
return generic_header_remove<fastly_http_resp_header_remove>(this->handle, name);
217+
}

0 commit comments

Comments
 (0)