Wasm: Allow to set the HTTP response status.
This commit enables WebAssembly modules to set the HTTP response status to something other than the previously hard coded '200 OK'. To do this they can make a call to nxt_wasm_set_resp_status() providing the required status code. If this function isn't called the status code defaults to '200 OK'. The WebAssembly module can also return -1 from the request_handler function as a short cut to signal a '500 Internal Server Error'. Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
This commit is contained in:
@@ -102,6 +102,19 @@ nxt_wasm_send_headers(void *env, wasmtime_caller_t *caller,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static wasm_trap_t *
|
||||||
|
nxt_wasm_set_resp_status(void *env, wasmtime_caller_t *caller,
|
||||||
|
const wasmtime_val_t *args, size_t nargs,
|
||||||
|
wasmtime_val_t *results, size_t nresults)
|
||||||
|
{
|
||||||
|
nxt_wasm_ctx_t *ctx = env;
|
||||||
|
|
||||||
|
ctx->status = args[0].of.i32;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nxt_wasmtime_execute_hook(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook)
|
nxt_wasmtime_execute_hook(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook)
|
||||||
{
|
{
|
||||||
@@ -123,8 +136,8 @@ nxt_wasmtime_execute_hook(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static int
|
||||||
nxt_wasmtime_execute_request(const nxt_wasm_ctx_t *ctx)
|
nxt_wasmtime_execute_request(nxt_wasm_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
wasm_trap_t *trap = NULL;
|
wasm_trap_t *trap = NULL;
|
||||||
@@ -142,7 +155,10 @@ nxt_wasmtime_execute_request(const nxt_wasm_ctx_t *ctx)
|
|||||||
nxt_wasmtime_err_msg(error, trap,
|
nxt_wasmtime_err_msg(error, trap,
|
||||||
"failed to call function [->wasm_request_handler]"
|
"failed to call function [->wasm_request_handler]"
|
||||||
);
|
);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return results[0].of.i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,6 +199,11 @@ nxt_wasmtime_set_function_imports(nxt_wasm_ctx_t *ctx)
|
|||||||
.func = nxt_wasm_send_headers,
|
.func = nxt_wasm_send_headers,
|
||||||
.params = { WASM_I32 },
|
.params = { WASM_I32 },
|
||||||
.ft = NXT_WASM_FT_1_0
|
.ft = NXT_WASM_FT_1_0
|
||||||
|
}, {
|
||||||
|
.func_name = "nxt_wasm_set_resp_status",
|
||||||
|
.func = nxt_wasm_set_resp_status,
|
||||||
|
.params = { WASM_I32 },
|
||||||
|
.ft = NXT_WASM_FT_1_0
|
||||||
},
|
},
|
||||||
|
|
||||||
{ }
|
{ }
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ static nxt_wasm_ctx_t nxt_wasm_ctx;
|
|||||||
|
|
||||||
static const nxt_wasm_operations_t *nxt_wops;
|
static const nxt_wasm_operations_t *nxt_wops;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NXT_WASM_HTTP_OK = 200,
|
||||||
|
NXT_WASM_HTTP_ERROR = 500
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nxt_wasm_do_response_end(nxt_wasm_ctx_t *ctx)
|
nxt_wasm_do_response_end(nxt_wasm_ctx_t *ctx)
|
||||||
@@ -48,7 +53,7 @@ nxt_wasm_do_send_headers(nxt_wasm_ctx_t *ctx, uint32_t offset)
|
|||||||
fields_len += rh->fields[i].name_len + rh->fields[i].value_len;
|
fields_len += rh->fields[i].name_len + rh->fields[i].value_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxt_unit_response_init(ctx->req, 200, rh->nfields, fields_len);
|
nxt_unit_response_init(ctx->req, ctx->status, rh->nfields, fields_len);
|
||||||
|
|
||||||
for (i = 0; i < rh->nfields; i++) {
|
for (i = 0; i < rh->nfields; i++) {
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -72,7 +77,7 @@ nxt_wasm_do_send_response(nxt_wasm_ctx_t *ctx, uint32_t offset)
|
|||||||
nxt_unit_request_info_t *req = ctx->req;
|
nxt_unit_request_info_t *req = ctx->req;
|
||||||
|
|
||||||
if (!nxt_unit_response_is_init(req)) {
|
if (!nxt_unit_response_is_init(req)) {
|
||||||
nxt_unit_response_init(req, 200, 0, 0);
|
nxt_unit_response_init(req, ctx->status, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = (nxt_wasm_response_t *)(nxt_wasm_ctx.baddr + offset);
|
resp = (nxt_wasm_response_t *)(nxt_wasm_ctx.baddr + offset);
|
||||||
@@ -84,6 +89,7 @@ nxt_wasm_do_send_response(nxt_wasm_ctx_t *ctx, uint32_t offset)
|
|||||||
static void
|
static void
|
||||||
nxt_wasm_request_handler(nxt_unit_request_info_t *req)
|
nxt_wasm_request_handler(nxt_unit_request_info_t *req)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
size_t offset, read_bytes, content_sent, content_len;
|
size_t offset, read_bytes, content_sent, content_len;
|
||||||
ssize_t bytes_read;
|
ssize_t bytes_read;
|
||||||
nxt_unit_field_t *sf, *sf_end;
|
nxt_unit_field_t *sf, *sf_end;
|
||||||
@@ -149,8 +155,12 @@ nxt_wasm_request_handler(nxt_unit_request_info_t *req)
|
|||||||
|
|
||||||
wr->request_size = offset + bytes_read;
|
wr->request_size = offset + bytes_read;
|
||||||
|
|
||||||
|
nxt_wasm_ctx.status = NXT_WASM_HTTP_OK;
|
||||||
nxt_wasm_ctx.req = req;
|
nxt_wasm_ctx.req = req;
|
||||||
nxt_wops->exec_request(&nxt_wasm_ctx);
|
err = nxt_wops->exec_request(&nxt_wasm_ctx);
|
||||||
|
if (err) {
|
||||||
|
goto out_err_500;
|
||||||
|
}
|
||||||
|
|
||||||
if (content_len == content_sent) {
|
if (content_len == content_sent) {
|
||||||
goto request_done;
|
goto request_done;
|
||||||
@@ -168,9 +178,18 @@ nxt_wasm_request_handler(nxt_unit_request_info_t *req)
|
|||||||
wr->request_size = wr->content_sent = bytes_read;
|
wr->request_size = wr->content_sent = bytes_read;
|
||||||
wr->total_content_sent = content_sent;
|
wr->total_content_sent = content_sent;
|
||||||
|
|
||||||
nxt_wops->exec_request(&nxt_wasm_ctx);
|
err = nxt_wops->exec_request(&nxt_wasm_ctx);
|
||||||
|
if (err) {
|
||||||
|
goto out_err_500;
|
||||||
|
}
|
||||||
} while (content_sent < content_len);
|
} while (content_sent < content_len);
|
||||||
|
|
||||||
|
goto request_done;
|
||||||
|
|
||||||
|
out_err_500:
|
||||||
|
nxt_unit_response_init(req, NXT_WASM_HTTP_ERROR, 0, 0);
|
||||||
|
nxt_unit_request_done(req, NXT_UNIT_OK);
|
||||||
|
|
||||||
request_done:
|
request_done:
|
||||||
NXT_WASM_DO_HOOK(NXT_WASM_FH_REQUEST_END);
|
NXT_WASM_DO_HOOK(NXT_WASM_FH_REQUEST_END);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,12 +118,14 @@ struct nxt_wasm_ctx_s {
|
|||||||
size_t baddr_off;
|
size_t baddr_off;
|
||||||
|
|
||||||
size_t response_off;
|
size_t response_off;
|
||||||
|
|
||||||
|
uint16_t status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nxt_wasm_operations_s {
|
struct nxt_wasm_operations_s {
|
||||||
int (*init)(nxt_wasm_ctx_t *ctx);
|
int (*init)(nxt_wasm_ctx_t *ctx);
|
||||||
void (*destroy)(const nxt_wasm_ctx_t *ctx);
|
void (*destroy)(const nxt_wasm_ctx_t *ctx);
|
||||||
void (*exec_request)(const nxt_wasm_ctx_t *ctx);
|
int (*exec_request)(nxt_wasm_ctx_t *ctx);
|
||||||
void (*exec_hook)(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook);
|
void (*exec_hook)(const nxt_wasm_ctx_t *ctx, nxt_wasm_fh_t hook);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user