mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
rhizome direct http transport now asks for response to enquiry when
enquiry received by server. Generating responses to enquiries not yet implemented. #9
This commit is contained in:
parent
bb0be86db3
commit
9a5dbbd14f
@ -378,6 +378,13 @@ typedef struct rhizome_http_request {
|
||||
|
||||
} rhizome_http_request;
|
||||
|
||||
struct http_response {
|
||||
unsigned int result_code;
|
||||
const char * content_type;
|
||||
unsigned long long content_length;
|
||||
const char * body;
|
||||
};
|
||||
|
||||
int rhizome_server_free_http_request(rhizome_http_request *r);
|
||||
int rhizome_server_http_send_bytes(rhizome_http_request *r);
|
||||
int rhizome_server_parse_http_request(rhizome_http_request *r);
|
||||
@ -474,6 +481,8 @@ rhizome_direct_sync_request
|
||||
void *transport_specific_state);
|
||||
int rhizome_direct_continue_sync_request(rhizome_direct_sync_request *r);
|
||||
int rhizome_direct_conclude_sync_request(rhizome_direct_sync_request *r);
|
||||
rhizome_direct_bundle_cursor *rhizome_direct_get_fill_response
|
||||
(unsigned char *buffer,int size);
|
||||
|
||||
typedef struct rhizome_direct_transport_state_http {
|
||||
int port;
|
||||
|
@ -255,6 +255,27 @@ int rhizome_direct_conclude_sync_request(rhizome_direct_sync_request *r)
|
||||
return 0;
|
||||
}
|
||||
|
||||
rhizome_direct_bundle_cursor *rhizome_direct_get_fill_response
|
||||
(unsigned char *buffer,int size)
|
||||
{
|
||||
if (size<10) return NULL;
|
||||
|
||||
rhizome_direct_bundle_cursor *c=calloc(sizeof(rhizome_direct_bundle_cursor),1);
|
||||
if (rhizome_direct_bundle_iterator_unpickle_range(c,buffer,10))
|
||||
{
|
||||
DEBUGF("Couldn't unpickle range");
|
||||
rhizome_direct_bundle_iterator_free(&c);
|
||||
return NULL;
|
||||
}
|
||||
DEBUGF("unpickled size_high=%lld, limit_size_high=%lld",
|
||||
c->size_high,c->limit_size_high);
|
||||
|
||||
rhizome_direct_bundle_iterator_free(&c);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int app_rhizome_direct_sync(int argc, const char *const *argv,
|
||||
struct command_line_option *o)
|
||||
{
|
||||
|
@ -44,6 +44,8 @@ int rhizome_direct_form_received(rhizome_http_request *r)
|
||||
*/
|
||||
|
||||
/* XXX process completed form based on the set of fields seen */
|
||||
if (!strcmp(r->path,"/rhizome/import"))
|
||||
{
|
||||
switch(r->fields_seen) {
|
||||
case RD_MIME_STATE_MANIFESTHEADERS
|
||||
|RD_MIME_STATE_DATAHEADERS:
|
||||
@ -65,10 +67,12 @@ int rhizome_direct_form_received(rhizome_http_request *r)
|
||||
/* clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
/* and 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
|
||||
import a bundle (or if we already have it).
|
||||
403 = forbidden, which might be appropriate if we refuse to accept it, e.g.,
|
||||
the import fails due to malformed data etc.
|
||||
(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.
|
||||
*/
|
||||
@ -77,10 +81,93 @@ int rhizome_direct_form_received(rhizome_http_request *r)
|
||||
default:
|
||||
/* Clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
}
|
||||
} else if (!strcmp(r->path,"/rhizome/enquiry")) {
|
||||
int fd=-1;
|
||||
char file[1024];
|
||||
switch(r->fields_seen) {
|
||||
case RD_MIME_STATE_DATAHEADERS:
|
||||
/* Read data buffer in, pass to rhizome direct for comparison with local
|
||||
rhizome database, and send back responses. */
|
||||
snprintf(file,1024,"rhizomedirect.%d.%s",r->alarm.poll.fd,"data");
|
||||
fd=open(file,O_RDONLY);
|
||||
if (fd == -1) {
|
||||
/* Clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
return rhizome_server_simple_http_response(r,500,"Couldn't read a file");
|
||||
}
|
||||
struct stat stat;
|
||||
if (fstat(fd,&stat)) {
|
||||
/* Clean up after ourselves */
|
||||
close(fd);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
return rhizome_server_simple_http_response(r,500,"Couldn't stat a file");
|
||||
}
|
||||
unsigned char *addr = mmap(NULL, stat.st_size, PROT_READ,
|
||||
MAP_FILE|MAP_SHARED, fd, 0);
|
||||
if (addr==MAP_FAILED) {
|
||||
/* Clean up after ourselves */
|
||||
close(fd);
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
return rhizome_server_simple_http_response(r,500,"Couldn't mmap() a file");
|
||||
}
|
||||
rhizome_direct_bundle_cursor *c=rhizome_direct_get_fill_response(addr,stat.st_size);
|
||||
munmap(addr,stat.st_size);
|
||||
close(fd);
|
||||
|
||||
if (c)
|
||||
{
|
||||
/* TODO: Write out_buffer as the body of the response.
|
||||
We should be able to do this using the async framework fairly easily.
|
||||
*/
|
||||
|
||||
int bytes=c->buffer_offset_bytes+c->buffer_used;
|
||||
r->buffer=malloc(bytes+1024);
|
||||
r->buffer_size=bytes+1024;
|
||||
r->buffer_offset=0;
|
||||
assert(r->buffer);
|
||||
|
||||
/* Write HTTP response header */
|
||||
struct http_response hr;
|
||||
hr.result_code=200;
|
||||
hr.content_type="binary/octet-stream";
|
||||
hr.content_length=bytes;
|
||||
r->request_type=0;
|
||||
rhizome_server_set_response(r,&hr);
|
||||
assert(r->buffer_offset<1024);
|
||||
|
||||
/* Now append body and send it back. */
|
||||
bcopy(c->buffer,&r->buffer[r->buffer_offset],bytes);
|
||||
r->buffer_length+=bytes;
|
||||
r->buffer_offset=0;
|
||||
|
||||
/* Clean up cursor after sending response */
|
||||
rhizome_direct_bundle_iterator_free(&c);
|
||||
/* Clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return rhizome_server_simple_http_response(r,500,"Could not get response to enquiry");
|
||||
}
|
||||
|
||||
/* Clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
break;
|
||||
default:
|
||||
/* Clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
|
||||
return rhizome_server_simple_http_response(r, 404, "/rhizome/enquiry requires 'data' field");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Clean up after ourselves */
|
||||
rhizome_direct_clear_temporary_files(r);
|
||||
/* Report error */
|
||||
return rhizome_server_simple_http_response(r, 500, "Something went wrong. Probably a missing data or manifest part, or invalid combination of URI and data/manifest provision.");
|
||||
|
||||
}
|
||||
|
@ -570,13 +570,6 @@ static const char *httpResultString(int response_code) {
|
||||
}
|
||||
}
|
||||
|
||||
struct http_response {
|
||||
unsigned int result_code;
|
||||
const char * content_type;
|
||||
unsigned long long content_length;
|
||||
const char * body;
|
||||
};
|
||||
|
||||
static strbuf strbuf_build_http_response(strbuf sb, const struct http_response *h)
|
||||
{
|
||||
strbuf_sprintf(sb, "HTTP/1.0 %03u %s\r\n", h->result_code, httpResultString(h->result_code));
|
||||
@ -588,7 +581,7 @@ static strbuf strbuf_build_http_response(strbuf sb, const struct http_response *
|
||||
return sb;
|
||||
}
|
||||
|
||||
static int rhizome_server_set_response(rhizome_http_request *r, const struct http_response *h)
|
||||
int rhizome_server_set_response(rhizome_http_request *r, const struct http_response *h)
|
||||
{
|
||||
strbuf b = strbuf_local((char *) r->buffer, r->buffer_size);
|
||||
strbuf_build_http_response(b, h);
|
||||
|
Loading…
Reference in New Issue
Block a user