|
|
|
@ -52,6 +52,7 @@ struct http_request
|
|
|
|
|
struct buffered_write* response_body_buffer;
|
|
|
|
|
struct header* response_headers;
|
|
|
|
|
bool sent_response_headers;
|
|
|
|
|
size_t unread_post_content;
|
|
|
|
|
|
|
|
|
|
// Memory holds
|
|
|
|
|
char* first_line;
|
|
|
|
@ -115,22 +116,31 @@ static void request_fiber_entry()
|
|
|
|
|
req->levels_to_root = depth;
|
|
|
|
|
|
|
|
|
|
int length;
|
|
|
|
|
int content_length = 0;
|
|
|
|
|
do {
|
|
|
|
|
n = 0;
|
|
|
|
|
getline_stripped( &ptr, &n, f );
|
|
|
|
|
length = strlen(ptr);
|
|
|
|
|
if( length > 0 ) {
|
|
|
|
|
/*
|
|
|
|
|
struct header* h = (struct header*)malloc(sizeof(struct header));
|
|
|
|
|
h->next = NULL;
|
|
|
|
|
int pos = index( ptr, ':' )
|
|
|
|
|
*/
|
|
|
|
|
char* value;
|
|
|
|
|
char* key = strtok_r( ptr, ":", &value );
|
|
|
|
|
while( *value == ' ' ) { ++value; }
|
|
|
|
|
|
|
|
|
|
printf( "Header: '%s' (%d)\n", ptr, length );
|
|
|
|
|
struct header* h = (struct header*)malloc(sizeof(struct header));
|
|
|
|
|
h->next = req->request_headers;
|
|
|
|
|
h->key = key;
|
|
|
|
|
h->value = value;
|
|
|
|
|
printf( "Header: %s: %s\n", h->key, h->value );
|
|
|
|
|
req->request_headers = h;
|
|
|
|
|
|
|
|
|
|
if( 0 == strcmp("Content-Length", key ) ) {
|
|
|
|
|
sscanf( value, "%u", &content_length );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free(ptr);
|
|
|
|
|
} while( length > 0 );
|
|
|
|
|
|
|
|
|
|
req->unread_post_content = content_length;
|
|
|
|
|
|
|
|
|
|
req->handler( req, req->handler_data );
|
|
|
|
|
|
|
|
|
|
fflush( req->response_body );
|
|
|
|
@ -212,6 +222,16 @@ static ssize_t http_request_read( void* cookie, char* buf, size_t size )
|
|
|
|
|
{
|
|
|
|
|
struct http_request* req = (struct http_request*)cookie;
|
|
|
|
|
|
|
|
|
|
if( req->unread_post_content == -1 ) {
|
|
|
|
|
size = 1;
|
|
|
|
|
} else if( req->unread_post_content == 0 ) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
if( size > req->unread_post_content ) {
|
|
|
|
|
size = req->unread_post_content;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct io_bytes_args args;
|
|
|
|
|
args.fd = req->sock;
|
|
|
|
|
args.failed = false;
|
|
|
|
@ -231,6 +251,10 @@ static ssize_t http_request_read( void* cookie, char* buf, size_t size )
|
|
|
|
|
http_request_call_nonblock( ready, NULL );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( req->unread_post_content != -1 ) {
|
|
|
|
|
req->unread_post_content -= args.size_read;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return args.size_read;
|
|
|
|
|
}
|
|
|
|
|
static ssize_t http_request_write_body( struct http_request* req, const char* buf, size_t size )
|
|
|
|
@ -316,10 +340,15 @@ static ssize_t http_request_body_write( void* cookie, const char* buf, size_t si
|
|
|
|
|
static int http_request_body_close( void* cookie )
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
static int http_request_seek( void* cookie, off64_t*, int )
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cookie_io_functions_t http_response_functions = {
|
|
|
|
|
.read = http_request_read,
|
|
|
|
|
.write = http_request_body_write,
|
|
|
|
|
.seek = NULL,
|
|
|
|
|
.seek = http_request_seek,
|
|
|
|
|
.close = http_request_body_close,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -343,6 +372,7 @@ struct http_request* http_request_new( ucontext_t* main, int sock, const char* r
|
|
|
|
|
req->sent_response_headers = false;
|
|
|
|
|
req->chunked_body = false;
|
|
|
|
|
req->response_size = -1;
|
|
|
|
|
req->unread_post_content = -1;
|
|
|
|
|
|
|
|
|
|
req->response_body = fopencookie( (void*)req, "w+", http_response_functions );
|
|
|
|
|
|
|
|
|
@ -374,6 +404,14 @@ void http_request_release( struct http_request* req )
|
|
|
|
|
{
|
|
|
|
|
printf( "closing socket %d\n", req->sock );
|
|
|
|
|
close( req->sock );
|
|
|
|
|
|
|
|
|
|
for( struct header* iter = req->request_headers; iter; ) {
|
|
|
|
|
struct header* next = iter->next;
|
|
|
|
|
free(iter->key);
|
|
|
|
|
free(iter);
|
|
|
|
|
iter = next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free( req->first_line );
|
|
|
|
|
free( req->context.uc_stack.ss_sp );
|
|
|
|
|
free( req->remote_addr );
|
|
|
|
|