Serve API contract bytes at /v1/contract
This commit is contained in:
parent
345c291c1b
commit
d8b789443e
|
|
@ -39,6 +39,12 @@ curl --unix-socket amduatd.sock http://localhost/v1/meta
|
|||
|
||||
Discover the store-backed API contract ref:
|
||||
|
||||
```sh
|
||||
curl --unix-socket amduatd.sock 'http://localhost/v1/contract?format=ref'
|
||||
```
|
||||
|
||||
Fetch the contract bytes (JSON):
|
||||
|
||||
```sh
|
||||
curl --unix-socket amduatd.sock http://localhost/v1/contract
|
||||
```
|
||||
|
|
@ -75,7 +81,8 @@ curl --unix-socket amduatd.sock -X POST http://localhost/v1/pel/run \
|
|||
## Current endpoints
|
||||
|
||||
- `GET /v1/meta` → `{store_id, encoding_profile_id, hash_id, api_contract_ref}`
|
||||
- `GET /v1/contract` → `{ref}` (fetch bytes via `GET /v1/artifacts/{ref}`)
|
||||
- `GET /v1/contract` → contract bytes (JSON) (+ `X-Amduat-Contract-Ref` header)
|
||||
- `GET /v1/contract?format=ref` → `{ref}`
|
||||
- `POST /v1/artifacts`
|
||||
- raw bytes: `Content-Type: application/octet-stream` (+ optional `X-Amduat-Type-Tag: 0x...`)
|
||||
- artifact framing: `Content-Type: application/vnd.amduat.asl.artifact+v1`
|
||||
|
|
|
|||
|
|
@ -854,27 +854,93 @@ static bool amduatd_handle_meta(int fd,
|
|||
}
|
||||
|
||||
static bool amduatd_handle_get_contract(int fd,
|
||||
amduat_asl_store_t *store,
|
||||
const amduatd_http_req_t *req,
|
||||
amduat_reference_t api_contract_ref) {
|
||||
char *hex = NULL;
|
||||
char json[2048];
|
||||
int n;
|
||||
char format[32];
|
||||
|
||||
if (api_contract_ref.hash_id == 0 || api_contract_ref.digest.data == NULL ||
|
||||
api_contract_ref.digest.len == 0) {
|
||||
return amduatd_http_send_json(fd, 404, "Not Found", "{\"ref\":null}\n",
|
||||
false);
|
||||
return amduatd_http_send_not_found(fd, req);
|
||||
}
|
||||
if (!amduat_asl_ref_encode_hex(api_contract_ref, &hex)) {
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||
"encode error\n", false);
|
||||
|
||||
memset(format, 0, sizeof(format));
|
||||
if (req != NULL &&
|
||||
amduatd_query_param(req->path, "format", format, sizeof(format)) !=
|
||||
NULL &&
|
||||
strcmp(format, "ref") == 0) {
|
||||
char json[2048];
|
||||
int n;
|
||||
if (!amduat_asl_ref_encode_hex(api_contract_ref, &hex)) {
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||
"encode error\n", false);
|
||||
}
|
||||
n = snprintf(json, sizeof(json), "{\"ref\":\"%s\"}\n", hex);
|
||||
free(hex);
|
||||
if (n <= 0 || (size_t)n >= sizeof(json)) {
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||
"error\n", false);
|
||||
}
|
||||
return amduatd_http_send_json(fd, 200, "OK", json, false);
|
||||
}
|
||||
n = snprintf(json, sizeof(json), "{\"ref\":\"%s\"}\n", hex);
|
||||
free(hex);
|
||||
if (n <= 0 || (size_t)n >= sizeof(json)) {
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error", "error\n",
|
||||
false);
|
||||
|
||||
{
|
||||
amduat_artifact_t artifact;
|
||||
amduat_asl_store_error_t err;
|
||||
|
||||
memset(&artifact, 0, sizeof(artifact));
|
||||
err = amduat_asl_store_get(store, api_contract_ref, &artifact);
|
||||
if (err == AMDUAT_ASL_STORE_ERR_NOT_FOUND) {
|
||||
return amduatd_http_send_not_found(fd, req);
|
||||
}
|
||||
if (err != AMDUAT_ASL_STORE_OK) {
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||
"store error\n", false);
|
||||
}
|
||||
if (artifact.bytes.len != 0 && artifact.bytes.data == NULL) {
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||
"store error\n", false);
|
||||
}
|
||||
|
||||
if (!amduat_asl_ref_encode_hex(api_contract_ref, &hex)) {
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return amduatd_http_send_text(fd, 500, "Internal Server Error",
|
||||
"encode error\n", false);
|
||||
}
|
||||
|
||||
{
|
||||
char hdr[600];
|
||||
int n = snprintf(hdr,
|
||||
sizeof(hdr),
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Length: %zu\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"X-Amduat-Contract-Ref: %s\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n",
|
||||
artifact.bytes.len,
|
||||
hex);
|
||||
free(hex);
|
||||
if (n <= 0 || (size_t)n >= sizeof(hdr)) {
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return false;
|
||||
}
|
||||
if (!amduatd_write_all(fd, (const uint8_t *)hdr, (size_t)n)) {
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return false;
|
||||
}
|
||||
if (artifact.bytes.len != 0) {
|
||||
bool ok = amduatd_write_all(fd, artifact.bytes.data, artifact.bytes.len);
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return ok;
|
||||
}
|
||||
amduat_asl_artifact_free(&artifact);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return amduatd_http_send_json(fd, 200, "OK", json, false);
|
||||
}
|
||||
|
||||
static bool amduatd_seed_api_contract(amduat_asl_store_t *store,
|
||||
|
|
@ -1518,7 +1584,7 @@ static bool amduatd_handle_conn(int fd,
|
|||
return amduatd_handle_meta(fd, cfg, api_contract_ref, true);
|
||||
}
|
||||
if (strcmp(req.method, "GET") == 0 && strcmp(no_query, "/v1/contract") == 0) {
|
||||
return amduatd_handle_get_contract(fd, api_contract_ref);
|
||||
return amduatd_handle_get_contract(fd, store, &req, api_contract_ref);
|
||||
}
|
||||
|
||||
if (strcmp(req.method, "POST") == 0 && strcmp(no_query, "/v1/artifacts") == 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue