From 08922ef22dbcbd8fa493b4d1385a94e7d7eef028 Mon Sep 17 00:00:00 2001 From: Carl Niklas Rydberg Date: Mon, 22 Dec 2025 19:10:14 +0100 Subject: [PATCH] Add /v1/pel/run endpoint --- .gitignore | 2 + CMakeLists.txt | 3 +- README.md | 11 + src/amduatd.c | 766 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 781 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 99142bc..9e89508 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /build/ *.sock +.amduat-asl/ +artifact.bin diff --git a/CMakeLists.txt b/CMakeLists.txt index d640e9e..4597847 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,5 +15,6 @@ target_include_directories(amduatd ) target_link_libraries(amduatd - PRIVATE amduat_asl_store_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util + PRIVATE amduat_pel amduat_format amduat_asl_store_fs amduat_asl amduat_enc + amduat_hash_asl1 amduat_util ) diff --git a/README.md b/README.md index 377b0f7..59de98e 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,14 @@ curl --unix-socket amduatd.sock \ 'http://localhost/v1/artifacts/?format=artifact' --output artifact.bin ``` +Run a PEL program from store-backed refs (default `scheme_ref=dag`): + +```sh +curl --unix-socket amduatd.sock -X POST http://localhost/v1/pel/run \ + -H 'Content-Type: application/json' \ + -d '{"program_ref":"","input_refs":[""],"params_ref":""}' +``` + ## Current endpoints - `GET /v1/meta` → `{store_id, encoding_profile_id, hash_id}` @@ -67,6 +75,9 @@ curl --unix-socket amduatd.sock \ - `GET|HEAD /v1/artifacts/{ref}` - raw bytes default - artifact framing: `?format=artifact` +- `POST /v1/pel/run` + - request: `{program_ref, input_refs[], params_ref?, scheme_ref?}` (refs are hex strings; omit `scheme_ref` to use `dag`) + - response: `{result_ref, trace_ref?, output_refs[], status}` ## Notes diff --git a/src/amduatd.c b/src/amduatd.c index f501300..64e5cfc 100644 --- a/src/amduatd.c +++ b/src/amduatd.c @@ -6,6 +6,10 @@ #include "amduat/asl/ref_text.h" #include "amduat/asl/store.h" #include "amduat/enc/asl1_core_codec.h" +#include "amduat/enc/pel1_result.h" +#include "amduat/format/pel.h" +#include "amduat/pel/program_dag_desc.h" +#include "amduat/pel/run.h" #include #include @@ -288,6 +292,364 @@ static const char *amduatd_query_param(const char *path, return NULL; } +typedef struct { + char *data; + size_t len; + size_t cap; +} amduatd_strbuf_t; + +static void amduatd_strbuf_free(amduatd_strbuf_t *b) { + if (b == NULL) { + return; + } + free(b->data); + b->data = NULL; + b->len = 0; + b->cap = 0; +} + +static bool amduatd_strbuf_reserve(amduatd_strbuf_t *b, size_t extra) { + size_t need; + size_t next_cap; + char *next; + + if (b == NULL) { + return false; + } + if (extra > (SIZE_MAX - b->len)) { + return false; + } + need = b->len + extra; + if (need <= b->cap) { + return true; + } + next_cap = b->cap != 0 ? b->cap : 256u; + while (next_cap < need) { + if (next_cap > (SIZE_MAX / 2u)) { + next_cap = need; + break; + } + next_cap *= 2u; + } + next = (char *)realloc(b->data, next_cap); + if (next == NULL) { + return false; + } + b->data = next; + b->cap = next_cap; + return true; +} + +static bool amduatd_strbuf_append(amduatd_strbuf_t *b, + const char *s, + size_t n) { + if (b == NULL) { + return false; + } + if (n == 0) { + return true; + } + if (s == NULL) { + return false; + } + if (!amduatd_strbuf_reserve(b, n + 1u)) { + return false; + } + memcpy(b->data + b->len, s, n); + b->len += n; + b->data[b->len] = '\0'; + return true; +} + +static bool amduatd_strbuf_append_cstr(amduatd_strbuf_t *b, const char *s) { + return amduatd_strbuf_append(b, s != NULL ? s : "", s != NULL ? strlen(s) : 0u); +} + +static bool amduatd_strbuf_append_char(amduatd_strbuf_t *b, char c) { + return amduatd_strbuf_append(b, &c, 1u); +} + +static const char *amduatd_json_skip_ws(const char *p, const char *end) { + while (p < end) { + char c = *p; + if (c != ' ' && c != '\t' && c != '\n' && c != '\r') { + break; + } + p++; + } + return p; +} + +static bool amduatd_json_expect(const char **p, + const char *end, + char expected) { + const char *cur; + if (p == NULL || *p == NULL) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur >= end || *cur != expected) { + return false; + } + *p = cur + 1; + return true; +} + +static bool amduatd_json_parse_string_noesc(const char **p, + const char *end, + const char **out_start, + size_t *out_len) { + const char *cur; + const char *s; + if (out_start != NULL) { + *out_start = NULL; + } + if (out_len != NULL) { + *out_len = 0; + } + if (p == NULL || *p == NULL) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur >= end || *cur != '"') { + return false; + } + cur++; + s = cur; + while (cur < end) { + unsigned char c = (unsigned char)*cur; + if (c == '"') { + if (out_start != NULL) { + *out_start = s; + } + if (out_len != NULL) { + *out_len = (size_t)(cur - s); + } + *p = cur + 1; + return true; + } + if (c == '\\' || c < 0x20u) { + return false; + } + cur++; + } + return false; +} + +static bool amduatd_json_skip_string(const char **p, const char *end) { + const char *cur; + if (p == NULL || *p == NULL) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur >= end || *cur != '"') { + return false; + } + cur++; + while (cur < end) { + unsigned char c = (unsigned char)*cur++; + if (c == '"') { + *p = cur; + return true; + } + if (c == '\\') { + if (cur >= end) { + return false; + } + cur++; + } else if (c < 0x20u) { + return false; + } + } + return false; +} + +static bool amduatd_json_skip_value(const char **p, + const char *end, + int depth); + +static bool amduatd_json_skip_array(const char **p, + const char *end, + int depth) { + const char *cur; + if (!amduatd_json_expect(p, end, '[')) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur < end && *cur == ']') { + *p = cur + 1; + return true; + } + for (;;) { + if (!amduatd_json_skip_value(p, end, depth + 1)) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur >= end) { + return false; + } + if (*cur == ',') { + *p = cur + 1; + continue; + } + if (*cur == ']') { + *p = cur + 1; + return true; + } + return false; + } +} + +static bool amduatd_json_skip_object(const char **p, + const char *end, + int depth) { + const char *cur; + if (!amduatd_json_expect(p, end, '{')) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur < end && *cur == '}') { + *p = cur + 1; + return true; + } + for (;;) { + if (!amduatd_json_skip_string(p, end)) { + return false; + } + if (!amduatd_json_expect(p, end, ':')) { + return false; + } + if (!amduatd_json_skip_value(p, end, depth + 1)) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur >= end) { + return false; + } + if (*cur == ',') { + *p = cur + 1; + continue; + } + if (*cur == '}') { + *p = cur + 1; + return true; + } + return false; + } +} + +static bool amduatd_json_skip_value(const char **p, + const char *end, + int depth) { + const char *cur; + if (p == NULL || *p == NULL) { + return false; + } + if (depth > 32) { + return false; + } + cur = amduatd_json_skip_ws(*p, end); + if (cur >= end) { + return false; + } + if (*cur == '"') { + return amduatd_json_skip_string(p, end); + } + if (*cur == '{') { + return amduatd_json_skip_object(p, end, depth); + } + if (*cur == '[') { + return amduatd_json_skip_array(p, end, depth); + } + if (*cur == 't' && (end - cur) >= 4 && memcmp(cur, "true", 4) == 0) { + *p = cur + 4; + return true; + } + if (*cur == 'f' && (end - cur) >= 5 && memcmp(cur, "false", 5) == 0) { + *p = cur + 5; + return true; + } + if (*cur == 'n' && (end - cur) >= 4 && memcmp(cur, "null", 4) == 0) { + *p = cur + 4; + return true; + } + if (*cur == '-' || (*cur >= '0' && *cur <= '9')) { + cur++; + while (cur < end) { + char c = *cur; + if ((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E' || + c == '+' || c == '-') { + cur++; + continue; + } + break; + } + *p = cur; + return true; + } + return false; +} + +static bool amduatd_copy_json_str(const char *s, + size_t len, + char **out) { + char *buf; + if (out == NULL) { + return false; + } + *out = NULL; + if (len > (SIZE_MAX - 1u)) { + return false; + } + buf = (char *)malloc(len + 1u); + if (buf == NULL) { + return false; + } + if (len != 0) { + memcpy(buf, s, len); + } + buf[len] = '\0'; + *out = buf; + return true; +} + +static bool amduatd_decode_ref_hex_str(const char *s, + size_t len, + amduat_reference_t *out_ref) { + char *tmp = NULL; + bool ok; + if (out_ref == NULL) { + return false; + } + memset(out_ref, 0, sizeof(*out_ref)); + if (!amduatd_copy_json_str(s, len, &tmp)) { + return false; + } + ok = amduat_asl_ref_decode_hex(tmp, out_ref); + free(tmp); + return ok; +} + +static bool amduatd_send_json_error(int fd, + int code, + const char *reason, + const char *msg) { + amduatd_strbuf_t b; + memset(&b, 0, sizeof(b)); + if (!amduatd_strbuf_append_cstr(&b, "{\"error\":\"") || + !amduatd_strbuf_append_cstr(&b, msg != NULL ? msg : "error") || + !amduatd_strbuf_append_cstr(&b, "\"}\n")) { + amduatd_strbuf_free(&b); + return amduatd_http_send_text(fd, 500, "Internal Server Error", "error\n", + false); + } + { + bool ok = amduatd_http_send_json(fd, code, reason, b.data, false); + amduatd_strbuf_free(&b); + return ok; + } +} + static void amduatd_path_without_query(const char *path, char *out, size_t cap) { @@ -541,6 +903,407 @@ static bool amduatd_handle_post_artifacts(int fd, } } +static bool amduatd_handle_post_pel_run(int fd, + amduat_asl_store_t *store, + const amduatd_http_req_t *req) { + uint8_t *body = NULL; + const char *p = NULL; + const char *end = NULL; + bool have_program_ref = false; + bool have_input_refs = false; + bool have_scheme_ref = false; + bool scheme_is_dag = false; + bool has_params_ref = false; + amduat_reference_t scheme_ref; + amduat_reference_t program_ref; + amduat_reference_t params_ref; + amduat_reference_t *input_refs = NULL; + size_t input_refs_len = 0; + amduat_pel_run_result_t run_result; + int status_code = 200; + const char *status_reason = "OK"; + bool ok = false; + + memset(&scheme_ref, 0, sizeof(scheme_ref)); + memset(&program_ref, 0, sizeof(program_ref)); + memset(¶ms_ref, 0, sizeof(params_ref)); + memset(&run_result, 0, sizeof(run_result)); + + if (store == NULL || req == NULL) { + return amduatd_send_json_error(fd, 500, "Internal Server Error", + "internal error"); + } + + if (req->content_length > (1u * 1024u * 1024u)) { + return amduatd_send_json_error(fd, 413, "Payload Too Large", + "payload too large"); + } + + if (req->content_length == 0) { + return amduatd_send_json_error(fd, 400, "Bad Request", "missing body"); + } + + body = NULL; + if (req->content_length != 0) { + body = (uint8_t *)malloc(req->content_length); + if (body == NULL) { + return amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + } + if (!amduatd_read_exact(fd, body, req->content_length)) { + free(body); + return false; + } + } + + p = (const char *)body; + end = (const char *)body + req->content_length; + if (!amduatd_json_expect(&p, end, '{')) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", "invalid json"); + goto pel_run_cleanup; + } + + for (;;) { + const char *key = NULL; + size_t key_len = 0; + const char *sv = NULL; + size_t sv_len = 0; + const char *cur = NULL; + + cur = amduatd_json_skip_ws(p, end); + if (cur < end && *cur == '}') { + p = cur + 1; + break; + } + + if (!amduatd_json_parse_string_noesc(&p, end, &key, &key_len)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid json key"); + goto pel_run_cleanup; + } + if (!amduatd_json_expect(&p, end, ':')) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", "invalid json"); + goto pel_run_cleanup; + } + + if (key_len == strlen("program_ref") && + memcmp(key, "program_ref", key_len) == 0) { + if (have_program_ref) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "duplicate program_ref"); + goto pel_run_cleanup; + } + if (!amduatd_json_parse_string_noesc(&p, end, &sv, &sv_len) || + !amduatd_decode_ref_hex_str(sv, sv_len, &program_ref)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid program_ref"); + goto pel_run_cleanup; + } + have_program_ref = true; + } else if (key_len == strlen("scheme_ref") && + memcmp(key, "scheme_ref", key_len) == 0) { + if (have_scheme_ref) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "duplicate scheme_ref"); + goto pel_run_cleanup; + } + if (!amduatd_json_parse_string_noesc(&p, end, &sv, &sv_len)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid scheme_ref"); + goto pel_run_cleanup; + } + if (sv_len == 3 && memcmp(sv, "dag", 3) == 0) { + scheme_ref = amduat_pel_program_dag_scheme_ref(); + scheme_is_dag = true; + } else if (!amduatd_decode_ref_hex_str(sv, sv_len, &scheme_ref)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid scheme_ref"); + goto pel_run_cleanup; + } + have_scheme_ref = true; + } else if (key_len == strlen("params_ref") && + memcmp(key, "params_ref", key_len) == 0) { + if (has_params_ref) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "duplicate params_ref"); + goto pel_run_cleanup; + } + if (!amduatd_json_parse_string_noesc(&p, end, &sv, &sv_len) || + !amduatd_decode_ref_hex_str(sv, sv_len, ¶ms_ref)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid params_ref"); + goto pel_run_cleanup; + } + has_params_ref = true; + } else if (key_len == strlen("input_refs") && + memcmp(key, "input_refs", key_len) == 0) { + size_t cap = 0; + if (have_input_refs) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "duplicate input_refs"); + goto pel_run_cleanup; + } + if (!amduatd_json_expect(&p, end, '[')) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid input_refs"); + goto pel_run_cleanup; + } + cur = amduatd_json_skip_ws(p, end); + if (cur < end && *cur == ']') { + p = cur + 1; + have_input_refs = true; + } else { + for (;;) { + amduat_reference_t ref; + memset(&ref, 0, sizeof(ref)); + if (!amduatd_json_parse_string_noesc(&p, end, &sv, &sv_len) || + !amduatd_decode_ref_hex_str(sv, sv_len, &ref)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid input_ref"); + goto pel_run_cleanup; + } + if (input_refs_len == cap) { + size_t next_cap = cap != 0 ? cap * 2u : 4u; + amduat_reference_t *next; + if (next_cap > (SIZE_MAX / sizeof(*input_refs))) { + amduat_reference_free(&ref); + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "too many input_refs"); + goto pel_run_cleanup; + } + next = (amduat_reference_t *)realloc( + input_refs, next_cap * sizeof(*input_refs)); + if (next == NULL) { + amduat_reference_free(&ref); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", + "oom"); + goto pel_run_cleanup; + } + input_refs = next; + cap = next_cap; + } + input_refs[input_refs_len++] = ref; + + cur = amduatd_json_skip_ws(p, end); + if (cur >= end) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid input_refs"); + goto pel_run_cleanup; + } + if (*cur == ',') { + p = cur + 1; + continue; + } + if (*cur == ']') { + p = cur + 1; + have_input_refs = true; + break; + } + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "invalid input_refs"); + goto pel_run_cleanup; + } + } + } else { + if (!amduatd_json_skip_value(&p, end, 0)) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", "invalid json"); + goto pel_run_cleanup; + } + } + + cur = amduatd_json_skip_ws(p, end); + if (cur >= end) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", "invalid json"); + goto pel_run_cleanup; + } + if (*cur == ',') { + p = cur + 1; + continue; + } + if (*cur == '}') { + p = cur + 1; + break; + } + ok = amduatd_send_json_error(fd, 400, "Bad Request", "invalid json"); + goto pel_run_cleanup; + } + + p = amduatd_json_skip_ws(p, end); + if (p != end) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", "invalid json"); + goto pel_run_cleanup; + } + free(body); + body = NULL; + + if (!have_program_ref) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "missing program_ref"); + goto pel_run_cleanup; + } + if (!have_input_refs) { + ok = amduatd_send_json_error(fd, 400, "Bad Request", + "missing input_refs"); + goto pel_run_cleanup; + } + if (!have_scheme_ref) { + scheme_ref = amduat_pel_program_dag_scheme_ref(); + scheme_is_dag = true; + } + + if (!amduat_pel_surf_run_with_result(store, + scheme_ref, + program_ref, + input_refs, + input_refs_len, + has_params_ref, + params_ref, + &run_result)) { + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", + "pel run failed"); + goto pel_run_cleanup; + } + + if (run_result.has_result_value && run_result.result_value.has_store_failure) { + if (run_result.result_value.store_failure.error_code == + AMDUAT_PEL_STORE_ERROR_NOT_FOUND) { + status_code = 404; + status_reason = "Not Found"; + } else { + status_code = 500; + status_reason = "Internal Server Error"; + } + } + + { + amduatd_strbuf_t resp; + char *result_hex = NULL; + char *trace_hex = NULL; + const char *status = "UNKNOWN"; + size_t i; + + memset(&resp, 0, sizeof(resp)); + + if (!amduat_asl_ref_encode_hex(run_result.result_ref, &result_hex)) { + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", + "encode error"); + goto pel_run_cleanup; + } + + if (run_result.has_result_value) { + status = amduat_format_pel_status_name( + run_result.result_value.core_result.status); + if (run_result.result_value.has_trace_ref) { + if (!amduat_asl_ref_encode_hex(run_result.result_value.trace_ref, + &trace_hex)) { + free(result_hex); + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", + "encode error"); + goto pel_run_cleanup; + } + } + } + + if (!amduatd_strbuf_append_cstr(&resp, "{\"result_ref\":\"") || + !amduatd_strbuf_append_cstr(&resp, result_hex) || + !amduatd_strbuf_append_cstr(&resp, "\"")) { + free(result_hex); + free(trace_hex); + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + goto pel_run_cleanup; + } + free(result_hex); + + if (trace_hex != NULL) { + if (!amduatd_strbuf_append_cstr(&resp, ",\"trace_ref\":\"") || + !amduatd_strbuf_append_cstr(&resp, trace_hex) || + !amduatd_strbuf_append_cstr(&resp, "\"")) { + free(trace_hex); + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + goto pel_run_cleanup; + } + free(trace_hex); + } + + if (!amduatd_strbuf_append_cstr(&resp, ",\"output_refs\":[")) { + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + goto pel_run_cleanup; + } + + for (i = 0; i < run_result.output_refs_len; ++i) { + char *out_hex = NULL; + if (!amduat_asl_ref_encode_hex(run_result.output_refs[i], &out_hex)) { + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", + "encode error"); + goto pel_run_cleanup; + } + if (i != 0) { + if (!amduatd_strbuf_append_char(&resp, ',')) { + free(out_hex); + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + goto pel_run_cleanup; + } + } + if (!amduatd_strbuf_append_cstr(&resp, "\"") || + !amduatd_strbuf_append_cstr(&resp, out_hex) || + !amduatd_strbuf_append_cstr(&resp, "\"")) { + free(out_hex); + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + goto pel_run_cleanup; + } + free(out_hex); + } + + if (!amduatd_strbuf_append_cstr(&resp, "],\"status\":\"") || + !amduatd_strbuf_append_cstr(&resp, status) || + !amduatd_strbuf_append_cstr(&resp, "\"}\n")) { + amduatd_strbuf_free(&resp); + ok = amduatd_send_json_error(fd, 500, "Internal Server Error", "oom"); + goto pel_run_cleanup; + } + + ok = amduatd_http_send_json(fd, status_code, status_reason, resp.data, false); + amduatd_strbuf_free(&resp); + } + +pel_run_cleanup: + if (body != NULL) { + free(body); + } + if (run_result.has_result_value) { + amduat_enc_pel1_result_free(&run_result.result_value); + } + if (run_result.output_refs != NULL) { + amduat_pel_surf_free_refs(run_result.output_refs, run_result.output_refs_len); + } + amduat_pel_surf_free_ref(&run_result.result_ref); + + if (input_refs != NULL) { + size_t i; + for (i = 0; i < input_refs_len; ++i) { + amduat_reference_free(&input_refs[i]); + } + free(input_refs); + } + if (has_params_ref) { + amduat_reference_free(¶ms_ref); + } + if (have_program_ref) { + amduat_reference_free(&program_ref); + } + if (have_scheme_ref && !scheme_is_dag) { + amduat_reference_free(&scheme_ref); + } + return ok; +} + static bool amduatd_handle_conn(int fd, amduat_asl_store_t *store, const amduat_asl_store_fs_config_t *cfg) { @@ -563,6 +1326,9 @@ static bool amduatd_handle_conn(int fd, if (strcmp(req.method, "POST") == 0 && strcmp(no_query, "/v1/artifacts") == 0) { return amduatd_handle_post_artifacts(fd, store, &req); } + if (strcmp(req.method, "POST") == 0 && strcmp(no_query, "/v1/pel/run") == 0) { + return amduatd_handle_post_pel_run(fd, store, &req); + } if (strcmp(req.method, "GET") == 0 && strncmp(no_query, "/v1/artifacts/", 14) == 0) { return amduatd_handle_get_artifact(fd, store, req.path, false);