Issue #9, fix HTTP server "POST /rhizome/bundle"

Handle failure cases properly.  The HttpImport test now fails because the
"servald" executable is not found by the system(3) call -- need to give the
full path name, or avoid the use of system(3) altogether.
This commit is contained in:
Andrew Bettison 2012-09-28 17:53:20 +09:30
parent 4379be5c50
commit e51745e39d
2 changed files with 47 additions and 42 deletions

View File

@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "serval.h" #include "serval.h"
#include "rhizome.h" #include "rhizome.h"
#include "str.h" #include "str.h"
#include "strbuf.h"
#include "strbuf_helpers.h"
#include <assert.h> #include <assert.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -40,44 +42,47 @@ int rhizome_direct_clear_temporary_files(rhizome_http_request *r)
int rhizome_direct_form_received(rhizome_http_request *r) int rhizome_direct_form_received(rhizome_http_request *r)
{ {
/* XXX This needs to be implemented. if (!strcmp(r->path,"/rhizome/import")) {
For now we just put out a "no content" response that makes testing convenient
*/
/* XXX process completed form based on the set of fields seen */
if (!strcmp(r->path,"/rhizome/import"))
{
switch(r->fields_seen) { switch(r->fields_seen) {
case RD_MIME_STATE_MANIFESTHEADERS case RD_MIME_STATE_MANIFESTHEADERS | RD_MIME_STATE_DATAHEADERS: {
|RD_MIME_STATE_DATAHEADERS:
/* A bundle to import */ /* A bundle to import */
DEBUGF("Call bundle import for rhizomedata.%d.{data,file}", strbuf cmd = strbuf_alloca(1024);
r->alarm.poll.fd); strbuf_sprintf(cmd,
char cmd[1024];
snprintf(cmd,1024,
"servald rhizome import bundle rhizomedirect.%d.data rhizomedirect.%d.manifest", "servald rhizome import bundle rhizomedirect.%d.data rhizomedirect.%d.manifest",
r->alarm.poll.fd,r->alarm.poll.fd); r->alarm.poll.fd, r->alarm.poll.fd
cmd[1023]=0; );
int rv=system(cmd); DEBUGF("system(\"%s\")", strbuf_str(cmd));
int status=-1; int status = system(strbuf_str(cmd));
if (rv!=-1) status=WEXITSTATUS(rv);
DEBUGF("Import returned %d",status);
/* clean up after ourselves */ /* clean up after ourselves */
rhizome_direct_clear_temporary_files(r); rhizome_direct_clear_temporary_files(r);
/* and report back to caller. 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. 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
import a bundle (or if we already have it). import a bundle (or if we already have it).
403 = forbidden, which might be appropriate if we refuse to accept it, e.g., 403 = forbidden, which might be appropriate if we refuse to accept it, e.g.,
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)
For now we are just returning "no content" as a place-holder while debugging.
*/ */
rhizome_server_simple_http_response(r, 204, "Move along. Nothing to see."); 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.");
}
}
WHY("should not reach here");
return rhizome_server_simple_http_response(r, 500, "Server error: Internal bug.");
}
break; break;
default: default:
/* Clean up after ourselves */ /* Clean up after ourselves */
@ -217,7 +222,7 @@ int rhizome_direct_process_mime_line(rhizome_http_request *r,char *buffer,int co
int blankLine=0; int blankLine=0;
if (!strcmp(buffer,"\r\n")) blankLine=1; if (!strcmp(buffer,"\r\n")) blankLine=1;
DEBUGF("mime state: 0x%x, blankLine=%d, boundary=%d, EOF=%d, bytes=%d", DEBUGF("mime state 0x%x, blankLine=%d, boundary=%d, EOF=%d, bytes=%d",
r->source_flags,blankLine,boundaryLine,endOfForm,count); r->source_flags,blankLine,boundaryLine,endOfForm,count);
switch(r->source_flags) { switch(r->source_flags) {
case RD_MIME_STATE_INITIAL: case RD_MIME_STATE_INITIAL:
@ -226,7 +231,7 @@ int rhizome_direct_process_mime_line(rhizome_http_request *r,char *buffer,int co
case RD_MIME_STATE_PARTHEADERS: case RD_MIME_STATE_PARTHEADERS:
case RD_MIME_STATE_MANIFESTHEADERS: case RD_MIME_STATE_MANIFESTHEADERS:
case RD_MIME_STATE_DATAHEADERS: case RD_MIME_STATE_DATAHEADERS:
DEBUGF("mime line: %s",r->request); DEBUGF("mime line %s", alloca_str_toprint(r->request));
if (blankLine) { if (blankLine) {
/* End of headers */ /* End of headers */
if (r->source_flags==RD_MIME_STATE_PARTHEADERS) if (r->source_flags==RD_MIME_STATE_PARTHEADERS)

View File

@ -608,7 +608,7 @@ int rhizome_server_set_response(rhizome_http_request *r, const struct http_respo
r->buffer_offset = 0; r->buffer_offset = 0;
r->request_type |= RHIZOME_HTTP_REQUEST_FROMBUFFER; r->request_type |= RHIZOME_HTTP_REQUEST_FROMBUFFER;
if (debug & DEBUG_RHIZOME_TX) if (debug & DEBUG_RHIZOME_TX)
DEBUGF("Sending HTTP response: %s", alloca_toprint(120, (const char *)r->buffer, r->buffer_length)); DEBUGF("Sending HTTP response: %s", alloca_toprint(160, (const char *)r->buffer, r->buffer_length));
return 0; return 0;
} }