WEBBY - the embedded web server with many faces / objects in plain C Snapshot
Classes | Defines | Typedefs | Functions
webby.c File Reference
#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_CONTEXTDATA_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_FILTERDATA_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_CONTEXTSERVLET_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_FILTERSERVLET_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)
WEBBYWEBBY_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_CONNECTIONWEBBY_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 Documentation

#define HTTP_100_CONTINUE_RESPONSE   "HTTP/1.1 100 Continue\r\n\r\n"

Definition at line 19 of file webby.c.

#define HTTP_100_CONTINUE_RESPONSE_LEN   25

Definition at line 20 of file webby.c.

#define HTTP_400_BAD_REQUEST   "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n"

Definition at line 22 of file webby.c.

#define HTTP_400_BAD_REQUEST_LEN   47

Definition at line 23 of file webby.c.

#define HTTP_404_NOT_FOUND   "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"

Definition at line 25 of file webby.c.

#define HTTP_404_NOT_FOUND_LEN   45

Definition at line 26 of file webby.c.

#define HTTP_500_SERVER_ERROR   "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n"

Definition at line 28 of file webby.c.

#define HTTP_500_SERVER_ERROR_LEN   57

Definition at line 29 of file webby.c.

#define LAST_CHUNK_FIRST   "0\r\n\r\n"

Definition at line 16 of file webby.c.

#define LAST_CHUNK_FIRST_SIZE   5

Definition at line 17 of file webby.c.

#define LAST_CHUNK_NOT_FIRST   "\r\n0\r\n\r\n"

Definition at line 13 of file webby.c.

#define LAST_CHUNK_NOT_FIRST_SIZE   7

Definition at line 14 of file webby.c.

#define RESERVED_FOR_CHUNK_HEADER_SIZE   15

Definition at line 11 of file webby.c.


Typedef Documentation


Function Documentation

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)

Definition at line 76 of file webby.c.

{
  free(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)
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;
 
}