Refactoring of Rhizome http server code so that we can supply a

different request parser, but otherwise share code between
rhizome transfers and rhizome direct. #9
This commit is contained in:
gardners 2012-08-28 14:32:12 +09:30
parent bde9d1c56a
commit 9d2aa61792
5 changed files with 77 additions and 76 deletions

View File

@ -153,7 +153,8 @@ schedule(&_sched_##X); }
/* Rhizome http server needs to know which callback to attach /* Rhizome http server needs to know which callback to attach
to client sockets, so provide it here, along with the name to to client sockets, so provide it here, along with the name to
appear in time accounting statistics. */ appear in time accounting statistics. */
rhizome_http_server_start(rhizome_client_poll,"rhizome_client_poll", rhizome_http_server_start(rhizome_server_parse_http_request,
"rhizome_server_parse_http_request",
RHIZOME_HTTP_PORT,RHIZOME_HTTP_PORT_MAX); RHIZOME_HTTP_PORT,RHIZOME_HTTP_PORT_MAX);
/* Pick next rhizome files to grab every few seconds /* Pick next rhizome files to grab every few seconds

View File

@ -302,3 +302,60 @@ int rhizome_ignore_manifest_check(rhizome_manifest *m,
int rhizome_suggest_queue_manifest_import(rhizome_manifest *m, int rhizome_suggest_queue_manifest_import(rhizome_manifest *m,
struct sockaddr_in *peerip); struct sockaddr_in *peerip);
typedef struct rhizome_http_request {
struct sched_ent alarm;
long long initiate_time; /* time connection was initiated */
/* The HTTP request as currently received */
int request_length;
#define RHIZOME_HTTP_REQUEST_MAXLEN 1024
char request[RHIZOME_HTTP_REQUEST_MAXLEN];
/* Nature of the request */
int request_type;
#define RHIZOME_HTTP_REQUEST_RECEIVING -1
#define RHIZOME_HTTP_REQUEST_FROMBUFFER 1
#define RHIZOME_HTTP_REQUEST_FILE 2
#define RHIZOME_HTTP_REQUEST_SUBSCRIBEDGROUPLIST 4
#define RHIZOME_HTTP_REQUEST_ALLGROUPLIST 8
#define RHIZOME_HTTP_REQUEST_BUNDLESINGROUP 16
// manifests are small enough to send from a buffer
// #define RHIZOME_HTTP_REQUEST_BUNDLEMANIFEST 32
// for anything too big, we can just use a blob
#define RHIZOME_HTTP_REQUEST_BLOB 64
#define RHIZOME_HTTP_REQUEST_FAVICON 128
/* Local buffer of data to be sent.
If a RHIZOME_HTTP_REQUEST_FROMBUFFER, then the buffer is sent, and when empty
the request is closed.
Else emptying the buffer triggers a request to fetch more data. Only if no
more data is provided do we then close the request. */
unsigned char *buffer;
int buffer_size; // size
int buffer_length; // number of bytes loaded into buffer
int buffer_offset; // where we are between [0,buffer_length)
/* The source specification data which are used in different ways by different
request types */
char source[1024];
long long source_index;
long long source_count;
int source_record_size;
unsigned int source_flags;
sqlite3_blob *blob;
/* source_index used for offset in blob */
long long blob_end;
} rhizome_http_request;
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);
int rhizome_server_simple_http_response(rhizome_http_request *r, int result, const char *response);
int rhizome_server_http_response_header(rhizome_http_request *r, int result, const char *mime_type, unsigned long long bytes);
int rhizome_server_sql_query_fill_buffer(rhizome_http_request *r, char *table, char *column);
int rhizome_http_server_start(int (*http_parse_func)(rhizome_http_request *),
const char *http_parse_func_description,
int port_low,int port_high);

View File

