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;
|
return rhizome_enabled_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Import a bundle from the inbox folder. The bundle is contained a pair of files, one containing
|
/* Import a bundle from a pair of files, one containing the manifest and the optional other
|
||||||
the manifest and the optional other containing the payload.
|
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.
|
||||||
The logic is all in rhizome_add_manifest(). 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,
|
int rhizome_bundle_import_files(const char *manifest_path, const char *payload_path, int ttl)
|
||||||
const char *manifest_path, int ttl)
|
|
||||||
{
|
{
|
||||||
if (debug & DEBUG_RHIZOME)
|
if (debug & DEBUG_RHIZOME)
|
||||||
DEBUGF("rhizome_bundle_import(m_in=%p, m_out=%p, manifest_path=%s, ttl=%d)",
|
DEBUGF("(manifest_path=%s, payload_path=%s, ttl=%d)",
|
||||||
m_in, m_out,
|
|
||||||
manifest_path ? alloca_str_toprint(manifest_path) : "NULL",
|
manifest_path ? alloca_str_toprint(manifest_path) : "NULL",
|
||||||
|
payload_path ? alloca_str_toprint(payload_path) : "NULL",
|
||||||
ttl
|
ttl
|
||||||
);
|
);
|
||||||
if (m_out)
|
|
||||||
*m_out = NULL;
|
|
||||||
/* Read manifest file if no manifest was given */
|
/* Read manifest file if no manifest was given */
|
||||||
rhizome_manifest *m = m_in;
|
if (!manifest_path)
|
||||||
if (!m_in) {
|
return WHY("No manifest supplied");
|
||||||
if (!manifest_path)
|
int ret = 0;
|
||||||
return WHY("No manifest supplied");
|
rhizome_manifest *m = rhizome_new_manifest();
|
||||||
m = rhizome_new_manifest();
|
if (!m)
|
||||||
if (!m)
|
ret = WHY("Out of manifests");
|
||||||
return WHY("Out of manifests");
|
else if (rhizome_read_manifest_file(m, manifest_path, 0 /* file not buffer */) == -1)
|
||||||
if (rhizome_read_manifest_file(m, manifest_path, 0 /* file not buffer */) == -1) {
|
ret = WHY("Could not read manifest file");
|
||||||
rhizome_manifest_free(m);
|
else if (rhizome_manifest_verify(m))
|
||||||
return WHY("Could not read manifest file");
|
ret = WHY("Verification of manifest file failed");
|
||||||
} else if (rhizome_manifest_verify(m)) {
|
else {
|
||||||
rhizome_manifest_free(m);
|
m->dataFileName = strdup(payload_path);
|
||||||
return WHY("Could not verify manifest file");
|
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. */
|
/* Add the manifest and its payload to the Rhizome database. */
|
||||||
if (m->fileLength > 0 && !(m->dataFileName && m->dataFileName[0]))
|
if (m->fileLength > 0 && !(m->dataFileName && m->dataFileName[0]))
|
||||||
return WHY("Missing data file name");
|
return WHY("Missing data file name");
|
||||||
if (rhizome_manifest_check_file(m))
|
if (rhizome_manifest_check_file(m))
|
||||||
return WHY("File does not belong to manifest");
|
return WHY("File does not belong to manifest");
|
||||||
int ret = rhizome_manifest_check_duplicate(m, NULL);
|
int ret = rhizome_manifest_check_duplicate(m, NULL);
|
||||||
if (ret == 0)
|
if (ret == 0) {
|
||||||
ret = rhizome_add_manifest(m, ttl);
|
ret = rhizome_add_manifest(m, ttl);
|
||||||
if (ret == -1) {
|
if (ret == -1)
|
||||||
WHY("rhizome_add_manifest() failed");
|
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 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;
|
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_manifest_add_group(rhizome_manifest *m,char *groupid);
|
||||||
int rhizome_clean_payload(const char *fileidhex);
|
int rhizome_clean_payload(const char *fileidhex);
|
||||||
int rhizome_store_file(rhizome_manifest *m,const unsigned char *key);
|
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_verify(rhizome_manifest *m);
|
||||||
int rhizome_manifest_check_sanity(rhizome_manifest *m_in);
|
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")) {
|
if (!strcmp(r->path,"/rhizome/import")) {
|
||||||
switch(r->fields_seen) {
|
switch(r->fields_seen) {
|
||||||
case RD_MIME_STATE_MANIFESTHEADERS | RD_MIME_STATE_DATAHEADERS: {
|
case RD_MIME_STATE_MANIFESTHEADERS | RD_MIME_STATE_DATAHEADERS: {
|
||||||
/* A bundle to import */
|
/* Got a bundle to import */
|
||||||
strbuf cmd = strbuf_alloca(1024);
|
strbuf manifest_path = strbuf_alloca(50);
|
||||||
strbuf_sprintf(cmd,
|
strbuf payload_path = strbuf_alloca(50);
|
||||||
"servald rhizome import bundle rhizomedirect.%d.data rhizomedirect.%d.manifest",
|
strbuf_sprintf(manifest_path, "rhizomedirect.%d.manifest", r->alarm.poll.fd);
|
||||||
r->alarm.poll.fd, 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
|
||||||
DEBUGF("system(\"%s\")", strbuf_str(cmd));
|
|
||||||
int status = system(strbuf_str(cmd));
|
|
||||||
/* clean up after ourselves */
|
|
||||||
rhizome_direct_clear_temporary_files(r);
|
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.
|
/* report back to caller.
|
||||||
200 = ok, which is probably appropriate for when we already had the bundle.
|
200 = ok, which is probably appropriate for when we already had the bundle.
|
||||||
201 = content created, which is probably appropriate for when we successfully
|
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.
|
the import fails due to malformed data etc.
|
||||||
(should probably also indicate if we have a newer version if possible)
|
(should probably also indicate if we have a newer version if possible)
|
||||||
*/
|
*/
|
||||||
if (WIFEXITED(status)) {
|
switch (ret) {
|
||||||
switch (WEXITSTATUS(status)) {
|
case 0:
|
||||||
case 0:
|
return rhizome_server_simple_http_response(r, 201, "Bundle succesfully imported.");
|
||||||
return rhizome_server_simple_http_response(r, 201, "Bundle succesfully imported.");
|
case 2:
|
||||||
case 1:
|
return rhizome_server_simple_http_response(r, 200, "Bundle already imported.");
|
||||||
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.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WHY("should not reach here");
|
return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command failed.");
|
||||||
return rhizome_server_simple_http_response(r, 500, "Server error: Internal bug.");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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);
|
DEBUGF("manifest len=%d has %d signatories", m->manifest_bytes, m->sig_count);
|
||||||
dump("manifest", m->manifestdata, m->manifest_all_bytes);
|
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. */
|
/* 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 {
|
} else {
|
||||||
if (debug & DEBUG_RHIZOME_RX)
|
if (debug & DEBUG_RHIZOME_RX)
|
||||||
DEBUGF("We already have the file for this manifest; importing from manifest alone.");
|
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"
|
"$addr_localhost:$PORTA/rhizome/import"
|
||||||
tfw_cat http.headers http.output
|
tfw_cat http.headers http.output
|
||||||
executeOk_servald rhizome list ''
|
executeOk_servald rhizome list ''
|
||||||
assert_rhizome_list README.WHYNOTSIPS
|
assert_rhizome_list README.WHYNOTSIPS!
|
||||||
}
|
}
|
||||||
|
|
||||||
doc_HttpAddLocal="Add file locally using HTTP, returns manifest"
|
doc_HttpAddLocal="Add file locally using HTTP, returns manifest"
|
||||||
|
Loading…
Reference in New Issue
Block a user