Skip to content

Commit 1ce77fa

Browse files
elliotttJakeChampion
authored andcommitted
Support request method get/set and version get in the host_api
1 parent 7d93254 commit 1ce77fa

File tree

6 files changed

+117
-40
lines changed

6 files changed

+117
-40
lines changed

runtime/js-compute-runtime/builtins/fetch-event.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "builtins/worker-location.h"
77
#include "host_interface/host_api.h"
88

9+
using namespace std::literals::string_view_literals;
10+
911
namespace builtins {
1012

1113
namespace {
@@ -77,33 +79,30 @@ JSObject *FetchEvent::prepare_downstream_request(JSContext *cx) {
7779
return Request::create(cx, requestInstance, HttpReq{}, HttpBody{}, true);
7880
}
7981

80-
bool FetchEvent::init_downstream_request(JSContext *cx, JS::HandleObject request,
81-
fastly_request_t *req) {
82+
bool FetchEvent::init_downstream_request(JSContext *cx, JS::HandleObject request, HttpReq req,
83+
HttpBody body) {
8284
MOZ_ASSERT(!Request::request_handle(request).is_valid());
8385

8486
fastly_error_t err;
8587

86-
fastly_request_handle_t request_handle = req->f0;
87-
fastly_body_handle_t body_handle = req->f1;
88-
8988
JS::SetReservedSlot(request, static_cast<uint32_t>(Request::Slots::Request),
90-
JS::Int32Value(request_handle));
89+
JS::Int32Value(req.handle));
9190
JS::SetReservedSlot(request, static_cast<uint32_t>(Request::Slots::Body),
92-
JS::Int32Value(body_handle));
91+
JS::Int32Value(body.handle));
9392

9493
// Set the method.
95-
fastly_world_string_t method_str;
96-
if (!fastly_http_req_method_get(request_handle, &method_str, &err)) {
97-
HANDLE_ERROR(cx, err);
94+
auto res = req.get_method();
95+
if (auto *err = res.to_err()) {
96+
HANDLE_ERROR(cx, *err);
9897
return false;
9998
}
10099

101-
bool is_get = strncmp(method_str.ptr, "GET", method_str.len) == 0;
102-
bool is_head = strncmp(method_str.ptr, "HEAD", method_str.len) == 0;
100+
auto method_str = std::move(res.unwrap());
101+
bool is_get = method_str == "GET"sv;
102+
bool is_head = method_str == "HEAD"sv;
103103

104104
if (!is_get) {
105-
JS::RootedString method(cx, JS_NewStringCopyN(cx, method_str.ptr, method_str.len));
106-
JS_free(cx, method_str.ptr);
105+
JS::RootedString method(cx, JS_NewStringCopyN(cx, method_str.ptr.release(), method_str.len));
107106
if (!method) {
108107
return false;
109108
}
@@ -121,7 +120,7 @@ bool FetchEvent::init_downstream_request(JSContext *cx, JS::HandleObject request
121120
}
122121

123122
fastly_world_string_t uri_str;
124-
if (!fastly_http_req_uri_get(request_handle, &uri_str, &err)) {
123+
if (!fastly_http_req_uri_get(req.handle, &uri_str, &err)) {
125124
HANDLE_ERROR(cx, err);
126125
return false;
127126
}
@@ -423,10 +422,10 @@ JSObject *FetchEvent::create(JSContext *cx) {
423422

424423
JS::HandleObject FetchEvent::instance() { return INSTANCE; }
425424

426-
bool FetchEvent::init_request(JSContext *cx, JS::HandleObject self, fastly_request_t *req) {
425+
bool FetchEvent::init_request(JSContext *cx, JS::HandleObject self, HttpReq req, HttpBody body) {
427426
JS::RootedObject request(
428427
cx, &JS::GetReservedSlot(self, static_cast<uint32_t>(Slots::Request)).toObject());
429-
return init_downstream_request(cx, request, req);
428+
return init_downstream_request(cx, request, req, body);
430429
}
431430

432431
bool FetchEvent::is_active(JSObject *self) {

runtime/js-compute-runtime/builtins/fetch-event.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "builtin.h"
55
#include "host_interface/fastly.h"
6+
#include "host_interface/host_api.h"
67

78
namespace builtins {
89

@@ -51,11 +52,11 @@ class FetchEvent final : public BuiltinNoConstructor<FetchEvent> {
5152
/**
5253
* Fully initialize the Request object based on the incoming request.
5354
*/
54-
static bool init_downstream_request(JSContext *cx, JS::HandleObject request,
55-
fastly_request_t *req);
55+
static bool init_downstream_request(JSContext *cx, JS::HandleObject request, HttpReq req,
56+
HttpBody body);
5657

5758
static bool respondWithError(JSContext *cx, JS::HandleObject self);
58-
static bool init_request(JSContext *cx, JS::HandleObject self, fastly_request_t *req);
59+
static bool init_request(JSContext *cx, JS::HandleObject self, HttpReq req, HttpBody body);
5960
static bool is_active(JSObject *self);
6061
static bool is_dispatching(JSObject *self);
6162
static void start_dispatching(JSObject *self);

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

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,14 +1217,13 @@ bool Request::url_get(JSContext *cx, unsigned argc, JS::Value *vp) {
12171217
bool Request::version_get(JSContext *cx, unsigned argc, JS::Value *vp) {
12181218
METHOD_HEADER(0)
12191219

1220-
fastly_error_t err;
1221-
fastly_http_version_t version = 0;
1222-
if (!fastly_http_req_version_get(request_handle(self).handle, &version, &err)) {
1223-
HANDLE_ERROR(cx, err);
1220+
auto res = request_handle(self).get_version();
1221+
if (auto *err = res.to_err()) {
1222+
HANDLE_ERROR(cx, *err);
12241223
return false;
12251224
}
12261225

1227-
args.rval().setInt32(version);
1226+
args.rval().setInt32(res.unwrap());
12281227
return true;
12291228
}
12301229

@@ -1753,10 +1752,9 @@ JSObject *Request::create(JSContext *cx, JS::HandleObject requestInstance, JS::H
17531752
is_get_or_head = strcmp(method.get(), "GET") == 0 || strcmp(method.get(), "HEAD") == 0;
17541753

17551754
JS::SetReservedSlot(request, static_cast<uint32_t>(Slots::Method), JS::StringValue(method_str));
1756-
fastly_world_string_t method_fastly_str = {method.get(), method_len};
1757-
fastly_error_t err;
1758-
if (!fastly_http_req_method_set(request_handle.handle, &method_fastly_str, &err)) {
1759-
HANDLE_ERROR(cx, err);
1755+
auto res = request_handle.set_method(std::string_view{method.get(), method_len});
1756+
if (auto *err = res.to_err()) {
1757+
HANDLE_ERROR(cx, *err);
17601758
return nullptr;
17611759
}
17621760
}
@@ -2224,14 +2222,13 @@ bool Response::url_get(JSContext *cx, unsigned argc, JS::Value *vp) {
22242222
bool Response::version_get(JSContext *cx, unsigned argc, JS::Value *vp) {
22252223
METHOD_HEADER(0)
22262224

2227-
fastly_http_version_t version = 0;
2228-
fastly_error_t err;
2229-
if (!fastly_http_resp_version_get(response_handle(self).handle, &version, &err)) {
2230-
HANDLE_ERROR(cx, err);
2225+
auto res = response_handle(self).get_version();
2226+
if (auto *err = res.to_err()) {
2227+
HANDLE_ERROR(cx, *err);
22312228
return false;
22322229
}
22332230

2234-
args.rval().setInt32(version);
2231+
args.rval().setInt32(res.unwrap());
22352232
return true;
22362233
}
22372234

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

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
#include "fastly-world/fastly_world.h"
55
#include "host_interface/host_api.h"
66

7+
namespace {
8+
9+
fastly_world_string_t string_view_to_world_string(std::string_view str) {
10+
return {
11+
.ptr = const_cast<char *>(str.data()),
12+
.len = str.size(),
13+
};
14+
}
15+
16+
} // namespace
17+
718
Result<HttpBody> HttpBody::make() {
819
Result<HttpBody> res;
920

@@ -121,7 +132,7 @@ Result<std::optional<std::vector<HostString>>> generic_get_header_values(auto ha
121132
std::string_view name) {
122133
Result<std::optional<std::vector<HostString>>> res;
123134

124-
fastly_world_string_t hdr{const_cast<char *>(name.data()), name.size()};
135+
fastly_world_string_t hdr = string_view_to_world_string(name);
125136
fastly_option_list_string_t ret;
126137
fastly_error_t err;
127138
if (!header_values_get(handle, &hdr, &ret, &err)) {
@@ -151,8 +162,8 @@ template <auto header_op>
151162
Result<Void> generic_header_op(auto handle, std::string_view name, std::string_view value) {
152163
Result<Void> res;
153164

154-
fastly_world_string_t hdr{const_cast<char *>(name.data()), name.size()};
155-
fastly_world_string_t val{const_cast<char *>(value.data()), value.size()};
165+
fastly_world_string_t hdr = string_view_to_world_string(name);
166+
fastly_world_string_t val = string_view_to_world_string(value);
156167
fastly_error_t err;
157168
if (!header_op(handle, &hdr, &val, &err)) {
158169
res.emplace_err(err);
@@ -165,7 +176,7 @@ template <auto remove_header>
165176
Result<Void> generic_header_remove(auto handle, std::string_view name) {
166177
Result<Void> res;
167178

168-
fastly_world_string_t hdr{const_cast<char *>(name.data()), name.size()};
179+
fastly_world_string_t hdr = string_view_to_world_string(name);
169180
fastly_error_t err;
170181
if (!remove_header(handle, &hdr, &err)) {
171182
res.emplace_err(err);
@@ -190,8 +201,48 @@ Result<HttpReq> HttpReq::make() {
190201
return res;
191202
}
192203

204+
Result<Void> HttpReq::set_method(std::string_view method) {
205+
Result<Void> res;
206+
207+
fastly_error_t err;
208+
fastly_world_string_t str = string_view_to_world_string(method);
209+
if (!fastly_http_req_method_set(this->handle, &str, &err)) {
210+
res.emplace_err(err);
211+
}
212+
213+
return res;
214+
}
215+
216+
Result<HostString> HttpReq::get_method() const {
217+
Result<HostString> res;
218+
219+
fastly_error_t err;
220+
fastly_world_string_t ret;
221+
if (!fastly_http_req_method_get(this->handle, &ret, &err)) {
222+
res.emplace_err(err);
223+
} else {
224+
res.emplace(ret);
225+
}
226+
227+
return res;
228+
}
229+
193230
bool HttpReq::is_valid() const { return this->handle != HttpReq::invalid; }
194231

232+
Result<fastly_http_version_t> HttpReq::get_version() const {
233+
Result<fastly_http_version_t> res;
234+
235+
fastly_error_t err;
236+
fastly_http_version_t ret;
237+
if (!fastly_http_req_version_get(this->handle, &ret, &err)) {
238+
res.emplace_err(err);
239+
} else {
240+
res.emplace(ret);
241+
}
242+
243+
return res;
244+
}
245+
195246
Result<std::vector<HostString>> HttpReq::get_header_names() {
196247
return generic_get_header_names<fastly_http_req_header_names_get>(this->handle);
197248
}
@@ -228,6 +279,20 @@ Result<HttpResp> HttpResp::make() {
228279

229280
bool HttpResp::is_valid() const { return this->handle != HttpResp::invalid; }
230281

282+
Result<fastly_http_version_t> HttpResp::get_version() const {
283+
Result<fastly_http_version_t> res;
284+
285+
fastly_error_t err;
286+
fastly_http_version_t ret;
287+
if (!fastly_http_resp_version_get(this->handle, &ret, &err)) {
288+
res.emplace_err(err);
289+
} else {
290+
res.emplace(ret);
291+
}
292+
293+
return res;
294+
}
295+
231296
Result<std::vector<HostString>> HttpResp::get_header_names() {
232297
return generic_get_header_names<fastly_http_resp_header_names_get>(this->handle);
233298
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ class HttpBase {
133133

134134
virtual bool is_valid() const = 0;
135135

136+
/// Get the http version used for this request.
137+
virtual Result<fastly_http_version_t> get_version() const = 0;
138+
136139
virtual Result<std::vector<HostString>> get_header_names() = 0;
137140
virtual Result<std::optional<std::vector<HostString>>>
138141
get_header_values(std::string_view name) = 0;
@@ -152,8 +155,18 @@ class HttpReq final : public HttpBase {
152155

153156
static Result<HttpReq> make();
154157

158+
/// Get the http version used for this request.
159+
160+
/// Set the request method.
161+
Result<Void> set_method(std::string_view method);
162+
163+
/// Get the request method.
164+
Result<HostString> get_method() const;
165+
155166
bool is_valid() const override;
156167

168+
Result<fastly_http_version_t> get_version() const override;
169+
157170
Result<std::vector<HostString>> get_header_names() override;
158171
Result<std::optional<std::vector<HostString>>> get_header_values(std::string_view name) override;
159172
Result<Void> insert_header(std::string_view name, std::string_view value) override;
@@ -174,6 +187,8 @@ class HttpResp final : public HttpBase {
174187

175188
bool is_valid() const override;
176189

190+
Result<fastly_http_version_t> get_version() const override;
191+
177192
Result<std::vector<HostString>> get_header_names() override;
178193
Result<std::optional<std::vector<HostString>>> get_header_values(std::string_view name) override;
179194
Result<Void> insert_header(std::string_view name, std::string_view value) override;

runtime/js-compute-runtime/js-compute-runtime.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "builtins/fetch-event.h"
2323
#include "core/allocator.h"
24+
#include "host_interface/host_api.h"
2425
#include "js-compute-builtins.h"
2526
#include "third_party/wizer.h"
2627
#ifdef MEM_STATS
@@ -488,8 +489,7 @@ bool js_compute_runtime_serve(js_compute_runtime_request_t *req) {
488489
js::ResetMathRandomSeed(cx);
489490

490491
HandleObject fetch_event = builtins::FetchEvent::instance();
491-
builtins::FetchEvent::init_request(cx, fetch_event,
492-
static_cast<fastly_request_t *>(static_cast<void *>(req)));
492+
builtins::FetchEvent::init_request(cx, fetch_event, HttpReq{req->f0}, HttpBody{req->f1});
493493

494494
dispatch_fetch_event(cx, fetch_event, &total_compute);
495495

0 commit comments

Comments
 (0)