@ -108,9 +108,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "serval.h" #include "serval.h"
#include "rhizome.h" #include "rhizome.h"
void rhizome_direct_client_poll(struct sched_ent *alarm) int rhizome_direct_parse_http_request(rhizome_http_request *r)
{ {
return 0;
} }
int app_rhizome_direct_server(int argc, const char *const *argv, int app_rhizome_direct_server(int argc, const char *const *argv,
@ -126,8 +126,8 @@ int app_rhizome_direct_server(int argc, const char *const *argv,
int port_high=confValueGetInt64Range("rhizome.direct.port_max",RHIZOME_DIRECT_PORT_MAX, int port_high=confValueGetInt64Range("rhizome.direct.port_max",RHIZOME_DIRECT_PORT_MAX,
port_low,65535); port_low,65535);
int r=rhizome_http_server_start(rhizome_direct_client_poll, int r=rhizome_http_server_start(rhizome_direct_parse_http_request,
"rhizome_direct_client_poll", "rhizome_direct_parse_http_request",
port_low,port_high); port_low,port_high);
return -1; return -1;

View File

@ -25,60 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "str.h" #include "str.h"
#include "rhizome.h" #include "rhizome.h"
typedef struct rhizome_http_request {
struct sched_ent alarm;
long long initiate_time; /* time connection was initiated */
/* The HTTP request as currently received */
int request_length;
#define RHIZOME_HTTP_REQUEST_MAXLEN 1024
char request[RHIZOME_HTTP_REQUEST_MAXLEN];
/* Nature of the request */
int request_type;
#define RHIZOME_HTTP_REQUEST_RECEIVING -1
#define RHIZOME_HTTP_REQUEST_FROMBUFFER 1
#define RHIZOME_HTTP_REQUEST_FILE 2
#define RHIZOME_HTTP_REQUEST_SUBSCRIBEDGROUPLIST 4
#define RHIZOME_HTTP_REQUEST_ALLGROUPLIST 8
#define RHIZOME_HTTP_REQUEST_BUNDLESINGROUP 16
// manifests are small enough to send from a buffer
// #define RHIZOME_HTTP_REQUEST_BUNDLEMANIFEST 32
// for anything too big, we can just use a blob
#define RHIZOME_HTTP_REQUEST_BLOB 64
#define RHIZOME_HTTP_REQUEST_FAVICON 128
/* Local buffer of data to be sent.
If a RHIZOME_HTTP_REQUEST_FROMBUFFER, then the buffer is sent, and when empty
the request is closed.
Else emptying the buffer triggers a request to fetch more data. Only if no
more data is provided do we then close the request. */
unsigned char *buffer;
int buffer_size; // size
int buffer_length; // number of bytes loaded into buffer
int buffer_offset; // where we are between [0,buffer_length)
/* The source specification data which are used in different ways by different
request types */
char source[1024];
long long source_index;
long long source_count;
int source_record_size;
unsigned int source_flags;
sqlite3_blob *blob;
/* source_index used for offset in blob */
long long blob_end;
} rhizome_http_request;
static int rhizome_server_free_http_request(rhizome_http_request *r);
static int rhizome_server_http_send_bytes(rhizome_http_request *r);
static int rhizome_server_parse_http_request(rhizome_http_request *r);
static int rhizome_server_simple_http_response(rhizome_http_request *r, int result, const char *response);
static int rhizome_server_http_response_header(rhizome_http_request *r, int result, const char *mime_type, unsigned long long bytes);
static int rhizome_server_sql_query_fill_buffer(rhizome_http_request *r, char *table, char *column);
#define RHIZOME_SERVER_MAX_LIVE_REQUESTS 32 #define RHIZOME_SERVER_MAX_LIVE_REQUESTS 32
struct sched_ent server_alarm; struct sched_ent server_alarm;
@ -96,8 +42,8 @@ unsigned short rhizome_http_server_port = 0;
static int rhizome_server_socket = -1; static int rhizome_server_socket = -1;
static time_ms_t rhizome_server_last_start_attempt = -1; static time_ms_t rhizome_server_last_start_attempt = -1;
void (*rhizome_http_client_poll_func)(struct sched_ent *)=NULL; int (*rhizome_http_parse_func)(rhizome_http_request *)=NULL;
const char *rhizome_http_client_poll_func_description="(null)"; const char *rhizome_http_parse_func_description="(null)";
// Format icon data using: // Format icon data using:
// od -vt u1 ~/Downloads/favicon.ico | cut -c9- | sed 's/ */,/g' // od -vt u1 ~/Downloads/favicon.ico | cut -c9- | sed 's/ */,/g'
@ -137,8 +83,8 @@ int rhizome_http_server_running()
Return 1 if the server is already started successfully. Return 1 if the server is already started successfully.
Return 2 if the server was not started because it is too soon since last failed attempt. Return 2 if the server was not started because it is too soon since last failed attempt.
*/ */
int rhizome_http_server_start(void (*client_poll_func)(struct sched_ent *), int rhizome_http_server_start(int (*parse_func)(rhizome_http_request *),
const char *client_poll_func_desc, const char *parse_func_desc,
int port_low,int port_high) int port_low,int port_high)
{ {
if (rhizome_server_socket != -1) if (rhizome_server_socket != -1)
@ -209,8 +155,8 @@ success:
INFOF("RHIZOME HTTP SERVER, START port=%d fd=%d", port, rhizome_server_socket); INFOF("RHIZOME HTTP SERVER, START port=%d fd=%d", port, rhizome_server_socket);
/* Remember which function to call when handling client connections */ /* Remember which function to call when handling client connections */
rhizome_http_client_poll_func=client_poll_func; rhizome_http_parse_func=parse_func;
rhizome_http_client_poll_func_description=client_poll_func_desc; rhizome_http_parse_func_description=parse_func_desc;
rhizome_http_server_port = port; rhizome_http_server_port = port;
/* Add Rhizome HTTPd server to list of file descriptors to watch */ /* Add Rhizome HTTPd server to list of file descriptors to watch */
@ -248,7 +194,7 @@ void rhizome_client_poll(struct sched_ent *alarm)
r->request_length += bytes; r->request_length += bytes;
if (http_header_complete(r->request, r->request_length, bytes + 4)) { if (http_header_complete(r->request, r->request_length, bytes + 4)) {
/* We have the request. Now parse it to see if we can respond to it */ /* We have the request. Now parse it to see if we can respond to it */
rhizome_server_parse_http_request(r); if (rhizome_http_parse_func!=NULL) rhizome_http_parse_func(r);
} }
} else { } else {
if (debug & DEBUG_RHIZOME_TX) if (debug & DEBUG_RHIZOME_TX)
@ -316,7 +262,7 @@ void rhizome_server_poll(struct sched_ent *alarm)
} }
} }
static int rhizome_server_free_http_request(rhizome_http_request *r) int rhizome_server_free_http_request(rhizome_http_request *r)
{ {
unwatch(&r->alarm); unwatch(&r->alarm);
unschedule(&r->alarm); unschedule(&r->alarm);
@ -329,7 +275,7 @@ static int rhizome_server_free_http_request(rhizome_http_request *r)
return 0; return 0;
} }
static int rhizome_server_sql_query_http_response(rhizome_http_request *r, int rhizome_server_sql_query_http_response(rhizome_http_request *r,
char *column,char *table,char *query_body, char *column,char *table,char *query_body,
int bytes_per_row,int dehexP) int bytes_per_row,int dehexP)
{ {
@ -398,7 +344,7 @@ static int rhizome_server_sql_query_http_response(rhizome_http_request *r,
return rhizome_server_sql_query_fill_buffer(r, table, column); return rhizome_server_sql_query_fill_buffer(r, table, column);
} }
static int rhizome_server_sql_query_fill_buffer(rhizome_http_request *r, char *table, char *column) int rhizome_server_sql_query_fill_buffer(rhizome_http_request *r, char *table, char *column)
{ {
unsigned char blob_value[r->source_record_size*2+1]; unsigned char blob_value[r->source_record_size*2+1];
@ -501,7 +447,7 @@ int http_header_complete(const char *buf, size_t len, size_t tail)
return count == 2; return count == 2;
} }
static int rhizome_server_parse_http_request(rhizome_http_request *r) int rhizome_server_parse_http_request(rhizome_http_request *r)
{ {
/* Switching to writing, so update the call-back */ /* Switching to writing, so update the call-back */
r->alarm.poll.events=POLLOUT; r->alarm.poll.events=POLLOUT;
@ -637,7 +583,7 @@ static int rhizome_server_set_response(rhizome_http_request *r, const struct htt
return 0; return 0;
} }
static int rhizome_server_simple_http_response(rhizome_http_request *r, int result, const char *response) int rhizome_server_simple_http_response(rhizome_http_request *r, int result, const char *response)
{ {
struct http_response hr; struct http_response hr;
hr.result_code = result; hr.result_code = result;
@ -647,7 +593,7 @@ static int rhizome_server_simple_http_response(rhizome_http_request *r, int resu
return rhizome_server_set_response(r, &hr); return rhizome_server_set_response(r, &hr);
} }
static int rhizome_server_http_response_header(rhizome_http_request *r, int result, const char *mime_type, unsigned long long bytes) int rhizome_server_http_response_header(rhizome_http_request *r, int result, const char *mime_type, unsigned long long bytes)
{ {
struct http_response hr; struct http_response hr;
hr.result_code = result; hr.result_code = result;
@ -663,7 +609,7 @@ static int rhizome_server_http_response_header(rhizome_http_request *r, int resu
0: connection finished. 0: connection finished.
<0: an error occurred. <0: an error occurred.
*/ */
static int rhizome_server_http_send_bytes(rhizome_http_request *r) int rhizome_server_http_send_bytes(rhizome_http_request *r)
{ {
// keep writing until the write would block or we run out of data // keep writing until the write would block or we run out of data
while(r->request_type){ while(r->request_type){

View File

@ -1124,9 +1124,6 @@ extern int sigIoFlag;
void sigPipeHandler(int signal); void sigPipeHandler(int signal);
void sigIoHandler(int signal); void sigIoHandler(int signal);
int rhizome_http_server_start(void (*server_poll_func)(struct sched_ent *),
const char *server_poll_func_description,
int port_low,int port_high);
int overlay_mdp_setup_sockets(); int overlay_mdp_setup_sockets();
int schedule(struct sched_ent *alarm); int schedule(struct sched_ent *alarm);