mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-09 12:01:15 +00:00
Improve Rhizome HTTP API diagnostics
Add RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG enum option to indicate that the manifest exceeded 8 KiB in size. Refactor rhizome_add_manifest() and rhizome_manifest_finalise() to return 'struct rhizome_bundle_result' instead of 'enum rhizome_bundle_status', so that that their detailed failure messages can reach the HTTP API layer instead of just being logged. Fix HTTP response status codes produced Rhizome direct HTTP requests to be consistent with the Rhizome RESTful API.
This commit is contained in:
parent
74735339aa
commit
3f8f0f6fc7
58
meshms.c
58
meshms.c
@ -86,6 +86,7 @@ static enum meshms_status get_my_conversation_bundle(const sid_t *my_sidp, rhizo
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
WARNF("Cannot create conversation manifest: %s", alloca_rhizome_bundle_result(result));
|
||||
rhizome_bundle_result_free(&result);
|
||||
return MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
@ -235,10 +236,12 @@ static enum meshms_status create_ply(const sid_t *my_sid, struct meshms_conversa
|
||||
WHYF("Error creating ply manifest: %s", alloca_rhizome_bundle_result(result));
|
||||
rhizome_bundle_result_free(&result);
|
||||
return MESHMS_STATUS_ERROR;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
// TODO
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
WARNF("Cannot create ply manifest: %s", alloca_rhizome_bundle_result(result));
|
||||
rhizome_bundle_result_free(&result);
|
||||
return MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
@ -416,9 +419,8 @@ static enum meshms_status append_meshms_buffer(const sid_t *my_sid, struct meshm
|
||||
status = MESHMS_STATUS_ERROR;
|
||||
goto end;
|
||||
}
|
||||
enum rhizome_bundle_status bstatus = rhizome_manifest_finalise(m, &mout, 1);
|
||||
DEBUGF(meshms, "bstatus=%d", bstatus);
|
||||
switch (bstatus) {
|
||||
struct rhizome_bundle_result result = rhizome_manifest_finalise(m, &mout, 1);
|
||||
switch (result.status) {
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
// error has already been logged
|
||||
status = MESHMS_STATUS_ERROR;
|
||||
@ -430,24 +432,33 @@ static enum meshms_status append_meshms_buffer(const sid_t *my_sid, struct meshm
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WHYF("MeshMS ply manifest (version=%"PRIu64") gazumped by Rhizome store (version=%"PRIu64")",
|
||||
WARNF("MeshMS ply manifest (version=%"PRIu64") gazumped by Rhizome store (version=%"PRIu64")",
|
||||
m->version, mout->version);
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARNF("MeshMS ply manifest evicted from store");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WHYF("MeshMS ply manifest not consistent with payload");
|
||||
WARNF("MeshMS ply manifest not consistent with payload");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WHYF("MeshMS ply manifest is not signed");
|
||||
WARNF("MeshMS ply manifest is not signed");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WHYF("MeshMS ply manifest is invalid");
|
||||
WARNF("MeshMS ply manifest is invalid");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARNF("MeshMS ply manifest not stored due to database locking");
|
||||
break;
|
||||
default:
|
||||
FATALF("bstatus=%d", bstatus);
|
||||
}
|
||||
rhizome_bundle_result_free(&result);
|
||||
end:
|
||||
if (mout && mout!=m)
|
||||
rhizome_manifest_free(mout);
|
||||
@ -738,8 +749,8 @@ static enum meshms_status write_known_conversations(rhizome_manifest *m, struct
|
||||
goto end;
|
||||
rhizome_manifest_set_filehash(m, &write.id);
|
||||
|
||||
enum rhizome_bundle_status bstatus = rhizome_manifest_finalise(m, &mout, 1);
|
||||
switch (bstatus) {
|
||||
struct rhizome_bundle_result result = rhizome_manifest_finalise(m, &mout, 1);
|
||||
switch (result.status) {
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
// error is already logged
|
||||
break;
|
||||
@ -749,25 +760,34 @@ static enum meshms_status write_known_conversations(rhizome_manifest *m, struct
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
WHYF("MeshMS conversation manifest (version=%"PRIu64") gazumped by Rhizome store (version=%"PRIu64")",
|
||||
m->version, mout->version);
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARNF("MeshMS conversation manifest (version=%"PRIu64") gazumped by Rhizome store (version=%"PRIu64")",
|
||||
m->version, mout->version);
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARNF("MeshMS ply manifest evicted from store");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
WHY("MeshMS conversation manifest not consistent with payload");
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARN("MeshMS conversation manifest not consistent with payload");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
WHY("MeshMS conversation manifest is not signed");
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARN("MeshMS conversation manifest is not signed");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
WHY("MeshMS conversation manifest is invalid");
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARN("MeshMS conversation manifest is invalid");
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
status = MESHMS_STATUS_PROTOCOL_FAULT;
|
||||
WARNF("MeshMS conversation manifest not stored due to database locking");
|
||||
break;
|
||||
default:
|
||||
FATALF("bstatus=%d", bstatus);
|
||||
}
|
||||
rhizome_bundle_result_free(&result);
|
||||
end:
|
||||
if (meshms_failed(status))
|
||||
rhizome_fail_write(&write);
|
||||
|
70
rhizome.c
70
rhizome.c
@ -229,6 +229,7 @@ struct rhizome_bundle_result rhizome_manifest_add_file(int appending,
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
FATALF("rhizome_retrieve_manifest() returned %s", rhizome_bundle_status_message(result.status));
|
||||
}
|
||||
}
|
||||
@ -325,16 +326,7 @@ error:
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
*mout = new_manifest;
|
||||
return result;
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
default:
|
||||
if (new_manifest && new_manifest != m && new_manifest != existing_manifest)
|
||||
rhizome_manifest_free(new_manifest);
|
||||
if (existing_manifest)
|
||||
@ -490,7 +482,7 @@ int rhizome_manifest_add_bundle_key(rhizome_manifest *m)
|
||||
rhizome_manifest_del_bundle_key(m);
|
||||
switch (m->authorship) {
|
||||
case AUTHOR_UNKNOWN:
|
||||
WHYF("Cannot set BK because author=%s is not in keyring", alloca_tohex_sid_t(m->author));
|
||||
INFOF("Cannot set BK because author=%s is not in keyring", alloca_tohex_sid_t(m->author));
|
||||
break;
|
||||
case AUTHENTICATION_ERROR:
|
||||
WHY("Cannot set BK due to error");
|
||||
@ -581,12 +573,12 @@ enum rhizome_bundle_status rhizome_manifest_check_stored(rhizome_manifest *m, rh
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
enum rhizome_bundle_status rhizome_add_manifest(rhizome_manifest *m, rhizome_manifest **mout)
|
||||
enum rhizome_bundle_status rhizome_add_manifest_to_store(rhizome_manifest *m, rhizome_manifest **mout)
|
||||
{
|
||||
if (mout == NULL)
|
||||
DEBUGF(rhizome, "rhizome_add_manifest(m=manifest[%d](%p), mout=NULL)", m->manifest_record_number, m);
|
||||
DEBUGF(rhizome, "%s(m=manifest[%d](%p), mout=NULL)", __func__, m->manifest_record_number, m);
|
||||
else
|
||||
DEBUGF(rhizome, "rhizome_add_manifest(m=manifest[%d](%p), *mout=manifest[%d](%p))", m->manifest_record_number, m, *mout ? (*mout)->manifest_record_number : -1, *mout);
|
||||
DEBUGF(rhizome, "%s(m=manifest[%d](%p), *mout=manifest[%d](%p))", __func__, m->manifest_record_number, m, *mout ? (*mout)->manifest_record_number : -1, *mout);
|
||||
if (!m->finalised && !rhizome_manifest_validate(m))
|
||||
return RHIZOME_BUNDLE_STATUS_INVALID;
|
||||
assert(m->finalised);
|
||||
@ -597,7 +589,7 @@ enum rhizome_bundle_status rhizome_add_manifest(rhizome_manifest *m, rhizome_man
|
||||
return WHY("Payload has not been stored");
|
||||
enum rhizome_bundle_status status = rhizome_manifest_check_stored(m, mout);
|
||||
if (status == RHIZOME_BUNDLE_STATUS_NEW && rhizome_store_manifest(m) == -1)
|
||||
return -1;
|
||||
status = RHIZOME_BUNDLE_STATUS_ERROR;
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -615,17 +607,18 @@ int rhizome_saw_voice_traffic()
|
||||
const char *rhizome_bundle_status_message(enum rhizome_bundle_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW: return "Bundle new to store";
|
||||
case RHIZOME_BUNDLE_STATUS_SAME: return "Bundle already in store";
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE: return "Duplicate bundle already in store";
|
||||
case RHIZOME_BUNDLE_STATUS_OLD: return "Newer bundle already in store";
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID: return "Invalid manifest";
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE: return "Manifest signature does not verify";
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT: return "Manifest inconsistent with supplied payload";
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM: return "No room in store for bundle";
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY: return "Bundle is read-only";
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY: return "Internal error";
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR: return "Internal error";
|
||||
case RHIZOME_BUNDLE_STATUS_NEW: return "Bundle new to store";
|
||||
case RHIZOME_BUNDLE_STATUS_SAME: return "Bundle already in store";
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE: return "Duplicate bundle already in store";
|
||||
case RHIZOME_BUNDLE_STATUS_OLD: return "Newer bundle already in store";
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID: return "Invalid manifest";
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE: return "Manifest signature does not verify";
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT: return "Manifest inconsistent with supplied payload";
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM: return "No room in store for bundle";
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY: return "Bundle is read-only";
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY: return "Internal error";
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR: return "Internal error";
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG: return "Manifest too big";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -669,17 +662,18 @@ void rhizome_bundle_result_free(struct rhizome_bundle_result *resultp)
|
||||
static const char *rhizome_bundle_status_symbol(enum rhizome_bundle_status status)
|
||||
{
|
||||
switch (status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW: return "NEW";
|
||||
case RHIZOME_BUNDLE_STATUS_SAME: return "SAME";
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE: return "DUPLICATE";
|
||||
case RHIZOME_BUNDLE_STATUS_OLD: return "OLD";
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID: return "INVALID";
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE: return "FAKE";
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT: return "INCONSISTENT";
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM: return "NO_ROOM";
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY: return "READONLY";
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY: return "BUSY";
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR: return "ERROR";
|
||||
case RHIZOME_BUNDLE_STATUS_NEW: return "NEW";
|
||||
case RHIZOME_BUNDLE_STATUS_SAME: return "SAME";
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE: return "DUPLICATE";
|
||||
case RHIZOME_BUNDLE_STATUS_OLD: return "OLD";
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID: return "INVALID";
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE: return "FAKE";
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT: return "INCONSISTENT";
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM: return "NO_ROOM";
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY: return "READONLY";
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY: return "BUSY";
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG: return "MANIFEST_TOO_BIG";
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR: return "ERROR";
|
||||
}
|
||||
FATALF("status=%d", (int)status);
|
||||
}
|
||||
@ -696,6 +690,7 @@ static void log_rhizome_bundle_result(struct __sourceloc __whence, struct rhizom
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
DEBUG(rhizome, alloca_rhizome_bundle_result(result));
|
||||
return;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
@ -772,6 +767,7 @@ strbuf strbuf_append_rhizome_bundle_result(strbuf sb, struct rhizome_bundle_resu
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
strbuf_puts(sb, "RHIZOME_BUNDLE_STATUS_");
|
||||
strbuf_puts(sb, rhizome_bundle_status_symbol(result.status));
|
||||
|
10
rhizome.h
10
rhizome.h
@ -412,6 +412,7 @@ enum rhizome_bundle_status {
|
||||
RHIZOME_BUNDLE_STATUS_NO_ROOM = 7, // doesn't fit; store may contain more important bundles
|
||||
RHIZOME_BUNDLE_STATUS_READONLY = 8, // cannot modify manifest; secret unknown
|
||||
RHIZOME_BUNDLE_STATUS_BUSY = 9, // the database is currently busy
|
||||
RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG = 10, // manifest + signature exceeds size limit
|
||||
};
|
||||
|
||||
// Useful for initialising a variable then checking later that it was set to a
|
||||
@ -443,8 +444,8 @@ struct rhizome_bundle_result _rhizome_bundle_result_strdup(struct __sourceloc, e
|
||||
struct rhizome_bundle_result _rhizome_bundle_result_sprintf(struct __sourceloc, enum rhizome_bundle_status, const char *fmt, ...);
|
||||
|
||||
#define rhizome_bundle_result(status) _rhizome_bundle_result(__WHENCE__, status)
|
||||
#define rhizome_bundle_result_static(status, str) _rhizome_bundle_result_static(__WHENCE__, status, str);
|
||||
#define rhizome_bundle_result_strdup(status, str) _rhizome_bundle_result_strdup(__WHENCE__, status, str);
|
||||
#define rhizome_bundle_result_static(status, str) _rhizome_bundle_result_static(__WHENCE__, status, str)
|
||||
#define rhizome_bundle_result_strdup(status, str) _rhizome_bundle_result_strdup(__WHENCE__, status, str)
|
||||
#define rhizome_bundle_result_sprintf(status, fmt, ...) _rhizome_bundle_result_sprintf(__WHENCE__, status, fmt, ## __VA_ARGS__);
|
||||
|
||||
// Functions for extracting information from a struct rhizome_bundle_result.
|
||||
@ -475,7 +476,6 @@ const char *rhizome_payload_status_message(enum rhizome_payload_status);
|
||||
const char *rhizome_payload_status_message_nonnull(enum rhizome_payload_status);
|
||||
|
||||
int rhizome_write_manifest_file(rhizome_manifest *m, const char *filename, char append);
|
||||
int rhizome_manifest_selfsign(rhizome_manifest *m);
|
||||
int rhizome_read_manifest_from_file(rhizome_manifest *m, const char *filename);
|
||||
int rhizome_manifest_validate(rhizome_manifest *m);
|
||||
const char *rhizome_manifest_validate_reason(rhizome_manifest *m);
|
||||
@ -513,9 +513,9 @@ void rhizome_find_bundle_author_and_secret(rhizome_manifest *m);
|
||||
int rhizome_lookup_author(rhizome_manifest *m);
|
||||
void rhizome_authenticate_author(rhizome_manifest *m);
|
||||
|
||||
enum rhizome_bundle_status rhizome_manifest_finalise(rhizome_manifest *m, rhizome_manifest **m_out, int deduplicate);
|
||||
struct rhizome_bundle_result rhizome_manifest_finalise(rhizome_manifest *m, rhizome_manifest **m_out, int deduplicate);
|
||||
enum rhizome_bundle_status rhizome_manifest_check_stored(rhizome_manifest *m, rhizome_manifest **m_out);
|
||||
enum rhizome_bundle_status rhizome_add_manifest(rhizome_manifest *m_in, rhizome_manifest **m_out);
|
||||
enum rhizome_bundle_status rhizome_add_manifest_to_store(rhizome_manifest *m_in, rhizome_manifest **m_out);
|
||||
|
||||
void rhizome_bytes_to_hex_upper(unsigned const char *in, char *out, int byteCount);
|
||||
int rhizome_find_privatekey(rhizome_manifest *m);
|
||||
|
@ -1322,9 +1322,10 @@ void _rhizome_manifest_free(struct __sourceloc __whence, rhizome_manifest *m)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert variable list into manifest text body and compute the hash. Do not sign.
|
||||
/* Converts the variable list into manifest text body and computes the hash. Does not sign.
|
||||
* Returns 0 if successful, -1 if the result exceeds the manifest size limit.
|
||||
*/
|
||||
static int rhizome_manifest_pack_variables(rhizome_manifest *m)
|
||||
static struct rhizome_bundle_result rhizome_manifest_pack_variables(rhizome_manifest *m)
|
||||
{
|
||||
assert(m->var_count <= NELS(m->vars));
|
||||
strbuf sb = strbuf_local_buf(m->manifestdata);
|
||||
@ -1335,42 +1336,47 @@ static int rhizome_manifest_pack_variables(rhizome_manifest *m)
|
||||
strbuf_puts(sb, m->values[i]);
|
||||
strbuf_putc(sb, '\n');
|
||||
}
|
||||
if (strbuf_overrun(sb))
|
||||
return WHYF("Manifest overflow: body of %zu bytes exceeds limit of %zu", strbuf_count(sb) + 1, sizeof m->manifestdata);
|
||||
if (strbuf_overrun(sb)) {
|
||||
return rhizome_bundle_result_sprintf(
|
||||
RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG,
|
||||
"Manifest too big: body of %zu bytes exceeds limit of %zu",
|
||||
strbuf_count(sb) + 1, sizeof m->manifestdata);
|
||||
}
|
||||
m->manifest_body_bytes = strbuf_len(sb) + 1;
|
||||
DEBUGF(rhizome, "Repacked variables into manifest: %zu bytes", m->manifest_body_bytes);
|
||||
m->manifest_all_bytes = m->manifest_body_bytes;
|
||||
m->selfSigned = 0;
|
||||
return 0;
|
||||
return rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NEW);
|
||||
}
|
||||
|
||||
/* Sign this manifest using it's own BID secret key. Manifest must not already be signed.
|
||||
* Manifest body hash must already be computed.
|
||||
*/
|
||||
int rhizome_manifest_selfsign(rhizome_manifest *m)
|
||||
static struct rhizome_bundle_result rhizome_manifest_selfsign(rhizome_manifest *m)
|
||||
{
|
||||
assert(m->manifest_body_bytes > 0);
|
||||
assert(m->manifest_body_bytes <= sizeof m->manifestdata);
|
||||
assert(m->manifestdata[m->manifest_body_bytes - 1] == '\0');
|
||||
assert(m->manifest_body_bytes == m->manifest_all_bytes); // no signature yet
|
||||
if (!m->haveSecret)
|
||||
return WHY("Need private key to sign manifest");
|
||||
return rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_READONLY, "Missing bundle secret");
|
||||
crypto_hash_sha512(m->manifesthash, m->manifestdata, m->manifest_body_bytes);
|
||||
rhizome_signature sig;
|
||||
if (rhizome_sign_hash(m, &sig) == -1)
|
||||
return WHY("rhizome_sign_hash() failed");
|
||||
return rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_ERROR, "rhizome_sign_hash() failed");
|
||||
assert(sig.signatureLength > 0);
|
||||
/* Append signature to end of manifest data */
|
||||
if (sig.signatureLength + m->manifest_body_bytes > sizeof m->manifestdata)
|
||||
return WHYF("Manifest overflow: body %zu + signature %zu bytes exceeds limit of %zu",
|
||||
m->manifest_body_bytes,
|
||||
sig.signatureLength,
|
||||
sizeof m->manifestdata
|
||||
);
|
||||
if (sig.signatureLength + m->manifest_body_bytes > sizeof m->manifestdata) {
|
||||
return rhizome_bundle_result_sprintf(RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG,
|
||||
"Manifest too big: body of %zu + signature of %zu bytes exceeds limit of %zu",
|
||||
m->manifest_body_bytes,
|
||||
sig.signatureLength,
|
||||
sizeof m->manifestdata);
|
||||
}
|
||||
bcopy(sig.signature, m->manifestdata + m->manifest_body_bytes, sig.signatureLength);
|
||||
m->manifest_all_bytes = m->manifest_body_bytes + sig.signatureLength;
|
||||
m->selfSigned = 1;
|
||||
return 0;
|
||||
return rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NEW);
|
||||
}
|
||||
|
||||
int rhizome_write_manifest_file(rhizome_manifest *m, const char *path, char append)
|
||||
@ -1410,12 +1416,15 @@ int rhizome_manifest_dump(rhizome_manifest *m, const char *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum rhizome_bundle_status rhizome_manifest_finalise(rhizome_manifest *m, rhizome_manifest **mout, int deduplicate)
|
||||
struct rhizome_bundle_result rhizome_manifest_finalise(rhizome_manifest *m, rhizome_manifest **mout, int deduplicate)
|
||||
{
|
||||
IN();
|
||||
assert(*mout == NULL);
|
||||
if (!m->finalised && !rhizome_manifest_validate(m))
|
||||
RETURN(RHIZOME_BUNDLE_STATUS_INVALID);
|
||||
if (!m->finalised) {
|
||||
const char *reason = rhizome_manifest_validate_reason(m);
|
||||
if (reason)
|
||||
RETURN(rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_INVALID, reason));
|
||||
}
|
||||
// The duplicate detection logic exists to filter out files repeatedly added with no existing
|
||||
// manifest (ie, "de-bounce" for the "Add File" user interface action).
|
||||
// 1. If a manifest was supplied with a bundle ID, don't check for a duplicate.
|
||||
@ -1427,13 +1436,13 @@ enum rhizome_bundle_status rhizome_manifest_finalise(rhizome_manifest *m, rhizom
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
assert(*mout != NULL);
|
||||
assert(*mout != m);
|
||||
RETURN(status);
|
||||
RETURN(rhizome_bundle_result(status));
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
if (*mout != NULL && *mout != m) {
|
||||
rhizome_manifest_free(*mout);
|
||||
*mout = NULL;
|
||||
}
|
||||
RETURN(status);
|
||||
RETURN(rhizome_bundle_result(status));
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
break;
|
||||
default:
|
||||
@ -1444,18 +1453,22 @@ enum rhizome_bundle_status rhizome_manifest_finalise(rhizome_manifest *m, rhizom
|
||||
*mout = m;
|
||||
|
||||
/* Convert to final form for signing and writing to disk */
|
||||
if (rhizome_manifest_pack_variables(m))
|
||||
RETURN(WHY("Could not convert manifest to wire format"));
|
||||
struct rhizome_bundle_result result = rhizome_manifest_pack_variables(m);
|
||||
if (result.status != RHIZOME_BUNDLE_STATUS_NEW)
|
||||
RETURN(result);
|
||||
rhizome_bundle_result_free(&result);
|
||||
|
||||
/* Sign it */
|
||||
assert(!m->selfSigned);
|
||||
if (rhizome_manifest_selfsign(m))
|
||||
RETURN(WHY("Could not sign manifest"));
|
||||
assert(m->selfSigned);
|
||||
result = rhizome_manifest_selfsign(m);
|
||||
if (result.status == RHIZOME_BUNDLE_STATUS_NEW) {
|
||||
assert(m->selfSigned);
|
||||
rhizome_bundle_result_free(&result);
|
||||
/* mark manifest as finalised */
|
||||
result.status = rhizome_add_manifest_to_store(m, mout);
|
||||
}
|
||||
|
||||
/* mark manifest as finalised */
|
||||
enum rhizome_bundle_status status = rhizome_add_manifest(m, mout);
|
||||
RETURN(status);
|
||||
RETURN(result);
|
||||
OUT();
|
||||
}
|
||||
|
||||
|
@ -273,10 +273,12 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
|
||||
if (!rhizome_manifest_validate(m) || m->malformed)
|
||||
result.status = RHIZOME_BUNDLE_STATUS_INVALID;
|
||||
else {
|
||||
result.status = rhizome_manifest_finalise(m, &mout, !force_new);
|
||||
rhizome_bundle_result_free(&result);
|
||||
result = rhizome_manifest_finalise(m, &mout, !force_new);
|
||||
if (mout && mout != m && !rhizome_manifest_validate(mout)) {
|
||||
WHYF("Stored manifest id=%s is invalid -- overwriting", alloca_tohex_rhizome_bid_t(mout->cryptoSignPublic));
|
||||
result.status = RHIZOME_BUNDLE_STATUS_NEW;
|
||||
WHYF("Stored manifest id=%s is invalid -- overwriting", alloca_tohex_rhizome_bid_t(mout->cryptoSignPublic));
|
||||
rhizome_bundle_result_free(&result);
|
||||
result = rhizome_bundle_result(RHIZOME_BUNDLE_STATUS_NEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,6 +307,7 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
status_valid = 1;
|
||||
break;
|
||||
// Do not use a default: label! With no default, if a new value is added to the enum, then the
|
||||
|
@ -61,6 +61,42 @@ static void rhizome_direct_clear_temporary_files(httpd_request *r)
|
||||
}
|
||||
}
|
||||
|
||||
static void http_request_rhizome_bundle_status_response(httpd_request *r, struct rhizome_bundle_result result, rhizome_manifest *m)
|
||||
{
|
||||
int http_status = 500;
|
||||
switch (result.status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
http_status = 201; // Created
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
http_status = 200; // OK
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
http_status = 202; // Accepted
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
http_status = 422; // Unprocessable Entity
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
http_status = 423; // Locked
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
http_status = 419; // Authentication Timeout
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
break;
|
||||
}
|
||||
if (m)
|
||||
http_request_response_static(&r->http, http_status, CONTENT_TYPE_TEXT, (const char *)m->manifestdata, m->manifest_all_bytes);
|
||||
else
|
||||
http_request_simple_response(&r->http, http_status, rhizome_bundle_result_message(result));
|
||||
}
|
||||
|
||||
static int rhizome_direct_import_end(struct http_request *hr)
|
||||
{
|
||||
httpd_request *r = (httpd_request *) hr;
|
||||
@ -85,52 +121,17 @@ static int rhizome_direct_import_end(struct http_request *hr)
|
||||
alloca_str_toprint(manifest_path),
|
||||
alloca_str_toprint(payload_path)
|
||||
);
|
||||
enum rhizome_bundle_status status = 0;
|
||||
rhizome_manifest *m = rhizome_new_manifest();
|
||||
if (!m)
|
||||
status = WHY("Out of manifests");
|
||||
else {
|
||||
status = rhizome_bundle_import_files(m, NULL, manifest_path, payload_path);
|
||||
rhizome_manifest_free(m);
|
||||
if (!m) {
|
||||
http_request_simple_response(&r->http, 429, "Manifest table full"); // Too Many Requests
|
||||
return 0;
|
||||
}
|
||||
struct rhizome_bundle_result result = INVALID_RHIZOME_BUNDLE_RESULT;
|
||||
result.status = rhizome_bundle_import_files(m, NULL, manifest_path, payload_path);
|
||||
rhizome_manifest_free(m);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
/* report back to caller.
|
||||
200 = ok, which is probably appropriate for when we already had the bundle.
|
||||
201 = content created, which is probably appropriate for when we successfully
|
||||
import a bundle (or if we already have it).
|
||||
403 = forbidden, which might be appropriate if we refuse to accept it, e.g.,
|
||||
the import fails due to malformed data etc.
|
||||
(should probably also indicate if we have a newer version if possible)
|
||||
*/
|
||||
switch (status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
http_request_simple_response(&r->http, 201, "Bundle succesfully imported");
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
http_request_simple_response(&r->http, 200, "Bundle already imported"); // OK
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
http_request_simple_response(&r->http, 202, "Newer bundle already stored"); // Accepted
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
http_request_simple_response(&r->http, 422, "Manifest is invalid"); // Unprocessable Entity
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
http_request_simple_response(&r->http, 422, "Manifest is inconsistent with file"); // Unprocessable Entity
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
http_request_simple_response(&r->http, 403, "Manifest not signed"); // Forbidden
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
http_request_simple_response(&r->http, 202, "Not enough space"); // Accepted
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
break;
|
||||
}
|
||||
http_request_simple_response(&r->http, 500, "Internal Error: Rhizome import failed");
|
||||
http_request_rhizome_bundle_status_response(r, result, NULL);
|
||||
rhizome_bundle_result_free(&result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -242,50 +243,34 @@ static int rhizome_direct_addfile_end(struct http_request *hr)
|
||||
http_request_simple_response(&r->http, 500, "Internal Error: Could not store file");
|
||||
return 0;
|
||||
}
|
||||
// If manifest template did not specify a service field, then by default it is "file".
|
||||
if (!rhizome_is_bk_none(&config.rhizome.api.addfile.bundle_secret_key))
|
||||
rhizome_apply_bundle_secret(m, &config.rhizome.api.addfile.bundle_secret_key);
|
||||
// If manifest template did not specify a service field, then by default it is "file".
|
||||
if (m->service == NULL)
|
||||
rhizome_manifest_set_service(m, RHIZOME_SERVICE_FILE);
|
||||
const sid_t *author = is_sid_t_any(config.rhizome.api.addfile.default_author) ? NULL : &config.rhizome.api.addfile.default_author;
|
||||
struct rhizome_bundle_result result = rhizome_fill_manifest(m, r->u.direct_import.data_file_name, author);
|
||||
if (result.status != RHIZOME_BUNDLE_STATUS_NEW) {
|
||||
rhizome_manifest_free(m);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
http_request_simple_response(&r->http, 500, result.message);
|
||||
rhizome_manifest *mout = NULL;
|
||||
if (result.status == RHIZOME_BUNDLE_STATUS_NEW) {
|
||||
rhizome_bundle_result_free(&result);
|
||||
return 0;
|
||||
}
|
||||
rhizome_bundle_result_free(&result);
|
||||
rhizome_manifest_set_crypt(m, PAYLOAD_CLEAR);
|
||||
// import file contents
|
||||
// TODO, stream file into database
|
||||
assert(m->filesize != RHIZOME_SIZE_UNSET);
|
||||
if (m->filesize > 0) {
|
||||
if (rhizome_store_payload_file(m, payload_path) != RHIZOME_PAYLOAD_STATUS_NEW) {
|
||||
rhizome_manifest_free(m);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
http_request_simple_response(&r->http, 500, "Internal Error: Could not store file");
|
||||
return 0;
|
||||
rhizome_manifest_set_crypt(m, PAYLOAD_CLEAR);
|
||||
// import file contents
|
||||
// TODO, stream file into database
|
||||
assert(m->filesize != RHIZOME_SIZE_UNSET);
|
||||
if (m->filesize == 0 || rhizome_store_payload_file(m, payload_path) == RHIZOME_PAYLOAD_STATUS_NEW) {
|
||||
result = rhizome_manifest_finalise(m, &mout, 1);
|
||||
if (mout)
|
||||
DEBUGF(rhizome, "Import sans-manifest appeared to succeed");
|
||||
}
|
||||
}
|
||||
rhizome_manifest *mout = NULL;
|
||||
if (rhizome_manifest_finalise(m, &mout, 1) == -1) {
|
||||
if (mout && mout != m)
|
||||
rhizome_manifest_free(mout);
|
||||
rhizome_manifest_free(m);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
http_request_simple_response(&r->http, 500, "Internal Error: Could not finalise manifest");
|
||||
return 0;
|
||||
}
|
||||
DEBUGF(rhizome, "Import sans-manifest appeared to succeed");
|
||||
/* Respond with the manifest that was added. */
|
||||
http_request_response_static(&r->http, 200, CONTENT_TYPE_TEXT, (const char *)m->manifestdata, m->manifest_all_bytes);
|
||||
/* clean up after ourselves */
|
||||
http_request_rhizome_bundle_status_response(r, result, mout);
|
||||
/* Clean up after ourselves. */
|
||||
rhizome_bundle_result_free(&result);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
if (mout && mout != m)
|
||||
rhizome_manifest_free(mout);
|
||||
rhizome_manifest_free(m);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
return 0;
|
||||
} else {
|
||||
http_request_simple_response(&r->http, 501, "Not Implemented: Rhizome add with manifest");
|
||||
|
@ -471,7 +471,7 @@ static int rhizome_import_received_bundle(struct rhizome_manifest *m)
|
||||
m->manifest_all_bytes, m->sig_count, m->filesize);
|
||||
if (IF_DEBUG(rhizome_rx))
|
||||
dump("manifest", m->manifestdata, m->manifest_all_bytes);
|
||||
enum rhizome_bundle_status status = rhizome_add_manifest(m, NULL);
|
||||
enum rhizome_bundle_status status = rhizome_add_manifest_to_store(m, NULL);
|
||||
switch (status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
return 0;
|
||||
@ -483,7 +483,7 @@ static int rhizome_import_received_bundle(struct rhizome_manifest *m)
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
return -1;
|
||||
default:
|
||||
FATALF("rhizome_add_manifest() returned %d", status);
|
||||
FATALF("rhizome_add_manifest_to_store() returned %d", status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,7 +750,7 @@ rhizome_fetch(struct rhizome_fetch_slot *slot, rhizome_manifest *m,
|
||||
// If the payload is already available, no need to fetch, so import now.
|
||||
if (result == IMPORTED) {
|
||||
DEBUGF(rhizome_rx, " fetch not started - payload already present, so importing instead");
|
||||
if (rhizome_add_manifest(m, NULL) == -1)
|
||||
if (rhizome_add_manifest_to_store(m, NULL) == -1)
|
||||
RETURN(WHY("add manifest failed"));
|
||||
}
|
||||
RETURN(result);
|
||||
|
@ -91,6 +91,7 @@ static int http_request_rhizome_response(struct httpd_request *r, uint16_t http_
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
rhizome_http_status = 422; // Unprocessable Entity
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
@ -453,6 +454,7 @@ static int insert_make_manifest(httpd_request *r)
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
return http_request_rhizome_response(r, 0, NULL);
|
||||
}
|
||||
@ -654,7 +656,7 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
assert(r->u.insert.write.file_length != RHIZOME_SIZE_UNSET);
|
||||
if (r->u.insert.appending) {
|
||||
// For journal appends, the user cannot supply a 'filesize' field. This will have been caught
|
||||
// by previous logic. The existing manifest should have a 'filesize' field. The new payload
|
||||
// by previous logic. The manifest should also have a 'filesize' field by now. The new payload
|
||||
// size should be the sum of 'filesize' and the appended portion.
|
||||
assert(r->manifest->is_journal);
|
||||
assert(r->manifest->filesize != RHIZOME_SIZE_UNSET);
|
||||
@ -721,9 +723,8 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
}
|
||||
rhizome_manifest *mout = NULL;
|
||||
rhizome_bundle_result_free(&r->bundle_result);
|
||||
r->bundle_result.status = rhizome_manifest_finalise(r->manifest, &mout, !r->u.insert.force_new);
|
||||
r->bundle_result = rhizome_manifest_finalise(r->manifest, &mout, !r->u.insert.force_new);
|
||||
int http_status = 500;
|
||||
DEBUGF(rhizome, "r->bundle_result = %s", alloca_rhizome_bundle_result(r->bundle_result));
|
||||
switch (r->bundle_result.status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
if (mout && mout != r->manifest)
|
||||
@ -740,7 +741,8 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
http_status = 201;
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
r->bundle_result.message = "Error in manifest finalise";
|
||||
rhizome_bundle_result_free(&r->bundle_result);
|
||||
r->bundle_result = rhizome_bundle_result_static(RHIZOME_BUNDLE_STATUS_ERROR, "Error in manifest finalise");
|
||||
// fall through
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
@ -748,6 +750,7 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
if (mout && mout != r->manifest)
|
||||
rhizome_manifest_free(mout);
|
||||
rhizome_manifest_free(r->manifest);
|
||||
@ -755,7 +758,7 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
return http_request_rhizome_response(r, 0, NULL);
|
||||
}
|
||||
if (http_status == 500)
|
||||
FATALF("rhizome_manifest_finalise() returned status = %d", r->bundle_result.status);
|
||||
FATALF("rhizome_manifest_finalise() returned status=%d", r->bundle_result.status);
|
||||
rhizome_authenticate_author(r->manifest);
|
||||
http_request_response_static(&r->http, http_status, "rhizome-manifest/text",
|
||||
(const char *)r->manifest->manifestdata, r->manifest->manifest_all_bytes
|
||||
@ -971,6 +974,7 @@ static void render_manifest_headers(struct http_request *hr, strbuf sb)
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
case RHIZOME_BUNDLE_STATUS_MANIFEST_TOO_BIG:
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
strbuf_sprintf(sb, "Serval-Rhizome-Result-Bundle-Status-Code: %d\r\n", r->bundle_result.status);
|
||||
strbuf_puts(sb, "Serval-Rhizome-Result-Bundle-Status-Message: ");
|
||||
|
@ -888,6 +888,30 @@ test_RhizomeInsertMissingManifest() {
|
||||
assert_rhizome_list
|
||||
}
|
||||
|
||||
doc_RhizomeInsertManifestOverflow="HTTP RESTful insert Rhizome bundle, 'manifest' form part overflow"
|
||||
setup_RhizomeInsertManifestOverflow() {
|
||||
setup
|
||||
echo 'File one' >file1
|
||||
{ echo -n 'foo='; create_file --omit="$LF" - 8185; echo; } >file1.manifest
|
||||
}
|
||||
test_RhizomeInsertManifestOverflow() {
|
||||
execute curl \
|
||||
--silent --show-error --write-out '%{http_code}' \
|
||||
--output http.body \
|
||||
--dump-header http.header \
|
||||
--basic --user harry:potter \
|
||||
--form "manifest=@file1.manifest;type=rhizome/manifest;format=\"text+binarysig\"" \
|
||||
--form "payload=@file1" \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/insert"
|
||||
tfw_cat http.header http.body
|
||||
assertExitStatus == 0
|
||||
assertStdoutIs 422
|
||||
assertJq http.body 'contains({"http_status_code": 422})'
|
||||
assertJqGrep --ignore-case http.body '.http_status_message' 'manifest.*too.*big'
|
||||
executeOk_servald rhizome list
|
||||
assert_rhizome_list
|
||||
}
|
||||
|
||||
doc_RhizomeInsertIncorrectManifestType="HTTP RESTful insert Rhizome bundle, incorrect 'manifest' content type"
|
||||
setup_RhizomeInsertIncorrectManifestType() {
|
||||
setup
|
||||
|
Loading…
x
Reference in New Issue
Block a user