mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Improve Rhizome HTTP status codes
Also improve some reason phrases and test them
This commit is contained in:
parent
96055e6b6c
commit
6123503c15
@ -1118,7 +1118,7 @@ static int http_request_start_body(struct http_request *r)
|
||||
else if (r->verb == HTTP_VERB_POST) {
|
||||
if (r->request_header.content_length == CONTENT_LENGTH_UNKNOWN) {
|
||||
IDEBUGF(r->debug, "Malformed HTTP %s request: missing Content-Length header", r->verb);
|
||||
return 411;
|
||||
return 411; // Length Required
|
||||
}
|
||||
if (r->request_header.content_length == 0) {
|
||||
r->parser = http_request_reject_content;
|
||||
@ -1142,7 +1142,7 @@ static int http_request_start_body(struct http_request *r)
|
||||
} else {
|
||||
IDEBUGF(r->debug, "Unsupported HTTP %s request: Content-Type %s not supported",
|
||||
r->verb, alloca_mime_content_type(&r->request_header.content_type));
|
||||
return 415;
|
||||
return 415; // Unsupported Media Type
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1917,6 +1917,9 @@ static const char *httpResultString(int response_code)
|
||||
case 414: return "Request-URI Too Long";
|
||||
case 415: return "Unsupported Media Type";
|
||||
case 416: return "Requested Range Not Satisfiable";
|
||||
case 422: return "Unprocessable Entity";
|
||||
case 423: return "Locked";
|
||||
case 429: return "Too Many Requests";
|
||||
case 431: return "Request Header Fields Too Large";
|
||||
case 500: return "Internal Server Error";
|
||||
case 501: return "Not Implemented";
|
||||
|
@ -93,10 +93,16 @@ public class RhizomeCommon
|
||||
JSONTokeniser json = new JSONTokeniser(new InputStreamReader(conn.getErrorStream(), "UTF-8"));
|
||||
decodeRestfulStatus(status, json);
|
||||
}
|
||||
if (status.http_status_code == HttpURLConnection.HTTP_FORBIDDEN)
|
||||
switch (status.http_status_code) {
|
||||
case HttpURLConnection.HTTP_FORBIDDEN: // for crypto failure (missing secret)
|
||||
case HttpURLConnection.HTTP_NOT_FOUND: // for unknown BID
|
||||
case 422: // Unprocessable Entity, for invalid/malformed manifest
|
||||
case 423: // Locked, for database busy
|
||||
case 429: // Too Many Requests, for out of manifests
|
||||
return status;
|
||||
if (status.http_status_code == HttpURLConnection.HTTP_NOT_IMPLEMENTED)
|
||||
case HttpURLConnection.HTTP_NOT_IMPLEMENTED:
|
||||
throw new ServalDNotImplementedException(status.http_status_message);
|
||||
}
|
||||
throw new ServalDInterfaceException("unexpected HTTP response: " + status.http_status_code + " " + status.http_status_message);
|
||||
}
|
||||
|
||||
|
@ -1658,6 +1658,14 @@ next:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Unpacks a database MANIFESTS table row into a manifest structure.
|
||||
*
|
||||
* Returns RHIZOME_BUNDLE_STATUS_SAME if unpack succeeds
|
||||
* Returns RHIZOME_BUNDLE_STATUS_NEW if manifest is not found
|
||||
* Returns RHIZOME_BUNDLE_STATUS_ERROR on error
|
||||
* Returns RHIZOME_BUNDLE_STATUS_BUSY if the database is locked
|
||||
* Caller is responsible for allocating and freeing rhizome_manifest
|
||||
*/
|
||||
static enum rhizome_bundle_status unpack_manifest_row(sqlite_retry_state *retry, rhizome_manifest *m, sqlite3_stmt *statement)
|
||||
{
|
||||
int r=sqlite_step_retry(retry, statement);
|
||||
|
@ -107,22 +107,22 @@ static int rhizome_direct_import_end(struct http_request *hr)
|
||||
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");
|
||||
http_request_simple_response(&r->http, 200, "Bundle already imported"); // OK
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
http_request_simple_response(&r->http, 403, "Newer bundle already stored");
|
||||
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, 403, "Manifest is 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, 403, "Manifest is inconsistent with file");
|
||||
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");
|
||||
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, 403, "Not enough space");
|
||||
http_request_simple_response(&r->http, 202, "Not enough space"); // Accepted
|
||||
return 0;
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
|
@ -75,22 +75,28 @@ static int http_request_rhizome_response(struct httpd_request *r, uint16_t resul
|
||||
uint16_t rhizome_result = 0;
|
||||
switch (r->bundle_status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
rhizome_result = 201; // Created
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
case RHIZOME_BUNDLE_STATUS_DUPLICATE:
|
||||
rhizome_result = 201;
|
||||
rhizome_result = 200; // OK
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
case RHIZOME_BUNDLE_STATUS_NO_ROOM:
|
||||
rhizome_result = 200;
|
||||
case RHIZOME_BUNDLE_STATUS_OLD:
|
||||
rhizome_result = 202; // Accepted
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
rhizome_result = 403; // Forbidden
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_INVALID:
|
||||
case RHIZOME_BUNDLE_STATUS_FAKE:
|
||||
case RHIZOME_BUNDLE_STATUS_INCONSISTENT:
|
||||
case RHIZOME_BUNDLE_STATUS_READONLY:
|
||||
rhizome_result = 403;
|
||||
rhizome_result = 422; // Unprocessable Entity
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
rhizome_result = 423; // Locked
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
rhizome_result = 500;
|
||||
break;
|
||||
}
|
||||
@ -118,12 +124,14 @@ static int http_request_rhizome_response(struct httpd_request *r, uint16_t resul
|
||||
break;
|
||||
case RHIZOME_PAYLOAD_STATUS_TOO_BIG:
|
||||
case RHIZOME_PAYLOAD_STATUS_EVICTED:
|
||||
rhizome_result = 200;
|
||||
rhizome_result = 202; // Accepted
|
||||
break;
|
||||
case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL:
|
||||
rhizome_result = 403; // Forbidden
|
||||
break;
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE:
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_HASH:
|
||||
case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL:
|
||||
rhizome_result = 403;
|
||||
rhizome_result = 422; // Unprocessable Entity
|
||||
break;
|
||||
case RHIZOME_PAYLOAD_STATUS_ERROR:
|
||||
rhizome_result = 500;
|
||||
@ -146,9 +154,9 @@ static int http_request_rhizome_response(struct httpd_request *r, uint16_t resul
|
||||
}
|
||||
if (result == 0) {
|
||||
result = 500;
|
||||
message = NULL;
|
||||
message = "Result logic error";
|
||||
}
|
||||
http_request_simple_response(&r->http, result, message ? message : result == 403 ? "Rhizome operation failed" : NULL);
|
||||
http_request_simple_response(&r->http, result, message);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -159,7 +167,7 @@ static int restful_rhizome_bundlelist_json(httpd_request *r, const char *remaind
|
||||
r->http.response.header.content_type = CONTENT_TYPE_JSON;
|
||||
r->http.render_extra_headers = render_manifest_headers;
|
||||
if (!is_rhizome_http_enabled())
|
||||
return 403;
|
||||
return 404;
|
||||
int ret = authorize_restful(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -191,7 +199,7 @@ static int restful_rhizome_newsince(httpd_request *r, const char *remainder)
|
||||
{
|
||||
r->http.response.header.content_type = CONTENT_TYPE_JSON;
|
||||
if (!is_rhizome_http_enabled())
|
||||
return 403;
|
||||
return 404;
|
||||
int ret = authorize_restful(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -338,7 +346,7 @@ static int restful_rhizome_insert(httpd_request *r, const char *remainder)
|
||||
r->http.response.header.content_type = CONTENT_TYPE_JSON;
|
||||
r->http.render_extra_headers = render_manifest_headers;
|
||||
if (!is_rhizome_http_enabled())
|
||||
return 403;
|
||||
return 404;
|
||||
int ret = authorize_restful(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -389,7 +397,7 @@ static int insert_make_manifest(httpd_request *r)
|
||||
if (!r->u.insert.received_manifest)
|
||||
return http_response_form_part(r, "Missing", PART_MANIFEST, NULL, 0);
|
||||
if ((r->manifest = rhizome_new_manifest()) == NULL)
|
||||
return http_request_rhizome_response(r, 500, "Internal Error: Out of manifests", NULL);
|
||||
return http_request_rhizome_response(r, 429, "Manifest table full", NULL); // Too Many Requests
|
||||
assert(r->u.insert.manifest.length <= sizeof r->manifest->manifestdata);
|
||||
memcpy(r->manifest->manifestdata, r->u.insert.manifest.buffer, r->u.insert.manifest.length);
|
||||
r->manifest->manifest_all_bytes = r->u.insert.manifest.length;
|
||||
@ -403,7 +411,7 @@ static int insert_make_manifest(httpd_request *r)
|
||||
rhizome_manifest_free(r->manifest);
|
||||
r->manifest = NULL;
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INVALID;
|
||||
return http_request_rhizome_response(r, 403, "Malformed manifest", NULL);
|
||||
return http_request_rhizome_response(r, 422, "Malformed manifest", NULL); // Unprocessable Entity
|
||||
default:
|
||||
WHYF("rhizome_manifest_parse() returned %d", n);
|
||||
// fall through
|
||||
@ -427,19 +435,19 @@ static int insert_make_manifest(httpd_request *r)
|
||||
break;
|
||||
case RHIZOME_ADD_FILE_INVALID:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INVALID; // TODO separate enum for CLI return codes
|
||||
return http_request_rhizome_response(r, 403, message, NULL);
|
||||
return http_request_rhizome_response(r, 422, message, NULL); // Unprocessable Entity
|
||||
case RHIZOME_ADD_FILE_BUSY:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_BUSY; // TODO separate enum for CLI return codes
|
||||
return http_request_rhizome_response(r, 403, message, NULL);
|
||||
return http_request_rhizome_response(r, 423, message, NULL); // Locked
|
||||
case RHIZOME_ADD_FILE_REQUIRES_JOURNAL:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INVALID; // TODO separate enum for CLI return codes
|
||||
return http_request_rhizome_response(r, 403, message, NULL);
|
||||
return http_request_rhizome_response(r, 422, message, NULL); // Unprocessable Entity
|
||||
case RHIZOME_ADD_FILE_INVALID_FOR_JOURNAL:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INVALID; // TODO separate enum for CLI return codes
|
||||
return http_request_rhizome_response(r, 403, message, NULL);
|
||||
return http_request_rhizome_response(r, 422, message, NULL); // Unprocessable Entity
|
||||
case RHIZOME_ADD_FILE_WRONG_SECRET:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_READONLY; // TODO separate enum for CLI return codes
|
||||
return http_request_rhizome_response(r, 403, message, NULL);
|
||||
return http_request_rhizome_response(r, 403, message, NULL); // Forbidden
|
||||
}
|
||||
if (!result_valid)
|
||||
FATALF("result = %d", result);
|
||||
@ -518,7 +526,7 @@ static int insert_mime_part_header(struct http_request *hr, const struct mime_pa
|
||||
r->payload_status = rhizome_write_open_journal(&r->u.insert.write, r->manifest, 0, RHIZOME_SIZE_UNSET);
|
||||
if (r->payload_status == RHIZOME_PAYLOAD_STATUS_ERROR) {
|
||||
WHYF("rhizome_write_open_journal() returned %d %s", r->payload_status, rhizome_payload_status_message(r->payload_status));
|
||||
return 500;
|
||||
return http_request_rhizome_response(r, 500, "Error in payload open for write (journal)", NULL);
|
||||
}
|
||||
} else {
|
||||
// Note: r->manifest->filesize can be RHIZOME_SIZE_UNSET at this point, if the manifest did
|
||||
@ -526,7 +534,7 @@ static int insert_mime_part_header(struct http_request *hr, const struct mime_pa
|
||||
r->payload_status = rhizome_write_open_manifest(&r->u.insert.write, r->manifest);
|
||||
if (r->payload_status == RHIZOME_PAYLOAD_STATUS_ERROR) {
|
||||
WHYF("rhizome_write_open_manifest() returned %d %s", r->payload_status, rhizome_payload_status_message(r->payload_status));
|
||||
return 500;
|
||||
return http_request_rhizome_response(r, 500, "Error in payload open for write", NULL);
|
||||
}
|
||||
}
|
||||
switch (r->payload_status) {
|
||||
@ -575,7 +583,7 @@ static int insert_mime_part_body(struct http_request *hr, char *buf, size_t len)
|
||||
switch (r->payload_status) {
|
||||
case RHIZOME_PAYLOAD_STATUS_NEW:
|
||||
if (rhizome_write_buffer(&r->u.insert.write, (unsigned char *)buf, len) == -1)
|
||||
return 500;
|
||||
return http_request_rhizome_response(r, 500, "Error in payload write", NULL);
|
||||
break;
|
||||
case RHIZOME_PAYLOAD_STATUS_STORED:
|
||||
// TODO: calculate payload hash so it can be compared with stored payload
|
||||
@ -672,7 +680,7 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
{
|
||||
strbuf msg = strbuf_alloca(200);
|
||||
strbuf_sprintf(msg, "Payload size (%"PRIu64") contradicts manifest (filesize=%"PRIu64")", r->u.insert.payload_size, r->manifest->filesize);
|
||||
return http_request_rhizome_response(r, 403, "Inconsistent filesize", strbuf_str(msg));
|
||||
return http_request_rhizome_response(r, 422, "Inconsistent filesize", strbuf_str(msg)); // Unprocessable Entity
|
||||
}
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_HASH:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INCONSISTENT;
|
||||
@ -681,19 +689,19 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
strbuf_sprintf(msg, "Payload hash (%s) contradicts manifest (filehash=%s)",
|
||||
alloca_tohex_rhizome_filehash_t(r->u.insert.write.id),
|
||||
alloca_tohex_rhizome_filehash_t(r->manifest->filehash));
|
||||
return http_request_rhizome_response(r, 403, "Inconsistent filehash", strbuf_str(msg));
|
||||
return http_request_rhizome_response(r, 422, "Inconsistent filehash", strbuf_str(msg)); // Unprocessable Entity
|
||||
}
|
||||
case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_READONLY;
|
||||
return http_request_rhizome_response(r, 403, "Missing bundle secret", NULL);
|
||||
return http_request_rhizome_response(r, 403, "Missing bundle secret", NULL); // Forbidden
|
||||
case RHIZOME_PAYLOAD_STATUS_TOO_BIG:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_NO_ROOM;
|
||||
return http_request_rhizome_response(r, 403, "Bundle too big", NULL);
|
||||
return http_request_rhizome_response(r, 202, "Bundle too big", NULL); // Accepted
|
||||
case RHIZOME_PAYLOAD_STATUS_EVICTED:
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_NO_ROOM;
|
||||
return http_request_rhizome_response(r, 403, "Bundle evicted", NULL);
|
||||
return http_request_rhizome_response(r, 202, "Bundle evicted", NULL); // Accepted
|
||||
case RHIZOME_PAYLOAD_STATUS_ERROR:
|
||||
return http_request_rhizome_response(r, 500, NULL, NULL);
|
||||
return http_request_rhizome_response(r, 500, "Payload store error", NULL);
|
||||
}
|
||||
if (!status_valid)
|
||||
FATALF("rhizome_finish_store() returned status = %d", r->payload_status);
|
||||
@ -701,19 +709,20 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
const char *invalid_reason = rhizome_manifest_validate_reason(r->manifest);
|
||||
if (invalid_reason) {
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INVALID;
|
||||
return http_request_rhizome_response(r, 403, invalid_reason, NULL);
|
||||
return http_request_rhizome_response(r, 422, invalid_reason, NULL); // Unprocessable Entity
|
||||
}
|
||||
if (r->manifest->malformed) {
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_INVALID;
|
||||
return http_request_rhizome_response(r, 403, r->manifest->malformed, NULL);
|
||||
return http_request_rhizome_response(r, 422, r->manifest->malformed, NULL); // Unprocessable Entity
|
||||
}
|
||||
if (!r->manifest->haveSecret) {
|
||||
r->bundle_status = RHIZOME_BUNDLE_STATUS_READONLY;
|
||||
return http_request_rhizome_response(r, 403, "Missing bundle secret", NULL);
|
||||
return http_request_rhizome_response(r, 403, "Missing bundle secret", NULL); // Forbidden
|
||||
}
|
||||
rhizome_manifest *mout = NULL;
|
||||
r->bundle_status = rhizome_manifest_finalise(r->manifest, &mout, !r->u.insert.force_new);
|
||||
int result = 500;
|
||||
const char *message = NULL;
|
||||
DEBUGF(rhizome, "r->bundle_status=%d", r->bundle_status);
|
||||
switch (r->bundle_status) {
|
||||
case RHIZOME_BUNDLE_STATUS_NEW:
|
||||
@ -730,18 +739,20 @@ static int restful_rhizome_insert_end(struct http_request *hr)
|
||||
}
|
||||
result = 201;
|
||||
break;
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
message = "Error in manifest finalise";
|
||||
// fall through
|
||||
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_ERROR:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
if (mout && mout != r->manifest)
|
||||
rhizome_manifest_free(mout);
|
||||
rhizome_manifest_free(r->manifest);
|
||||
r->manifest = NULL;
|
||||
return http_request_rhizome_response(r, 0, NULL, NULL);
|
||||
return http_request_rhizome_response(r, 0, message, NULL);
|
||||
}
|
||||
if (result == 500)
|
||||
FATALF("rhizome_manifest_finalise() returned status = %d", r->bundle_status);
|
||||
@ -761,7 +772,7 @@ static int restful_rhizome_(httpd_request *r, const char *remainder)
|
||||
r->http.response.header.content_type = CONTENT_TYPE_JSON;
|
||||
r->http.render_extra_headers = render_manifest_headers;
|
||||
if (!is_rhizome_http_enabled())
|
||||
return 403;
|
||||
return 404;
|
||||
int ret = authorize_restful(&r->http);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -785,7 +796,7 @@ static int restful_rhizome_(httpd_request *r, const char *remainder)
|
||||
if (r->http.verb != HTTP_VERB_GET)
|
||||
return 405;
|
||||
if ((r->manifest = rhizome_new_manifest()) == NULL)
|
||||
return 500;
|
||||
return http_request_rhizome_response(r, 429, "Manifest table full", NULL); // Too Many Requests
|
||||
r->bundle_status = rhizome_retrieve_manifest(&bid, r->manifest);
|
||||
switch(r->bundle_status){
|
||||
case RHIZOME_BUNDLE_STATUS_SAME:
|
||||
@ -795,10 +806,15 @@ static int restful_rhizome_(httpd_request *r, const char *remainder)
|
||||
rhizome_manifest_free(r->manifest);
|
||||
r->manifest = NULL;
|
||||
break;
|
||||
default:
|
||||
case RHIZOME_BUNDLE_STATUS_BUSY:
|
||||
rhizome_manifest_free(r->manifest);
|
||||
return http_request_rhizome_response(r, 423, "Database busy", NULL); // Locked
|
||||
case RHIZOME_BUNDLE_STATUS_ERROR:
|
||||
rhizome_manifest_free(r->manifest);
|
||||
r->manifest = NULL;
|
||||
return 500;
|
||||
return http_request_rhizome_response(r, 500, "Manifest retrieve error", NULL);
|
||||
default: // should not return others
|
||||
FATALF("rhizome_retrieve_manifest() returned status = %d", r->bundle_status);
|
||||
}
|
||||
return handler(r, remainder);
|
||||
}
|
||||
@ -808,7 +824,7 @@ static int restful_rhizome_bid_rhm(httpd_request *r, const char *remainder)
|
||||
if (*remainder)
|
||||
return 404;
|
||||
if (r->manifest == NULL)
|
||||
return http_request_rhizome_response(r, 403, NULL, NULL);
|
||||
return http_request_rhizome_response(r, 404, "Bundle not found", NULL); // Not Found
|
||||
http_request_response_static(&r->http, 200, "rhizome-manifest/text",
|
||||
(const char *)r->manifest->manifestdata, r->manifest->manifest_all_bytes
|
||||
);
|
||||
@ -820,14 +836,14 @@ static int restful_rhizome_bid_raw_bin(httpd_request *r, const char *remainder)
|
||||
if (*remainder)
|
||||
return 404;
|
||||
if (r->manifest == NULL)
|
||||
return http_request_rhizome_response(r, 403, NULL, NULL);
|
||||
return http_request_rhizome_response(r, 404, "Bundle not found", NULL); // Not Found
|
||||
if (r->manifest->filesize == 0) {
|
||||
http_request_response_static(&r->http, 200, CONTENT_TYPE_BLOB, "", 0);
|
||||
return 1;
|
||||
}
|
||||
int ret = rhizome_response_content_init_filehash(r, &r->manifest->filehash);
|
||||
if (ret)
|
||||
return http_request_rhizome_response(r, ret, NULL, NULL);
|
||||
return ret;
|
||||
http_request_response_generated(&r->http, 200, CONTENT_TYPE_BLOB, rhizome_payload_content);
|
||||
return 1;
|
||||
}
|
||||
@ -837,7 +853,7 @@ static int restful_rhizome_bid_decrypted_bin(httpd_request *r, const char *remai
|
||||
if (*remainder)
|
||||
return 404;
|
||||
if (r->manifest == NULL)
|
||||
return http_request_rhizome_response(r, 403, NULL, NULL);
|
||||
return http_request_rhizome_response(r, 404, "Bundle not found", NULL); // Not Found
|
||||
if (r->manifest->filesize == 0) {
|
||||
// TODO use Content Type from manifest (once it is implemented)
|
||||
http_request_response_static(&r->http, 200, CONTENT_TYPE_BLOB, "", 0);
|
||||
@ -845,7 +861,7 @@ static int restful_rhizome_bid_decrypted_bin(httpd_request *r, const char *remai
|
||||
}
|
||||
int ret = rhizome_response_content_init_payload(r, r->manifest);
|
||||
if (ret)
|
||||
return http_request_rhizome_response(r, ret, NULL, NULL);
|
||||
return ret;
|
||||
// TODO use Content Type from manifest (once it is implemented)
|
||||
http_request_response_generated(&r->http, 200, CONTENT_TYPE_BLOB, rhizome_payload_content);
|
||||
return 1;
|
||||
@ -855,7 +871,7 @@ static int rhizome_response_content_init_read_state(httpd_request *r)
|
||||
{
|
||||
if (r->u.read_state.length == RHIZOME_SIZE_UNSET && rhizome_read(&r->u.read_state, NULL, 0)) {
|
||||
rhizome_read_close(&r->u.read_state);
|
||||
return 404;
|
||||
return http_request_rhizome_response(r, 404, "Payload not found", NULL);
|
||||
}
|
||||
assert(r->u.read_state.length != RHIZOME_SIZE_UNSET);
|
||||
int ret = http_response_init_content_range(r, r->u.read_state.length);
|
||||
@ -876,14 +892,14 @@ int rhizome_response_content_init_filehash(httpd_request *r, const rhizome_fileh
|
||||
case RHIZOME_PAYLOAD_STATUS_STORED:
|
||||
return rhizome_response_content_init_read_state(r);
|
||||
case RHIZOME_PAYLOAD_STATUS_NEW:
|
||||
return 403;
|
||||
return http_request_rhizome_response(r, 404, "Payload not found", NULL);
|
||||
case RHIZOME_PAYLOAD_STATUS_ERROR:
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE:
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_HASH:
|
||||
case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL:
|
||||
case RHIZOME_PAYLOAD_STATUS_TOO_BIG:
|
||||
case RHIZOME_PAYLOAD_STATUS_EVICTED:
|
||||
return -1;
|
||||
return http_request_rhizome_response(r, 500, "Payload read error", NULL);
|
||||
}
|
||||
FATALF("rhizome_open_read() returned status = %d", r->payload_status);
|
||||
}
|
||||
@ -900,14 +916,15 @@ int rhizome_response_content_init_payload(httpd_request *r, rhizome_manifest *m)
|
||||
case RHIZOME_PAYLOAD_STATUS_STORED:
|
||||
return rhizome_response_content_init_read_state(r);
|
||||
case RHIZOME_PAYLOAD_STATUS_NEW:
|
||||
return http_request_rhizome_response(r, 404, "Payload not found", NULL);
|
||||
case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL:
|
||||
return 403;
|
||||
return http_request_rhizome_response(r, 403, NULL, NULL); // Forbidden
|
||||
case RHIZOME_PAYLOAD_STATUS_ERROR:
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE:
|
||||
case RHIZOME_PAYLOAD_STATUS_WRONG_HASH:
|
||||
case RHIZOME_PAYLOAD_STATUS_TOO_BIG:
|
||||
case RHIZOME_PAYLOAD_STATUS_EVICTED:
|
||||
return -1;
|
||||
return http_request_rhizome_response(r, 500, "Payload read error", NULL);
|
||||
}
|
||||
FATALF("rhizome_open_decrypt_read() returned status = %d", r->payload_status);
|
||||
}
|
||||
|
@ -979,7 +979,9 @@ enum rhizome_payload_status rhizome_store_payload_file(rhizome_manifest *m, cons
|
||||
return rhizome_finish_store(&write, m, status);
|
||||
}
|
||||
|
||||
/* Return RHIZOME_PAYLOAD_STATUS_STORED if file blob found, RHIZOME_PAYLOAD_STATUS_NEW if not found.
|
||||
/* Returns RHIZOME_PAYLOAD_STATUS_STORED if file blob found
|
||||
* Returns RHIZOME_PAYLOAD_STATUS_NEW if not found
|
||||
* Returns RHIZOME_PAYLOAD_STATUS_ERROR if unexpected error
|
||||
*/
|
||||
enum rhizome_payload_status rhizome_open_read(struct rhizome_read *read, const rhizome_filehash_t *hashp)
|
||||
{
|
||||
|
@ -344,12 +344,13 @@ test_RhizomeManifestNonexist() {
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/$BID_NONEXISTENT.rhm"
|
||||
tfw_cat http.headers http.content
|
||||
assertStdoutIs 403
|
||||
assertStdoutIs 404
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Code: 0$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Message: .*bundle new to store.*$CR\$"
|
||||
assertGrep --matches=0 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Code:"
|
||||
assertGrep --matches=0 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Message:"
|
||||
assertJq http.content 'contains({"http_status_code": 403})'
|
||||
assertJq http.content 'contains({"http_status_code": 404})'
|
||||
assertJq http.content 'contains({"http_status_message": "Bundle not found"})'
|
||||
assertJq http.content 'contains({"rhizome_bundle_status_code": 0})'
|
||||
assertJqGrep --ignore-case http.content '.rhizome_bundle_status_message' "bundle new to store"
|
||||
}
|
||||
@ -392,12 +393,13 @@ test_RhizomePayloadRawNonexistManifest() {
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/$BID_NONEXISTENT/raw.bin"
|
||||
tfw_cat http.headers http.content
|
||||
assertStdoutIs 403
|
||||
assertStdoutIs 404
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Code: 0$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Message: .*bundle new to store.*$CR\$"
|
||||
assertGrep --matches=0 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Code:"
|
||||
assertGrep --matches=0 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Message:"
|
||||
assertJq http.content 'contains({"http_status_code": 403})'
|
||||
assertJq http.content 'contains({"http_status_code": 404})'
|
||||
assertJq http.content 'contains({"http_status_message": "Bundle not found"})'
|
||||
assertJq http.content 'contains({"rhizome_bundle_status_code": 0})'
|
||||
assertJqGrep --ignore-case http.content '.rhizome_bundle_status_message' "bundle new to store"
|
||||
}
|
||||
@ -419,12 +421,13 @@ test_RhizomePayloadRawNonexistPayload() {
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/${BID[0]}/raw.bin"
|
||||
tfw_cat http.headers http.content
|
||||
assertStdoutIs 403
|
||||
assertStdoutIs 404
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Code: 1$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Message: .*bundle already in store.*$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Code: 1$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Message: .*payload new to store.*$CR\$"
|
||||
assertJq http.content 'contains({"http_status_code": 403})'
|
||||
assertJq http.content 'contains({"http_status_code": 404})'
|
||||
assertJq http.content 'contains({"http_status_message": "Payload not found"})'
|
||||
assertJq http.content 'contains({"rhizome_bundle_status_code": 1})'
|
||||
assertJqGrep --ignore-case http.content '.rhizome_bundle_status_message' "bundle already in store"
|
||||
assertJq http.content 'contains({"rhizome_payload_status_code": 1})'
|
||||
@ -495,12 +498,13 @@ test_RhizomePayloadDecryptedNonexistManifest() {
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/$BID_NONEXISTENT/decrypted.bin"
|
||||
tfw_cat http.headers http.content
|
||||
assertStdoutIs 403
|
||||
assertStdoutIs 404
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Code: 0$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Message: .*bundle new to store.*$CR\$"
|
||||
assertGrep --matches=0 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Code:"
|
||||
assertGrep --matches=0 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Message:"
|
||||
assertJq http.content 'contains({"http_status_code": 403})'
|
||||
assertJq http.content 'contains({"http_status_code": 404})'
|
||||
assertJq http.content 'contains({"http_status_message": "Bundle not found"})'
|
||||
assertJq http.content 'contains({"rhizome_bundle_status_code": 0})'
|
||||
assertJqGrep --ignore-case http.content '.rhizome_bundle_status_message' "bundle new to store"
|
||||
}
|
||||
@ -522,12 +526,13 @@ test_RhizomePayloadDecryptedNonexistPayload() {
|
||||
--basic --user harry:potter \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/${BID[0]}/decrypted.bin"
|
||||
tfw_cat http.headers http.content
|
||||
assertStdoutIs 403
|
||||
assertStdoutIs 404
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Code: 1$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Bundle-Status-Message: .*bundle already in store.*$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Code: 1$CR\$"
|
||||
assertGrep --matches=1 --ignore-case http.headers$n "^Serval-Rhizome-Result-Payload-Status-Message: .*payload new to store.*$CR\$"
|
||||
assertJq http.content 'contains({"http_status_code": 403})'
|
||||
assertJq http.content 'contains({"http_status_code": 404})'
|
||||
assertJq http.content 'contains({"http_status_message": "Payload not found"})'
|
||||
assertJq http.content 'contains({"rhizome_bundle_status_code": 1})'
|
||||
assertJqGrep --ignore-case http.content '.rhizome_bundle_status_message' "bundle already in store"
|
||||
assertJq http.content 'contains({"rhizome_payload_status_code": 1})'
|
||||
@ -972,8 +977,9 @@ test_RhizomeInsertJournalForbidden() {
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/insert"
|
||||
tfw_cat http.header http.body
|
||||
assertExitStatus == 0
|
||||
assertStdoutIs 403
|
||||
assertJq http.body 'contains({"http_status_code": 403})'
|
||||
assertStdoutIs 422
|
||||
assertJq http.body 'contains({"http_status_code": 422})'
|
||||
assertJq http.body 'contains({"http_status_message": "Cannot add a journal bundle (use append instead)"})'
|
||||
assertJqGrep --ignore-case http.body '.http_status_message' 'cannot add.*journal'
|
||||
executeOk_servald rhizome list
|
||||
assert_rhizome_list
|
||||
@ -1097,8 +1103,9 @@ test_RhizomeInsertIncorrectFilesize() {
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/insert"
|
||||
tfw_cat http.header http.body
|
||||
assertExitStatus == 0
|
||||
assertStdoutIs 403
|
||||
assertJq http.body 'contains({"http_status_code": 403})'
|
||||
assertStdoutIs 422
|
||||
assertJq http.body 'contains({"http_status_code": 422})'
|
||||
assertJq http.body 'contains({"http_status_message": "Inconsistent filesize"})'
|
||||
assertJq http.body 'contains({"rhizome_payload_status_code": 3})'
|
||||
assertJqGrep --ignore-case http.body '.rhizome_payload_status_message' 'payload size.*contradicts manifest'
|
||||
execute curl \
|
||||
@ -1111,8 +1118,9 @@ test_RhizomeInsertIncorrectFilesize() {
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/insert"
|
||||
tfw_cat http.header http.body
|
||||
assertExitStatus == 0
|
||||
assertStdoutIs 403
|
||||
assertJq http.body 'contains({"http_status_code": 403})'
|
||||
assertStdoutIs 422
|
||||
assertJq http.body 'contains({"http_status_code": 422})'
|
||||
assertJq http.body 'contains({"http_status_message": "Inconsistent filesize"})'
|
||||
assertJq http.body 'contains({"rhizome_payload_status_code": 3})'
|
||||
assertJqGrep --ignore-case http.body '.rhizome_payload_status_message' 'payload size.*contradicts manifest'
|
||||
executeOk_servald rhizome list
|
||||
@ -1136,8 +1144,9 @@ test_RhizomeInsertIncorrectFilehash() {
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/insert"
|
||||
tfw_cat http.header http.body
|
||||
assertExitStatus == 0
|
||||
assertStdoutIs 403
|
||||
assertJq http.body 'contains({"http_status_code": 403})'
|
||||
assertStdoutIs 422
|
||||
assertJq http.body 'contains({"http_status_code": 422})'
|
||||
assertJq http.body 'contains({"http_status_message": "Inconsistent filehash"})'
|
||||
assertJq http.body 'contains({"rhizome_payload_status_code": 4})'
|
||||
assertJqGrep --ignore-case http.body '.rhizome_payload_status_message' 'payload hash.*contradicts manifest'
|
||||
executeOk_servald rhizome list
|
||||
@ -1316,8 +1325,9 @@ test_RhizomeAppendNonJournalForbidden() {
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/append"
|
||||
tfw_cat http.header http.body
|
||||
assertExitStatus == 0
|
||||
assertStdoutIs 403
|
||||
assertJq http.body 'contains({"http_status_code": 403})'
|
||||
assertStdoutIs 422
|
||||
assertJq http.body 'contains({"http_status_code": 422})'
|
||||
assertJq http.body 'contains({"http_status_message": "Cannot append to a non-journal"})'
|
||||
assertJqGrep --ignore-case http.body '.http_status_message' 'cannot append.*non.*journal'
|
||||
executeOk_servald rhizome list
|
||||
assert_rhizome_list file1
|
||||
|
Loading…
Reference in New Issue
Block a user