mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Issue #9, 'rhizomeprotocol' HttpImport test now passes
Any HTTP client can import a bundle into Rhizome using a PUSH request.
This commit is contained in:
parent
cc9cb8d827
commit
5fed0460e1
77
rhizome.c
77
rhizome.c
@ -41,60 +41,63 @@ int rhizome_enabled()
|
||||
return rhizome_enabled_flag;
|
||||
}
|
||||
|
||||
/* Import a bundle from the inbox folder. The bundle is contained a pair of files, one containing
|
||||
the manifest and the optional other containing the payload.
|
||||
|
||||
The logic is all in rhizome_add_manifest(). This function just wraps that function and manages
|
||||
file and object buffers and lifetimes.
|
||||
/* Import a bundle from a pair of files, one containing the manifest and the optional other
|
||||
containing the payload. The logic is all in rhizome_bundle_import(). This function just wraps
|
||||
that function and manages file and object buffers and lifetimes.
|
||||
*/
|
||||
|
||||
int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out,
|
||||
const char *manifest_path, int ttl)
|
||||
int rhizome_bundle_import_files(const char *manifest_path, const char *payload_path, int ttl)
|
||||
{
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("rhizome_bundle_import(m_in=%p, m_out=%p, manifest_path=%s, ttl=%d)",
|
||||
m_in, m_out,
|
||||
DEBUGF("(manifest_path=%s, payload_path=%s, ttl=%d)",
|
||||
manifest_path ? alloca_str_toprint(manifest_path) : "NULL",
|
||||
payload_path ? alloca_str_toprint(payload_path) : "NULL",
|
||||
ttl
|
||||
);
|
||||
if (m_out)
|
||||
*m_out = NULL;
|
||||
/* Read manifest file if no manifest was given */
|
||||
rhizome_manifest *m = m_in;
|
||||
if (!m_in) {
|
||||
if (!manifest_path)
|
||||
return WHY("No manifest supplied");
|
||||
m = rhizome_new_manifest();
|
||||
if (!m)
|
||||
return WHY("Out of manifests");
|
||||
if (rhizome_read_manifest_file(m, manifest_path, 0 /* file not buffer */) == -1) {
|
||||
rhizome_manifest_free(m);
|
||||
return WHY("Could not read manifest file");
|
||||
} else if (rhizome_manifest_verify(m)) {
|
||||
rhizome_manifest_free(m);
|
||||
return WHY("Could not verify manifest file");
|
||||
}
|
||||
if (!manifest_path)
|
||||
return WHY("No manifest supplied");
|
||||
int ret = 0;
|
||||
rhizome_manifest *m = rhizome_new_manifest();
|
||||
if (!m)
|
||||
ret = WHY("Out of manifests");
|
||||
else if (rhizome_read_manifest_file(m, manifest_path, 0 /* file not buffer */) == -1)
|
||||
ret = WHY("Could not read manifest file");
|
||||
else if (rhizome_manifest_verify(m))
|
||||
ret = WHY("Verification of manifest file failed");
|
||||
else {
|
||||
m->dataFileName = strdup(payload_path);
|
||||
if (rhizome_manifest_check_file(m))
|
||||
ret = WHY("Payload does not belong to manifest");
|
||||
else
|
||||
ret = rhizome_bundle_import(m, ttl);
|
||||
}
|
||||
if (m)
|
||||
rhizome_manifest_free(m);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Import a bundle from a finalised manifest struct. The dataFileName element must give the path
|
||||
of a readable file containing the payload unless the payload is null (zero length). The logic is
|
||||
all in rhizome_add_manifest(). This function just wraps that function and manages object buffers
|
||||
and lifetimes.
|
||||
*/
|
||||
|
||||
int rhizome_bundle_import(rhizome_manifest *m, int ttl)
|
||||
{
|
||||
if (debug & DEBUG_RHIZOME)
|
||||
DEBUGF("(m=%p, ttl=%d)", m, ttl);
|
||||
/* Add the manifest and its payload to the Rhizome database. */
|
||||
if (m->fileLength > 0 && !(m->dataFileName && m->dataFileName[0]))
|
||||
return WHY("Missing data file name");
|
||||
if (rhizome_manifest_check_file(m))
|
||||
return WHY("File does not belong to manifest");
|
||||
int ret = rhizome_manifest_check_duplicate(m, NULL);
|
||||
if (ret == 0)
|
||||
if (ret == 0) {
|
||||
ret = rhizome_add_manifest(m, ttl);
|
||||
if (ret == -1) {
|
||||
WHY("rhizome_add_manifest() failed");
|
||||
} else {
|
||||
if (manifest_path && rhizome_write_manifest_file(m, manifest_path))
|
||||
ret = WHYF("Could not write %s", manifest_path);
|
||||
if (ret == -1)
|
||||
WHY("rhizome_add_manifest() failed");
|
||||
}
|
||||
/* If the manifest structure was allocated in this function, and it is not being returned to the
|
||||
caller, then this function is responsible for freeing it */
|
||||
if (m_out)
|
||||
*m_out = m;
|
||||
else if (!m_in)
|
||||
rhizome_manifest_free(m);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,8 @@ int rhizome_store_bundle(rhizome_manifest *m);
|
||||
int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid);
|
||||
int rhizome_clean_payload(const char *fileidhex);
|
||||
int rhizome_store_file(rhizome_manifest *m,const unsigned char *key);
|
||||
int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out, const char *manifest_path, int ttl);
|
||||
int rhizome_bundle_import_files(const char *manifest_path, const char *payload_path, int ttl);
|
||||
int rhizome_bundle_import(rhizome_manifest *m, int ttl);
|
||||
|
||||
int rhizome_manifest_verify(rhizome_manifest *m);
|
||||
int rhizome_manifest_check_sanity(rhizome_manifest *m_in);
|
||||
|
@ -45,23 +45,13 @@ int rhizome_direct_form_received(rhizome_http_request *r)
|
||||
if (!strcmp(r->path,"/rhizome/import")) {
|
||||
switch(r->fields_seen) {
|
||||
case RD_MIME_STATE_MANIFESTHEADERS | RD_MIME_STATE_DATAHEADERS: {
|
||||
/* A bundle to import */
|
||||
strbuf cmd = strbuf_alloca(1024);
|
||||
strbuf_sprintf(cmd,
|
||||
"servald rhizome import bundle rhizomedirect.%d.data rhizomedirect.%d.manifest",
|
||||
r->alarm.poll.fd, r->alarm.poll.fd
|
||||
);
|
||||
DEBUGF("system(\"%s\")", strbuf_str(cmd));
|
||||
int status = system(strbuf_str(cmd));
|
||||
/* clean up after ourselves */
|
||||
/* Got a bundle to import */
|
||||
strbuf manifest_path = strbuf_alloca(50);
|
||||
strbuf payload_path = strbuf_alloca(50);
|
||||
strbuf_sprintf(manifest_path, "rhizomedirect.%d.manifest", r->alarm.poll.fd);
|
||||
strbuf_sprintf(payload_path, "rhizomedirect.%d.data", r->alarm.poll.fd);
|
||||
int ret = rhizome_bundle_import_files(strbuf_str(manifest_path), strbuf_str(payload_path), 1); // ttl = 1
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
if (status == -1) {
|
||||
WHYF_perror("system(\"%s\")", strbuf_str(cmd));
|
||||
return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command not executed.");
|
||||
}
|
||||
strbuf st = strbuf_alloca(100);
|
||||
strbuf_append_exit_status(st, status);
|
||||
DEBUGF("Import command %s", strbuf_str(st));
|
||||
/* 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
|
||||
@ -70,18 +60,13 @@ int rhizome_direct_form_received(rhizome_http_request *r)
|
||||
the import fails due to malformed data etc.
|
||||
(should probably also indicate if we have a newer version if possible)
|
||||
*/
|
||||
if (WIFEXITED(status)) {
|
||||
switch (WEXITSTATUS(status)) {
|
||||
case 0:
|
||||
return rhizome_server_simple_http_response(r, 201, "Bundle succesfully imported.");
|
||||
case 1:
|
||||
return rhizome_server_simple_http_response(r, 200, "Bundle already imported.");
|
||||
default:
|
||||
return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command failed.");
|
||||
}
|
||||
switch (ret) {
|
||||
case 0:
|
||||
return rhizome_server_simple_http_response(r, 201, "Bundle succesfully imported.");
|
||||
case 2:
|
||||
return rhizome_server_simple_http_response(r, 200, "Bundle already imported.");
|
||||
}
|
||||
WHY("should not reach here");
|
||||
return rhizome_server_simple_http_response(r, 500, "Server error: Internal bug.");
|
||||
return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command failed.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -388,7 +388,7 @@ void rhizome_import_received_bundle(struct rhizome_manifest *m)
|
||||
DEBUGF("manifest len=%d has %d signatories", m->manifest_bytes, m->sig_count);
|
||||
dump("manifest", m->manifestdata, m->manifest_all_bytes);
|
||||
}
|
||||
rhizome_bundle_import(m, NULL, NULL, m->ttl - 1 /* TTL */);
|
||||
rhizome_bundle_import(m, m->ttl - 1 /* TTL */);
|
||||
}
|
||||
|
||||
/* Verifies manifests as late as possible to avoid wasting time. */
|
||||
@ -707,7 +707,7 @@ int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peeri
|
||||
} else {
|
||||
if (debug & DEBUG_RHIZOME_RX)
|
||||
DEBUGF("We already have the file for this manifest; importing from manifest alone.");
|
||||
rhizome_bundle_import(m, NULL, NULL, m->ttl-1);
|
||||
rhizome_bundle_import(m, m->ttl-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ test_HttpImport() {
|
||||
"$addr_localhost:$PORTA/rhizome/import"
|
||||
tfw_cat http.headers http.output
|
||||
executeOk_servald rhizome list ''
|
||||
assert_rhizome_list README.WHYNOTSIPS
|
||||
assert_rhizome_list README.WHYNOTSIPS!
|
||||
}
|
||||
|
||||
doc_HttpAddLocal="Add file locally using HTTP, returns manifest"
|
||||
|
Loading…
Reference in New Issue
Block a user