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:
Andrew Bettison 2012-10-02 17:15:14 +09:30
parent cc9cb8d827
commit 5fed0460e1
5 changed files with 57 additions and 68 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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:

View File

@ -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);
}
}

View File

@ -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"