|
WEBBY - the embedded web server with many faces / objects in plain C Snapshot
|
#include "webby.h"#include "webbyimpl.h"#include <hutils/http.h>#include <string.h>#include <stdio.h>#include <cutils/properties.h>#include <butils/logg.h>Go to the source code of this file.
Classes | |
| struct | tagVIRTUAL_HOST_DEFINITION |
| struct | tagDATA_SINK_FILTER |
| struct | tagDATA_SINK_FILTER_CONNECTION_CONTEXT |
| struct | tagSERVLET_RUNNER_FILTER |
| struct | SERVLET_FILTER_CONNECTION_CONTEXT |
Defines | |
| #define | RESERVED_FOR_CHUNK_HEADER_SIZE 15 |
| #define | LAST_CHUNK_NOT_FIRST "\r\n0\r\n\r\n" |
| #define | LAST_CHUNK_NOT_FIRST_SIZE 7 |
| #define | LAST_CHUNK_FIRST "0\r\n\r\n" |
| #define | LAST_CHUNK_FIRST_SIZE 5 |
| #define | HTTP_100_CONTINUE_RESPONSE "HTTP/1.1 100 Continue\r\n\r\n" |
| #define | HTTP_100_CONTINUE_RESPONSE_LEN 25 |
| #define | HTTP_400_BAD_REQUEST "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n" |
| #define | HTTP_400_BAD_REQUEST_LEN 47 |
| #define | HTTP_404_NOT_FOUND "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n" |
| #define | HTTP_404_NOT_FOUND_LEN 45 |
| #define | HTTP_500_SERVER_ERROR "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n" |
| #define | HTTP_500_SERVER_ERROR_LEN 57 |
Typedefs | |
| typedef struct tagVIRTUAL_HOST_DEFINITION | VIRTUAL_HOST_DEFINITION |
| typedef struct tagDATA_SINK_FILTER | DATA_SINK_FILTER |
| typedef struct tagDATA_SINK_FILTER_CONNECTION_CONTEXT | DATA_SINK_FILTER_CONNECTION_CONTEXT |
| typedef struct tagSERVLET_RUNNER_FILTER | SERVLET_RUNNER_FILTER |
| typedef struct SERVLET_FILTER_CONNECTION_CONTEXT | SERVLET_FILTER_CONNECTION_CONTEXT |
Functions | |
| DATA_SINK_FILTER_CONNECTION_CONTEXT * | DATA_SINK_FILTER_CONNECTION_CONTEXT_init (void *impl_connection_ctx, BF *out_buf) |
| void | DATA_SINK_FILTER_CONNECTION_CONTEXT_free (DATA_SINK_FILTER_CONNECTION_CONTEXT *ctx) |
| static int | sink_req_header_parsed (HTTP_REQUEST *request, FILTER_CONTEXT *context) |
| static int | sink_req_data (HTTP_REQUEST *request, void *data, size_t data_size, FILTER_CONTEXT *context) |
| static int | sink_req_completed (HTTP_REQUEST *request, FILTER_CONTEXT *context) |
| static int | sink_on_response_header (HTTP_RESPONSE *response, FILTER_CONTEXT *context) |
| static int | sink_on_response_data (HTTP_RESPONSE *response, int is_chunk, RDATA rdata, FILTER_CONTEXT *context) |
| static int | sink_on_response_complete (HTTP_RESPONSE *response, FILTER_CONTEXT *context) |
| static int | sink_connection_close (FILTER_CONTEXT *context) |
| DATA_SINK_FILTER * | DATA_SINK_FILTER_init (WEBBY *server) |
| int | DATA_SINK_FILTER_add_vhost (DATA_SINK_FILTER *vhost_filter, const char *host, int port_num, size_t *vhost_idx) |
| int | DATA_SINK_FILTER_add_filter_to_vhost (DATA_SINK_FILTER *vhost_filter, size_t vhost_idx, HTTP_FILTER *new_filter) |
| SERVLET_FILTER_CONNECTION_CONTEXT * | SERVLET_FILTER_CONNECTION_CONTEXT_init (SERVLET_RUNNER_FILTER *rfilter) |
| static int | servlets_req_header_parsed (HTTP_REQUEST *request, FILTER_CONTEXT *context) |
| static int | servlets_req_on_message_data (HTTP_REQUEST *request, void *data, size_t data_size, FILTER_CONTEXT *context) |
| static int | servlets_req_finished (HTTP_REQUEST *request, FILTER_CONTEXT *context) |
| static int | servlets_connection_close (FILTER_CONTEXT *context) |
| SERVLET_RUNNER_FILTER * | SERVLET_RUNNER_FILTER_init () |
| void | SERVLET_RUNNER_FILTER_free (SERVLET_RUNNER_FILTER *servlets) |
| int | SERVLET_RUNNER_FILTER_add_servlet (SERVLET_RUNNER_FILTER *servlets, HTTP_SERVLET *servlet) |
| int | WEBBY_CONFIG_load (WEBBY_CONFIG *cfg, const char *file) |
| WEBBY * | WEBBY_init (WEBBY_CONFIG *cfg) |
| int | WEBBY_add_vhost (WEBBY *server, const char *host, int port_num, size_t *vhost_idx) |
| int | WEBBY_add_filter (WEBBY *server, size_t vhost_idx, HTTP_FILTER *filter) |
| int | WEBBY_add_servlet (WEBBY *server, HTTP_SERVLET *servlet) |
| int | WEBBY_run (WEBBY *server) |
| int | WEBBY_shutdown (WEBBY *server) |
| static int | http_header_parsed (HTTP_REQUEST *request, void *ctx) |
| static int | http_on_message_data (HTTP_REQUEST *request, void *data, size_t data_size, void *ctx) |
| static int | http_req_finished (HTTP_REQUEST *request, void *ctx) |
| WEBBY_CONNECTION * | WEBBY_new_connection (WEBBY *server, void *implconndata) |
| int | WEBBY_connection_data_received (WEBBY_CONNECTION *connection) |
| void | WEBBY_connection_close (WEBBY_CONNECTION *connection) |
| int | HTTP_response_start (HTTP_servlet_response *resp, int status, const char *mime_type, HTTP_servlet_response_type rtype, size_t length) |
| initiate an HTTP response | |
| int | HTTP_response_send (HTTP_servlet_response *resp, void *data, size_t size) |
| send response data when sending RESPONSE_CONTENT_LENGTH or RESPONSE_CONNECTION_CLOSE responses | |
| BF * | HTTP_response_get_chunk_buffer (HTTP_servlet_response *resp, size_t chunk_size) |
| returns buffer for sending chunks The buffer reserves enough space before start of buffer, in order to allow addition of chunk header before the sent daa | |
| int | HTTP_response_write_chunk (HTTP_servlet_response *resp, BF *bf) |
| send chunk from buffer The buffer must reserve enough space for the chunk header, before start of buffer | |
| int | HTTP_response_finish (HTTP_servlet_response *resp) |
| finish sending of response | |
| #define HTTP_100_CONTINUE_RESPONSE "HTTP/1.1 100 Continue\r\n\r\n" |
| #define HTTP_400_BAD_REQUEST "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n" |
| #define HTTP_404_NOT_FOUND "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n" |
| #define HTTP_500_SERVER_ERROR "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n" |
| typedef struct tagDATA_SINK_FILTER DATA_SINK_FILTER |
| typedef struct tagSERVLET_RUNNER_FILTER SERVLET_RUNNER_FILTER |
| typedef struct tagVIRTUAL_HOST_DEFINITION VIRTUAL_HOST_DEFINITION |
| int DATA_SINK_FILTER_add_filter_to_vhost | ( | DATA_SINK_FILTER * | vhost_filter, |
| size_t | vhost_idx, | ||
| HTTP_FILTER * | new_filter | ||
| ) |
Definition at line 313 of file webby.c.
{
size_t filter_idx;
VIRTUAL_HOST_DEFINITION *vhost;
HTTP_FILTER *last_filter;
HTTP_FILTER **tmp;
int is_default_vhost;
// get virtual host defnition
if (ARRAY_size( &vhost_filter->vhosts ) == 0) {
vhost = &vhost_filter->default_vhost;
is_default_vhost = 1;
} else {
vhost = (VIRTUAL_HOST_DEFINITION *) ARRAY_at( &vhost_filter->vhosts, vhost_idx );
is_default_vhost = 0;
}
if (!vhost) {
return -1;
}
// insert the new filter
if (ARRAY_push_back( &vhost_filter->server->filters, &new_filter, sizeof(void *) ) ) {
return -1;
}
filter_idx = ARRAY_size( &vhost_filter->server->filters ) - 1;
// update virtual host filter chain.
if (vhost->next_filter_idx == (size_t) -1) {
vhost->next_filter_idx = filter_idx;
vhost->last_filter_idx = filter_idx;
new_filter->next_request_filter_idx = (size_t) -1; ;
new_filter->next_response_filter_idx = 0;
if (is_default_vhost) {
vhost_filter->base.next_request_filter_idx = filter_idx;
vhost_filter->base.next_response_filter_idx = (size_t) -1;
}
} else {
new_filter->next_response_filter_idx = vhost->last_filter_idx;
new_filter->next_request_filter_idx = (size_t) -1;
tmp = (HTTP_FILTER **) ARRAY_at( &vhost_filter->server->filters, vhost->next_filter_idx );
last_filter = *tmp;
last_filter->next_request_filter_idx = filter_idx;
vhost->last_filter_idx = filter_idx;
}
return 0;
}
| int DATA_SINK_FILTER_add_vhost | ( | DATA_SINK_FILTER * | vhost_filter, |
| const char * | host, | ||
| int | port_num, | ||
| size_t * | vhost_idx | ||
| ) |
Definition at line 297 of file webby.c.
{
VIRTUAL_HOST_DEFINITION def;
def.host = strdup(host);
def.host_port = port_num;
def.next_filter_idx = def.last_filter_idx = (size_t) -1;
*vhost_idx = ARRAY_size( &vhost_filter->vhosts ) ;
if ( ARRAY_push_back( &vhost_filter->vhosts, &def, sizeof( VIRTUAL_HOST_DEFINITION ) ) ) {
return -1;
}
return 0;
}
| void DATA_SINK_FILTER_CONNECTION_CONTEXT_free | ( | DATA_SINK_FILTER_CONNECTION_CONTEXT * | ctx | ) |
| DATA_SINK_FILTER_CONNECTION_CONTEXT* DATA_SINK_FILTER_CONNECTION_CONTEXT_init | ( | void * | impl_connection_ctx, |
| BF * | out_buf | ||
| ) |
Definition at line 61 of file webby.c.
{
DATA_SINK_FILTER_CONNECTION_CONTEXT *ret;
ret = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) malloc( sizeof( DATA_SINK_FILTER_CONNECTION_CONTEXT ) );
if (!ret) {
return 0;
}
ret->impl_connection_ctx = impl_connection_ctx;
ret->out_buf = out_buf;
ret->next_request_filter = (size_t) -1;
return ret;
}
| DATA_SINK_FILTER* DATA_SINK_FILTER_init | ( | WEBBY * | server | ) |
Definition at line 268 of file webby.c.
{
DATA_SINK_FILTER * ret;
ret = (DATA_SINK_FILTER *) malloc( sizeof( DATA_SINK_FILTER ) );
if (!ret) {
return 0;
}
ret->base.on_request_header_parsed = sink_req_header_parsed;
ret->base.on_request_data = sink_req_data;
ret->base.on_request_completed = sink_req_completed;
ret->base.on_response_header = sink_on_response_header;
ret->base.on_response_data = sink_on_response_data;
ret->base.on_response_completed = sink_on_response_complete;
ret->base.on_connection_close = sink_connection_close;
ret->server = server;
memset( &ret->default_vhost, 0, sizeof( VIRTUAL_HOST_DEFINITION ) );
ret->default_vhost.next_filter_idx = ret->default_vhost.last_filter_idx = (size_t) -1;
if (ARRAY_init( &ret->vhosts, sizeof( VIRTUAL_HOST_DEFINITION ), 10 )) {
return 0;
}
return ret;
}
| static int http_header_parsed | ( | HTTP_REQUEST * | request, |
| void * | ctx | ||
| ) | [static] |
Definition at line 727 of file webby.c.
{
MLOG_TRACE( "webby - http header parsed" );
FILTER_CONTEXT *filter_data = (FILTER_CONTEXT *) ctx;
return filter_data->filter->on_request_header_parsed(request, filter_data );
}
| static int http_on_message_data | ( | HTTP_REQUEST * | request, |
| void * | data, | ||
| size_t | data_size, | ||
| void * | ctx | ||
| ) | [static] |
Definition at line 736 of file webby.c.
{
MLOG_TRACE( "webby - request body data parsed. size %u", data_size );
FILTER_CONTEXT *filter_data = (FILTER_CONTEXT *) ctx;
return filter_data->filter->on_request_data( request, data, data_size, filter_data );
}
| static int http_req_finished | ( | HTTP_REQUEST * | request, |
| void * | ctx | ||
| ) | [static] |
Definition at line 745 of file webby.c.
{
MLOG_TRACE( "webby - request parsing finished" );
FILTER_CONTEXT *filter_data = (FILTER_CONTEXT *) ctx;
return filter_data->filter->on_request_completed( request, filter_data );
}
| SERVLET_FILTER_CONNECTION_CONTEXT* SERVLET_FILTER_CONNECTION_CONTEXT_init | ( | SERVLET_RUNNER_FILTER * | rfilter | ) |
Definition at line 385 of file webby.c.
{
size_t nservlets;
SERVLET_FILTER_CONNECTION_CONTEXT *ret;
SERVLET_CONTEXT *cur;
HTTP_SERVLET **tmp;
size_t i;
nservlets = ARRAY_size( &rfilter->servlets );
ret = malloc( sizeof( SERVLET_FILTER_CONNECTION_CONTEXT ) );
if (!ret) {
return 0;
}
ret->servlet_contexts = (SERVLET_CONTEXT *) malloc( nservlets * sizeof( SERVLET_CONTEXT ) );
if (!ret->servlet_contexts) {
return 0;
}
for( i = 0, cur = ret->servlet_contexts; i < nservlets; ++i, ++cur) {
cur->connection_ctx = 0;
tmp = (HTTP_SERVLET **) ARRAY_at( &rfilter->servlets, i );
cur->servlet = *tmp;
}
DBUF_init( &ret->request_data, 0 );
HTTP_RESPONSE_init( &ret->response.response, HTTP_VERSION_1_1, 501 );
return ret;
}
| int SERVLET_RUNNER_FILTER_add_servlet | ( | SERVLET_RUNNER_FILTER * | servlets, |
| HTTP_SERVLET * | servlet | ||
| ) |
Definition at line 559 of file webby.c.
{
if (servlet->init_servlet) {
if (servlet->init_servlet( servlet )) {
return -1;
}
}
return ARRAY_push_back( &servlets->servlets, &servlet, sizeof( void * ) );
}
| void SERVLET_RUNNER_FILTER_free | ( | SERVLET_RUNNER_FILTER * | servlets | ) |
Definition at line 544 of file webby.c.
{
size_t i;
HTTP_SERVLET *servlet;
for(i = 0; i < ARRAY_size( &servlets->servlets ); i++) {
servlet = (HTTP_SERVLET *) ARRAY_at( &servlets->servlets, i );
if (servlet->free_servlet) {
servlet->free_servlet( servlet );
}
}
ARRAY_free( &servlets->servlets );
free( servlets );
}
| SERVLET_RUNNER_FILTER* SERVLET_RUNNER_FILTER_init | ( | ) |
Definition at line 521 of file webby.c.
{
SERVLET_RUNNER_FILTER *ret;
ret = (SERVLET_RUNNER_FILTER *) malloc( sizeof( SERVLET_RUNNER_FILTER ) );
if (!ret) {
return 0;
}
memset( &ret->base, 0, sizeof( HTTP_FILTER ) );
ret->base.on_request_header_parsed = servlets_req_header_parsed;
ret->base.on_request_data = servlets_req_on_message_data;
ret->base.on_request_completed = servlets_req_finished;
ret->base.on_connection_close = servlets_connection_close;
if (ARRAY_init( &ret->servlets, sizeof( void * ), 10 ) ) {
free( ret );
return 0;
}
return ret;
}
| static int servlets_connection_close | ( | FILTER_CONTEXT * | context | ) | [static] |
Definition at line 502 of file webby.c.
{
size_t i;
SERVLET_FILTER_CONNECTION_CONTEXT *fcontext = (SERVLET_FILTER_CONNECTION_CONTEXT * ) context->connection_ctx;
SERVLET_RUNNER_FILTER *runner = (SERVLET_RUNNER_FILTER *) context->filter;
SERVLET_CONTEXT *scontext;
if (!fcontext->servlet_contexts) {
return 0;
}
for(i = 0, scontext = (SERVLET_CONTEXT *) fcontext->servlet_contexts; i < ARRAY_size( &runner->servlets ); ++i, ++scontext) {
if (scontext->servlet->free_connection) {
scontext->servlet->free_connection( scontext );
}
}
return 0;
}
| static int servlets_req_finished | ( | HTTP_REQUEST * | request, |
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 444 of file webby.c.
{
size_t i;
RDATA rd;
SERVLET_FILTER_CONNECTION_CONTEXT *fcontext = (SERVLET_FILTER_CONNECTION_CONTEXT * ) context->connection_ctx;
SERVLET_RUNNER_FILTER *runner = (SERVLET_RUNNER_FILTER *) context->filter;
SERVLET_CONTEXT *scontext;
SERVLET_STATUS status;
if ( request->expect_100_continue) {
rd.no_chunk.data = HTTP_100_CONTINUE_RESPONSE;
rd.no_chunk.data_size = HTTP_100_CONTINUE_RESPONSE_LEN;
if (call_next_filter_response_data ( 0, 0, rd, context ) ) {
return -1;
}
}
fcontext->request.request = request;
fcontext->request.request_data = fcontext->buff;
HTTP_RESPONSE_free( &fcontext->response.response );
HTTP_RESPONSE_init( &fcontext->response.response, request->version, 501 );
fcontext->response.request = request;
fcontext->response.filter_context = context;
fcontext->response.data_sent = 0;
fcontext->response.state = 0;
fcontext->response.chunk_buf = 0;
fcontext->response.chunk_buf_size = 0;
fcontext->response.chunk_no = 0;
for(i = 0, scontext = (SERVLET_CONTEXT *) fcontext->servlet_contexts; i < ARRAY_size( &runner->servlets ); ++i, ++scontext) {
status = scontext->servlet->servlet_action( &fcontext->request, &fcontext->response, scontext );
if (status == SERVLET_REQUEST_HANDLED) {
return 0;
}
if (status == SERVLET_REQUEST_ERROR) {
rd.no_chunk.data = HTTP_500_SERVER_ERROR;
rd.no_chunk.data_size = HTTP_500_SERVER_ERROR_LEN;
call_next_filter_response_data( 0, 0, rd, context );
return -1;
}
}
rd.no_chunk.data = HTTP_404_NOT_FOUND;
rd.no_chunk.data_size = HTTP_404_NOT_FOUND_LEN;
call_next_filter_response_data( 0, 0, rd, context );
return 0;
}
| static int servlets_req_header_parsed | ( | HTTP_REQUEST * | request, |
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 420 of file webby.c.
{
M_UNUSED( request );
if (!context->connection_ctx) {
context->connection_ctx = SERVLET_FILTER_CONNECTION_CONTEXT_init( (SERVLET_RUNNER_FILTER *) context->filter );
}
if (! context->connection_ctx) {
return -1;
}
return 0;
}
| static int servlets_req_on_message_data | ( | HTTP_REQUEST * | request, |
| void * | data, | ||
| size_t | data_size, | ||
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 435 of file webby.c.
{
SERVLET_FILTER_CONNECTION_CONTEXT *fcontext = (SERVLET_FILTER_CONNECTION_CONTEXT * ) context->connection_ctx;
M_UNUSED( request );
return DBUF_add( &fcontext->request_data, data, data_size );
}
| static int sink_connection_close | ( | FILTER_CONTEXT * | context | ) | [static] |
Definition at line 260 of file webby.c.
{
if (context->connection_ctx) {
free( context->connection_ctx);
}
return 0;
}
| static int sink_on_response_complete | ( | HTTP_RESPONSE * | response, |
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 251 of file webby.c.
{
DATA_SINK_FILTER_CONNECTION_CONTEXT *sink = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) context->connection_ctx;
M_UNUSED( response );
return WEBBY_impl_response_completed( sink->impl_connection_ctx, response->base.flags & HTTP_MESSAGE_FLAG_CONNECTION_CLOSE );
}
| static int sink_on_response_data | ( | HTTP_RESPONSE * | response, |
| int | is_chunk, | ||
| RDATA | rdata, | ||
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 200 of file webby.c.
{
DATA_SINK_FILTER_CONNECTION_CONTEXT *sink = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) context->connection_ctx;
BF *bf;
void *data;
size_t size;
int len;
char chunk_header[ 20 ];
M_UNUSED( response );
if (!is_chunk) {
return WEBBY_impl_send_data( sink->impl_connection_ctx, rdata.no_chunk.data, rdata.no_chunk.data_size );
}
bf = rdata.chunk.bf;
if (bf) {
if (rdata.chunk.chunk_no) {
len = snprintf( chunk_header, sizeof( chunk_header ), "\r\n%x\r\n", BF_get_size(bf) );
} else {
len = snprintf( chunk_header, sizeof( chunk_header ), "%x\r\n", BF_get_size(bf) );
}
if ( (bf->start - bf->bf) < len) {
MLOG_INFO( "Failed to send chunk - buffer did not reserved enough room before start of chunk data" );
return -1;
}
bf->start -= len;
strncpy( (char *) bf->start, chunk_header, len );
if (WEBBY_impl_send_data( sink->impl_connection_ctx, bf->start, bf->put_pos - bf->start )) {
MLOG_INFO( "Failed to send chunk data" );
}
} else {
if (rdata.chunk.chunk_no) {
data = LAST_CHUNK_NOT_FIRST;
size = LAST_CHUNK_NOT_FIRST_SIZE;
} else {
data = LAST_CHUNK_FIRST;
size = LAST_CHUNK_FIRST_SIZE;
}
if (WEBBY_impl_send_data( sink->impl_connection_ctx, data, size )) {
MLOG_INFO( "Failed to send chunk data" );
}
}
return 0;
}
| static int sink_on_response_header | ( | HTTP_RESPONSE * | response, |
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 168 of file webby.c.
{
DATA_SINK_FILTER_CONNECTION_CONTEXT *sink = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) context->connection_ctx;
BF *bf;
PARSER_STATUS stat;
bf = sink->out_buf;
HTTP_RESPONSE_WRITER_init( &sink->writer, response );
while(1) {
stat = HTTP_RESPONSE_WRITER_write( &sink->writer, bf );
switch(stat) {
case PARSER_STATUS_ERROR:
MLOG_INFO( "Failed to format response header" );
return -1;
case PARSER_STATUS_COMPLETED:
if (WEBBY_impl_send_data( sink->impl_connection_ctx, bf->get_pos, BF_get_size( bf ) ) ) {
MLOG_INFO( "Failed to send response header" );
return -1;
}
return 0;
case PARSER_STATUS_NEED_MORE_DATA:
if (WEBBY_impl_send_data( sink->impl_connection_ctx, bf->get_pos, BF_get_size( bf ) ) ) {
MLOG_INFO( "Failed to send response header" );
return -1;
}
break;
}
} while( 1 );
}
| static int sink_req_completed | ( | HTTP_REQUEST * | request, |
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 155 of file webby.c.
{
DATA_SINK_FILTER_CONNECTION_CONTEXT * sink;
sink = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) context;
if (sink->next_request_filter == (size_t) -1) {
return call_next_filter_request_completed( request, context );
}
context = context + sink->next_request_filter;
return context->filter->on_request_completed( request, context );
}
| static int sink_req_data | ( | HTTP_REQUEST * | request, |
| void * | data, | ||
| size_t | data_size, | ||
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 142 of file webby.c.
{
DATA_SINK_FILTER_CONNECTION_CONTEXT * sink;
sink = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) context;
if (sink->next_request_filter == (size_t) -1) {
return call_next_filter_request_data( request, data, data_size, context );
}
context = context + sink->next_request_filter;
return context->filter->on_request_data( request, data, data_size, context );
}
| static int sink_req_header_parsed | ( | HTTP_REQUEST * | request, |
| FILTER_CONTEXT * | context | ||
| ) | [static] |
Definition at line 81 of file webby.c.
{
DATA_SINK_FILTER *sink_filter;
DATA_SINK_FILTER_CONNECTION_CONTEXT *sink;
VIRTUAL_HOST_DEFINITION *vhosts_def;
size_t i, found;
RDATA rd;
// no host header in HTTP 1.0; go to the next filter.
if (request->version == HTTP_VERSION_1_0) {
return call_next_filter_request_header_parsed( request, context );
}
// presence of Host header is absolutely required with HTTP/1.1
if (!request->has_host_header) {
MLOG_INFO( "HTTP/1.1 no host header" );
goto bad_request;
}
sink_filter = (DATA_SINK_FILTER *) context->filter;
if (ARRAY_size( &sink_filter->vhosts ) == 0) {
return call_next_filter_request_header_parsed( request, context );
}
// find which virtua host corresponds to the request host entry
for( found = i = 0, vhosts_def = (VIRTUAL_HOST_DEFINITION *) ARRAY_at( &sink_filter->vhosts, 0 );
i < ARRAY_size( &sink_filter->vhosts);
++i, ++vhosts_def ) {
if ( strcmp( request->host_header, vhosts_def->host ) == 0 && request->host_header_port == vhosts_def->host_port) {
found = 1;
break;
}
}
if (!found) {
MLOG_INFO( "Host header %s %d does not correspond to any virtual hosts", request->host_header, request->host_header_port );
goto bad_request;
}
// now that the virtual host is found - remember the next filter index for the following notifications.
sink = (DATA_SINK_FILTER_CONNECTION_CONTEXT *) context;
sink->next_request_filter = vhosts_def->next_filter_idx;
// call next filter.
context = context + vhosts_def->next_filter_idx;
return context->filter->on_request_header_parsed( request, context );
bad_request:
rd.no_chunk.data = HTTP_400_BAD_REQUEST;
rd.no_chunk.data_size = HTTP_400_BAD_REQUEST_LEN;
context->filter->on_response_data( 0, 0, rd, context );
//call_next_filter_response_data( 0, 0, rd, context );
return -1;
}
1.7.4