2008-07-23 20:19:23 +00:00
2008-11-16 20:33:53 +00:00
# include <lighttpd/base.h>
# include <lighttpd/plugin_core.h>
# include <lighttpd/profiler.h>
2008-07-23 20:19:23 +00:00
2008-09-18 07:14:57 +00:00
# include <sys/stat.h>
# include <fcntl.h>
2008-09-26 14:11:08 +00:00
static action * core_list ( server * srv , plugin * p , value * val ) {
2008-07-24 11:25:40 +00:00
action * a ;
guint i ;
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
if ( ! val ) {
2008-08-09 15:20:12 +00:00
ERROR ( srv , " %s " , " need parameter " ) ;
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val - > type = = VALUE_ACTION ) {
a = val - > data . val_action . action ;
2008-08-06 18:46:42 +00:00
action_acquire ( a ) ;
return a ;
}
2008-09-26 14:11:08 +00:00
if ( val - > type ! = VALUE_LIST ) {
ERROR ( srv , " expected list, got %s " , value_type_string ( val - > type ) ) ;
2008-07-24 11:25:40 +00:00
return NULL ;
}
a = action_new_list ( ) ;
2008-09-26 14:11:08 +00:00
for ( i = 0 ; i < val - > data . list - > len ; i + + ) {
value * oa = g_array_index ( val - > data . list , value * , i ) ;
if ( oa - > type ! = VALUE_ACTION ) {
ERROR ( srv , " expected action at entry %u of list, got %s " , i , value_type_string ( oa - > type ) ) ;
2008-07-24 11:25:40 +00:00
action_release ( srv , a ) ;
return NULL ;
}
2008-09-26 14:11:08 +00:00
assert ( srv = = oa - > data . val_action . srv ) ;
action_acquire ( oa - > data . val_action . action ) ;
g_array_append_val ( a - > data . list , oa - > data . val_action . action ) ;
2008-07-24 11:25:40 +00:00
}
return a ;
}
2008-09-26 14:11:08 +00:00
static action * core_when ( server * srv , plugin * p , value * val ) {
value * val_cond , * val_act , * val_act_else ;
2008-08-27 14:39:30 +00:00
action * a , * act_else ;
2008-07-24 11:25:40 +00:00
UNUSED ( p ) ;
2008-07-25 12:09:03 +00:00
2008-09-26 14:11:08 +00:00
if ( ! val ) {
2008-08-09 15:20:12 +00:00
ERROR ( srv , " %s " , " need parameter " ) ;
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val - > type ! = VALUE_LIST ) {
ERROR ( srv , " expected list, got %s " , value_type_string ( val - > type ) ) ;
2008-07-24 11:25:40 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val - > data . list - > len = = 2 ) {
val_act_else = NULL ;
2008-08-27 14:39:30 +00:00
act_else = NULL ;
2008-09-26 14:11:08 +00:00
} else if ( val - > data . list - > len = = 3 ) {
val_act_else = g_array_index ( val - > data . list , value * , 2 ) ;
act_else = val_act_else - > data . val_action . action ;
2008-08-27 14:39:30 +00:00
} else {
2008-09-26 14:11:08 +00:00
ERROR ( srv , " expected list with length 2 or 3, has length %u " , val - > data . list - > len ) ;
2008-07-24 11:25:40 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
val_cond = g_array_index ( val - > data . list , value * , 0 ) ;
val_act = g_array_index ( val - > data . list , value * , 1 ) ;
2008-08-27 14:39:30 +00:00
2008-09-26 14:11:08 +00:00
if ( val_cond - > type ! = VALUE_CONDITION ) {
ERROR ( srv , " expected condition as first parameter, got %s " , value_type_string ( val_cond - > type ) ) ;
2008-07-24 11:25:40 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val_act - > type ! = VALUE_ACTION ) {
ERROR ( srv , " expected action as second parameter, got %s " , value_type_string ( val_act - > type ) ) ;
2008-07-24 11:25:40 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val_act_else & & val_act_else - > type ! = VALUE_ACTION ) {
ERROR ( srv , " expected action as third parameter, got %s " , value_type_string ( val_act_else - > type ) ) ;
2008-08-27 14:39:30 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
condition_acquire ( val_cond - > data . val_cond . cond ) ;
action_acquire ( val_act - > data . val_action . action ) ;
2008-08-27 14:39:30 +00:00
if ( act_else ) action_acquire ( act_else ) ;
2008-09-26 14:11:08 +00:00
a = action_new_condition ( val_cond - > data . val_cond . cond , val_act - > data . val_action . action , act_else ) ;
2008-07-24 11:25:40 +00:00
return a ;
}
2008-09-26 14:11:08 +00:00
static action * core_set ( server * srv , plugin * p , value * val ) {
value * val_val , * val_name ;
2008-08-08 16:49:00 +00:00
action * a ;
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
if ( ! val ) {
2008-08-09 15:20:12 +00:00
ERROR ( srv , " %s " , " need parameter " ) ;
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val - > type ! = VALUE_LIST ) {
ERROR ( srv , " expected list, got %s " , value_type_string ( val - > type ) ) ;
2008-08-08 16:49:00 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
if ( val - > data . list - > len ! = 2 ) {
ERROR ( srv , " expected list with length 2, has length %u " , val - > data . list - > len ) ;
2008-08-08 16:49:00 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
val_name = g_array_index ( val - > data . list , value * , 0 ) ;
val_val = g_array_index ( val - > data . list , value * , 1 ) ;
if ( val_name - > type ! = VALUE_STRING ) {
ERROR ( srv , " expected string as first parameter, got %s " , value_type_string ( val_name - > type ) ) ;
2008-08-08 16:49:00 +00:00
return NULL ;
}
2008-09-26 14:11:08 +00:00
a = option_action ( srv , val_name - > data . string - > str , val_val ) ;
2008-08-08 16:49:00 +00:00
return a ;
}
2008-10-25 12:53:57 +00:00
static gboolean core_setup_set ( server * srv , plugin * p , value * val ) {
value * val_val , * val_name ;
UNUSED ( p ) ;
if ( ! val ) {
ERROR ( srv , " %s " , " need parameter " ) ;
return FALSE ;
}
if ( val - > type ! = VALUE_LIST ) {
ERROR ( srv , " expected list, got %s " , value_type_string ( val - > type ) ) ;
return FALSE ;
}
if ( val - > data . list - > len ! = 2 ) {
ERROR ( srv , " expected list with length 2, has length %u " , val - > data . list - > len ) ;
return FALSE ;
}
val_name = g_array_index ( val - > data . list , value * , 0 ) ;
val_val = g_array_index ( val - > data . list , value * , 1 ) ;
if ( val_name - > type ! = VALUE_STRING ) {
ERROR ( srv , " expected string as first parameter, got %s " , value_type_string ( val_name - > type ) ) ;
return FALSE ;
}
return plugin_set_default_option ( srv , val_name - > data . string - > str , val_val ) ;
}
2009-01-05 21:24:54 +00:00
static handler_t core_handle_docroot ( vrequest * vr , gpointer param , gpointer * context ) {
2008-12-09 23:23:27 +00:00
UNUSED ( context ) ;
2008-08-09 15:20:12 +00:00
2009-01-05 21:24:54 +00:00
g_string_truncate ( vr - > physical . doc_root , 0 ) ;
g_string_append_len ( vr - > physical . doc_root , GSTR_LEN ( ( GString * ) param ) ) ;
/* reset stat info because path has changed */
vr - > physical . have_stat = FALSE ;
2008-10-02 22:52:46 +00:00
/* build physical path: docroot + uri.path */
2008-10-25 12:53:57 +00:00
g_string_truncate ( vr - > physical . path , 0 ) ;
2009-01-05 21:24:54 +00:00
g_string_append_len ( vr - > physical . path , GSTR_LEN ( ( GString * ) param ) ) ;
2008-10-25 12:53:57 +00:00
g_string_append_len ( vr - > physical . path , GSTR_LEN ( vr - > request . uri . path ) ) ;
2008-08-09 15:20:12 +00:00
2008-12-30 13:24:33 +00:00
VR_DEBUG ( vr , " physical path: %s " , vr - > physical . path - > str ) ;
2008-08-09 15:20:12 +00:00
2009-01-05 21:24:54 +00:00
return HANDLER_GO_ON ;
}
static void core_docroot_free ( server * srv , gpointer param ) {
UNUSED ( srv ) ;
g_string_free ( param , TRUE ) ;
}
static action * core_docroot ( server * srv , plugin * p , value * val ) {
UNUSED ( p ) ;
if ( ! val | | val - > type ! = VALUE_STRING ) {
ERROR ( srv , " %s " , " docroot action expects a string parameter " ) ;
return NULL ;
}
return action_new_function ( core_handle_docroot , NULL , core_docroot_free , value_extract ( val ) . string ) ;
}
static handler_t core_handle_static ( vrequest * vr , gpointer param , gpointer * context ) {
int fd ;
UNUSED ( param ) ;
UNUSED ( context ) ;
2008-10-25 16:01:02 +00:00
if ( vr - > physical . path - > len = = 0 ) return HANDLER_GO_ON ;
2008-08-09 15:20:12 +00:00
2008-10-25 12:53:57 +00:00
if ( ! vrequest_handle_direct ( vr ) ) return HANDLER_GO_ON ;
2008-08-09 15:20:12 +00:00
2008-10-25 12:53:57 +00:00
fd = open ( vr - > physical . path - > str , O_RDONLY ) ;
2008-08-09 15:20:12 +00:00
if ( fd = = - 1 ) {
2008-10-25 12:53:57 +00:00
vr - > response . http_status = 404 ;
2008-12-30 13:24:33 +00:00
VR_DEBUG ( vr , " open() failed: %s (%d) " , g_strerror ( errno ) , errno ) ;
2008-10-02 22:52:46 +00:00
switch ( errno ) {
case ENOENT :
2008-10-25 13:25:02 +00:00
vr - > response . http_status = 404 ; break ;
2008-10-02 22:52:46 +00:00
case EACCES :
case EFAULT :
2008-10-25 13:25:02 +00:00
vr - > response . http_status = 403 ; break ;
2008-10-02 22:52:46 +00:00
default :
2008-10-25 13:25:02 +00:00
vr - > response . http_status = 500 ;
2008-10-02 22:52:46 +00:00
}
2008-08-09 15:20:12 +00:00
} else {
struct stat st ;
fstat ( fd , & st ) ;
2008-10-22 14:54:44 +00:00
2008-08-09 15:20:12 +00:00
# ifdef FD_CLOEXEC
fcntl ( fd , F_SETFD , FD_CLOEXEC ) ;
# endif
2008-09-08 00:28:55 +00:00
if ( ! S_ISREG ( st . st_mode ) ) {
2008-10-25 12:53:57 +00:00
vr - > response . http_status = 404 ;
2008-09-08 00:28:55 +00:00
close ( fd ) ;
} else {
2008-10-25 16:01:02 +00:00
GString * mime_str = mimetype_get ( vr , vr - > request . uri . path ) ;
2008-10-25 12:53:57 +00:00
vr - > response . http_status = 200 ;
2008-10-02 23:50:47 +00:00
if ( mime_str )
2008-10-25 13:25:02 +00:00
http_header_overwrite ( vr - > response . headers , CONST_STR_LEN ( " Content-Type " ) , GSTR_LEN ( mime_str ) ) ;
2008-10-02 23:50:47 +00:00
else
2008-10-25 13:25:02 +00:00
http_header_overwrite ( vr - > response . headers , CONST_STR_LEN ( " Content-Type " ) , CONST_STR_LEN ( " application/octet-stream " ) ) ;
2008-10-25 12:53:57 +00:00
chunkqueue_append_file_fd ( vr - > out , NULL , 0 , st . st_size , fd ) ;
2008-09-08 00:28:55 +00:00
}
2008-08-09 15:20:12 +00:00
}
2008-10-25 12:53:57 +00:00
return HANDLER_GO_ON ;
2008-07-23 20:25:16 +00:00
}
2008-09-26 14:11:08 +00:00
static action * core_static ( server * srv , plugin * p , value * val ) {
2008-07-24 11:25:40 +00:00
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
if ( val ) {
2008-07-23 20:25:16 +00:00
ERROR ( srv , " %s " , " static action doesn't have parameters " ) ;
2008-07-24 11:25:40 +00:00
return NULL ;
2008-07-23 20:25:16 +00:00
}
2008-12-09 23:23:27 +00:00
return action_new_function ( core_handle_static , NULL , NULL , NULL ) ;
2008-07-23 20:25:16 +00:00
}
2008-07-23 20:19:23 +00:00
2008-12-09 23:23:27 +00:00
static handler_t core_handle_test ( vrequest * vr , gpointer param , gpointer * context ) {
2008-10-25 12:53:57 +00:00
connection * con = vr - > con ;
2008-09-08 00:20:55 +00:00
server * srv = con - > srv ;
2008-09-25 14:59:09 +00:00
worker * wrk = con - > wrk ;
2008-09-24 21:43:22 +00:00
/*GHashTableIter iter;
2008-08-12 15:09:05 +00:00
gpointer k , v ;
2008-09-24 21:43:22 +00:00
GList * hv ; */
2008-08-13 23:05:15 +00:00
GString * str ;
2008-08-15 16:21:21 +00:00
gchar * backend ;
2008-08-13 23:05:15 +00:00
guint64 uptime ;
guint64 avg1 , avg2 , avg3 ;
gchar suffix1 [ 2 ] = { 0 , 0 } , suffix2 [ 2 ] = { 0 , 0 } , suffix3 [ 2 ] = { 0 , 0 } ;
2008-08-06 18:46:42 +00:00
UNUSED ( param ) ;
2008-12-09 23:23:27 +00:00
UNUSED ( context ) ;
2008-08-06 18:46:42 +00:00
2008-10-25 12:53:57 +00:00
if ( ! vrequest_handle_direct ( vr ) ) return HANDLER_GO_ON ;
2008-08-06 18:46:42 +00:00
2008-10-25 12:53:57 +00:00
vr - > response . http_status = 200 ;
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " host: " ) ) ;
chunkqueue_append_mem ( vr - > out , GSTR_LEN ( vr - > request . uri . host ) ) ;
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n path: " ) ) ;
chunkqueue_append_mem ( vr - > out , GSTR_LEN ( vr - > request . uri . path ) ) ;
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n query: " ) ) ;
chunkqueue_append_mem ( vr - > out , GSTR_LEN ( vr - > request . uri . query ) ) ;
2008-08-13 23:05:15 +00:00
2008-10-25 12:53:57 +00:00
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n \r \n actions executed: " ) ) ;
2008-09-08 00:20:55 +00:00
uptime = ( guint64 ) ( ev_now ( con - > wrk - > loop ) - srv - > started ) ;
2008-08-13 23:05:15 +00:00
if ( uptime = = 0 )
uptime = 1 ;
2008-09-25 14:59:09 +00:00
avg1 = wrk - > stats . actions_executed ;
2008-08-13 23:05:15 +00:00
suffix1 [ 0 ] = counter_format ( & avg1 , 1000 ) ;
2008-09-25 14:59:09 +00:00
avg2 = wrk - > stats . actions_executed / uptime ;
2008-08-13 23:05:15 +00:00
suffix2 [ 0 ] = counter_format ( & avg2 , 1000 ) ;
2008-09-25 14:59:09 +00:00
avg3 = wrk - > stats . actions_executed / wrk - > stats . requests ;
2008-08-13 23:05:15 +00:00
suffix3 [ 0 ] = counter_format ( & avg3 , 1000 ) ;
str = g_string_sized_new ( 0 ) ;
g_string_printf ( str ,
" % " G_GUINT64_FORMAT " %s (% " G_GUINT64_FORMAT " %s/s, % " G_GUINT64_FORMAT " %s/req) " ,
avg1 , suffix1 , avg2 , suffix2 , avg3 , suffix3
) ;
2008-10-25 12:53:57 +00:00
chunkqueue_append_string ( vr - > out , str ) ;
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n requests: " ) ) ;
2008-09-25 14:59:09 +00:00
avg1 = wrk - > stats . requests ;
2008-08-13 23:05:15 +00:00
suffix1 [ 0 ] = counter_format ( & avg1 , 1000 ) ;
2008-09-25 14:59:09 +00:00
avg2 = wrk - > stats . requests / uptime ;
2008-08-13 23:05:15 +00:00
suffix2 [ 0 ] = counter_format ( & avg2 , 1000 ) ;
str = g_string_sized_new ( 0 ) ;
g_string_printf ( str , " % " G_GUINT64_FORMAT " %s (% " G_GUINT64_FORMAT " %s/s) " , avg1 , suffix1 , avg2 , suffix2 ) ;
2008-10-25 12:53:57 +00:00
chunkqueue_append_string ( vr - > out , str ) ;
2008-08-13 23:05:15 +00:00
2008-09-08 00:20:55 +00:00
backend = ev_backend_string ( ev_backend ( con - > wrk - > loop ) ) ;
2008-10-25 12:53:57 +00:00
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n event handler: " ) ) ;
chunkqueue_append_mem ( vr - > out , backend , strlen ( backend ) ) ;
2008-08-15 16:21:21 +00:00
2008-10-25 12:53:57 +00:00
/* chunkqueue_append_mem(vr->out, CONST_STR_LEN("\r\n\r\n--- headers ---\r\n"));
2008-08-12 15:09:05 +00:00
g_hash_table_iter_init ( & iter , con - > request . headers - > table ) ;
while ( g_hash_table_iter_next ( & iter , & k , & v ) ) {
hv = g_queue_peek_head_link ( & ( ( http_header * ) v ) - > values ) ;
while ( hv ! = NULL ) {
2008-10-25 12:53:57 +00:00
chunkqueue_append_mem ( vr - > out , GSTR_LEN ( ( ( http_header * ) v ) - > key ) ) ;
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " : " ) ) ;
chunkqueue_append_mem ( vr - > out , GSTR_LEN ( ( GString * ) hv - > data ) ) ;
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n " ) ) ;
2008-08-12 15:09:05 +00:00
hv = hv - > next ;
}
2008-09-09 14:38:40 +00:00
} */
2008-10-25 12:53:57 +00:00
chunkqueue_append_mem ( vr - > out , CONST_STR_LEN ( " \r \n " ) ) ;
2008-08-06 18:46:42 +00:00
2008-10-25 12:53:57 +00:00
return HANDLER_GO_ON ;
2008-08-06 18:46:42 +00:00
}
2008-09-26 14:11:08 +00:00
static action * core_test ( server * srv , plugin * p , value * val ) {
2008-08-06 18:46:42 +00:00
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
if ( val ) {
2008-08-16 22:23:52 +00:00
ERROR ( srv , " %s " , " 'static' action doesn't have parameters " ) ;
2008-08-06 18:46:42 +00:00
return NULL ;
}
2008-12-09 23:23:27 +00:00
return action_new_function ( core_handle_test , NULL , NULL , NULL ) ;
2008-08-06 18:46:42 +00:00
}
2008-12-09 23:23:27 +00:00
static handler_t core_handle_blank ( vrequest * vr , gpointer param , gpointer * context ) {
2008-08-16 22:23:52 +00:00
UNUSED ( param ) ;
2008-12-09 23:23:27 +00:00
UNUSED ( context ) ;
2008-08-16 22:23:52 +00:00
2008-10-25 12:53:57 +00:00
if ( ! vrequest_handle_direct ( vr ) ) return HANDLER_GO_ON ;
2008-08-16 22:23:52 +00:00
2008-10-25 12:53:57 +00:00
vr - > response . http_status = 200 ;
2008-08-16 22:23:52 +00:00
2008-10-25 12:53:57 +00:00
return HANDLER_GO_ON ;
2008-08-16 22:23:52 +00:00
}
2008-09-26 14:11:08 +00:00
static action * core_blank ( server * srv , plugin * p , value * val ) {
2008-08-16 22:23:52 +00:00
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
if ( val ) {
2008-08-16 22:23:52 +00:00
ERROR ( srv , " %s " , " 'empty' action doesn't have parameters " ) ;
return NULL ;
}
2008-12-09 23:23:27 +00:00
return action_new_function ( core_handle_blank , NULL , NULL , NULL ) ;
2008-08-16 22:23:52 +00:00
}
2008-12-09 23:23:27 +00:00
static handler_t core_handle_profile_mem ( vrequest * vr , gpointer param , gpointer * context ) {
2008-10-25 16:01:02 +00:00
UNUSED ( vr ) ;
2008-10-17 16:08:40 +00:00
UNUSED ( param ) ;
2008-12-09 23:23:27 +00:00
UNUSED ( context ) ;
2008-10-17 16:08:40 +00:00
2008-10-17 22:06:06 +00:00
/*g_mem_profile();*/
profiler_dump ( ) ;
2008-10-17 16:08:40 +00:00
2008-10-25 16:01:02 +00:00
return HANDLER_GO_ON ;
2008-10-17 16:08:40 +00:00
}
static action * core_profile_mem ( server * srv , plugin * p , value * val ) {
UNUSED ( p ) ;
if ( val ) {
ERROR ( srv , " %s " , " 'profile_mem' action doesn't have parameters " ) ;
return NULL ;
}
2008-12-09 23:23:27 +00:00
return action_new_function ( core_handle_profile_mem , NULL , NULL , NULL ) ;
2008-10-17 16:08:40 +00:00
}
2008-09-26 14:11:08 +00:00
static gboolean core_listen ( server * srv , plugin * p , value * val ) {
2008-09-27 15:06:43 +00:00
GString * ipstr ;
2008-12-20 15:25:02 +00:00
int s ;
2008-07-24 11:25:40 +00:00
UNUSED ( p ) ;
2008-09-27 15:06:43 +00:00
2008-09-26 14:11:08 +00:00
if ( val - > type ! = VALUE_STRING ) {
2008-07-23 20:19:23 +00:00
ERROR ( srv , " %s " , " listen expects a string as parameter " ) ;
return FALSE ;
}
2008-12-20 15:25:02 +00:00
ipstr = val - > data . string ;
if ( - 1 = = ( s = angel_listen ( srv , ipstr ) ) ) {
ERROR ( srv , " %s " , " angel_listen failed " ) ;
2008-08-06 18:46:42 +00:00
return FALSE ;
}
2008-12-20 15:25:02 +00:00
server_listen ( srv , s ) ;
2008-07-23 20:19:23 +00:00
return TRUE ;
}
2008-08-13 17:57:19 +00:00
2008-09-26 14:11:08 +00:00
static gboolean core_event_handler ( server * srv , plugin * p , value * val ) {
2008-08-15 16:21:21 +00:00
guint backend ;
gchar * str ;
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
if ( val - > type ! = VALUE_STRING ) {
2008-08-15 16:21:21 +00:00
ERROR ( srv , " %s " , " event_handler expects a string as parameter " ) ;
return FALSE ;
}
2008-09-26 14:11:08 +00:00
str = val - > data . string - > str ;
2008-08-15 16:21:21 +00:00
backend = 0 ; /* libev will chose the right one by default */
if ( g_str_equal ( str , " select " ) )
backend = EVBACKEND_SELECT ;
else if ( g_str_equal ( str , " poll " ) )
backend = EVBACKEND_POLL ;
else if ( g_str_equal ( str , " epoll " ) )
backend = EVBACKEND_EPOLL ;
else if ( g_str_equal ( str , " kqueue " ) )
backend = EVBACKEND_KQUEUE ;
else if ( g_str_equal ( str , " devpoll " ) )
backend = EVBACKEND_DEVPOLL ;
else if ( g_str_equal ( str , " port " ) )
backend = EVBACKEND_PORT ;
else {
ERROR ( srv , " unkown event handler: '%s' " , str ) ;
return FALSE ;
}
if ( backend ) {
if ( ! ( ev_supported_backends ( ) & backend ) ) {
ERROR ( srv , " unsupported event handler: '%s' " , str ) ;
return FALSE ;
}
if ( ! ( ev_recommended_backends ( ) & backend ) ) {
2008-12-30 13:24:33 +00:00
DEBUG ( srv , " warning: event handler '%s' not recommended for this platform! " , str ) ;
2008-08-15 16:21:21 +00:00
}
}
srv - > loop_flags | = backend ;
return TRUE ;
}
2008-09-26 14:11:08 +00:00
static gboolean core_workers ( server * srv , plugin * p , value * val ) {
2008-09-09 09:31:08 +00:00
gint workers ;
UNUSED ( p ) ;
2008-09-26 14:11:08 +00:00
workers = val - > data . number ;
if ( val - > type ! = VALUE_NUMBER | | workers < 1 ) {
2008-09-09 09:31:08 +00:00
ERROR ( srv , " %s " , " workers expects a positive integer as parameter " ) ;
return FALSE ;
}
if ( srv - > worker_count ! = 0 ) {
ERROR ( srv , " workers already called with '%i', overwriting " , srv - > worker_count ) ;
}
srv - > worker_count = workers ;
return TRUE ;
}
2008-10-22 14:54:44 +00:00
static gboolean core_module_load ( server * srv , plugin * p , value * val ) {
value * mods = value_new_list ( ) ;
UNUSED ( p ) ;
if ( ! g_module_supported ( ) ) {
ERROR ( srv , " %s " , " module loading not supported on this platform " ) ;
value_free ( mods ) ;
return FALSE ;
}
if ( val - > type = = VALUE_STRING ) {
/* load only one module */
value * name = value_new_string ( value_extract ( val ) . string ) ;
g_array_append_val ( mods - > data . list , name ) ;
} else if ( val - > type = = VALUE_LIST ) {
/* load a list of modules */
for ( guint i = 0 ; i < val - > data . list - > len ; i + + ) {
value * v = g_array_index ( val - > data . list , value * , i ) ;
if ( v - > type ! = VALUE_STRING ) {
ERROR ( srv , " module_load takes either a string or a list of strings as parameter, list with %s entry given " , value_type_string ( v - > type ) ) ;
value_free ( mods ) ;
return FALSE ;
}
}
mods - > data . list = value_extract ( val ) . list ;
} else {
ERROR ( srv , " module_load takes either a string or a list of strings as parameter, %s given " , value_type_string ( val - > type ) ) ;
return FALSE ;
}
/* parameter types ok, load modules */
for ( guint i = 0 ; i < mods - > data . list - > len ; i + + ) {
GString * name = g_array_index ( mods - > data . list , value * , i ) - > data . string ;
if ( ! module_load ( srv - > modules , name - > str ) ) {
ERROR ( srv , " could not load module '%s': %s " , name - > str , g_module_error ( ) ) ;
value_free ( mods ) ;
return FALSE ;
}
2008-12-30 13:24:33 +00:00
DEBUG ( srv , " loaded module '%s' " , name - > str ) ;
2008-10-22 14:54:44 +00:00
}
value_free ( mods ) ;
return TRUE ;
}
2008-11-10 14:39:03 +00:00
static gboolean core_io_timeout ( server * srv , plugin * p , value * val ) {
UNUSED ( p ) ;
if ( ! val | | val - > type ! = VALUE_NUMBER | | val - > data . number < 1 ) {
ERROR ( srv , " %s " , " io_timeout expects a positive number as parameter " ) ;
return FALSE ;
}
srv - > io_timeout = value_extract ( val ) . number ;
return TRUE ;
}
2008-10-22 14:54:44 +00:00
/*
* OPTIONS
*/
2008-09-26 15:09:30 +00:00
static gboolean core_option_log_parse ( server * srv , plugin * p , size_t ndx , value * val , option_value * oval ) {
2008-09-24 21:43:22 +00:00
GHashTableIter iter ;
gpointer k , v ;
log_level_t level ;
GString * path ;
GString * level_str ;
2008-12-31 01:50:32 +00:00
GArray * arr = g_array_sized_new ( FALSE , TRUE , sizeof ( log_t * ) , 6 ) ;
2008-09-26 14:11:08 +00:00
UNUSED ( p ) ;
UNUSED ( ndx ) ;
2008-09-26 15:09:30 +00:00
oval - > list = arr ;
2008-12-31 01:50:32 +00:00
g_array_set_size ( arr , 6 ) ;
2008-10-01 20:20:31 +00:00
/* default value */
if ( ! val ) {
2008-12-31 01:50:32 +00:00
/* default: log LOG_LEVEL_WARNING, LOG_LEVEL_ERROR and LOG_LEVEL_BACKEND to stderr */
2008-10-01 20:20:31 +00:00
log_t * log = srv - > logs . stderr ;
log_ref ( srv , log ) ;
g_array_index ( arr , log_t * , LOG_LEVEL_WARNING ) = log ;
log_ref ( srv , log ) ;
g_array_index ( arr , log_t * , LOG_LEVEL_ERROR ) = log ;
2008-12-31 01:50:32 +00:00
log_ref ( srv , log ) ;
g_array_index ( arr , log_t * , LOG_LEVEL_BACKEND ) = log ;
2008-10-01 20:20:31 +00:00
return TRUE ;
}
2008-08-13 17:57:19 +00:00
2008-09-26 14:11:08 +00:00
g_hash_table_iter_init ( & iter , val - > data . hash ) ;
2008-09-24 21:43:22 +00:00
while ( g_hash_table_iter_next ( & iter , & k , & v ) ) {
2008-10-02 22:59:59 +00:00
if ( ( ( value * ) v ) - > type ! = VALUE_STRING ) {
ERROR ( srv , " log expects a hashtable with string values, %s given " , value_type_string ( ( ( value * ) v ) - > type ) ) ;
g_array_free ( arr , TRUE ) ;
return FALSE ;
}
2008-09-26 14:11:08 +00:00
path = ( ( value * ) v ) - > data . string ;
2008-09-24 21:43:22 +00:00
level_str = ( GString * ) k ;
if ( g_str_equal ( level_str - > str , " * " ) ) {
for ( guint i = 0 ; i < arr - > len ; i + + ) {
2009-01-01 15:44:42 +00:00
log_t * log ;
2008-09-24 21:43:22 +00:00
if ( NULL ! = g_array_index ( arr , log_t * , i ) )
continue ;
2009-01-01 15:44:42 +00:00
log = log_new ( srv , log_type_from_path ( path ) , path ) ;
2008-09-24 21:43:22 +00:00
g_array_index ( arr , log_t * , i ) = log ;
}
}
else {
log_t * log = log_new ( srv , log_type_from_path ( path ) , path ) ;
level = log_level_from_string ( level_str ) ;
g_array_index ( arr , log_t * , level ) = log ;
}
}
2008-08-13 17:57:19 +00:00
return TRUE ;
}
2008-09-26 15:09:30 +00:00
static void core_option_log_free ( server * srv , plugin * p , size_t ndx , option_value oval ) {
2009-01-01 15:44:42 +00:00
GArray * arr = oval . list ;
2008-08-13 17:57:19 +00:00
UNUSED ( p ) ;
UNUSED ( ndx ) ;
2008-09-24 21:43:22 +00:00
2008-09-26 15:09:30 +00:00
if ( ! arr ) return ;
2008-09-24 21:43:22 +00:00
for ( guint i = 0 ; i < arr - > len ; i + + ) {
if ( NULL ! = g_array_index ( arr , log_t * , i ) )
log_unref ( srv , g_array_index ( arr , log_t * , i ) ) ;
}
2008-09-26 15:09:30 +00:00
g_array_free ( arr , TRUE ) ;
2008-08-13 17:57:19 +00:00
}
2008-09-26 15:09:30 +00:00
static gboolean core_option_log_timestamp_parse ( server * srv , plugin * p , size_t ndx , value * val , option_value * oval ) {
2008-08-22 18:51:25 +00:00
UNUSED ( p ) ;
UNUSED ( ndx ) ;
2008-09-26 15:09:30 +00:00
if ( ! val ) return TRUE ;
2008-09-26 22:09:12 +00:00
oval - > ptr = log_timestamp_new ( srv , value_extract ( val ) . string ) ;
2008-09-24 21:43:22 +00:00
return TRUE ;
2008-08-22 18:51:25 +00:00
}
2008-09-26 15:09:30 +00:00
static void core_option_log_timestamp_free ( server * srv , plugin * p , size_t ndx , option_value oval ) {
2008-08-22 18:51:25 +00:00
UNUSED ( p ) ;
UNUSED ( ndx ) ;
2008-09-26 14:11:08 +00:00
2008-09-26 15:09:30 +00:00
if ( ! oval . ptr ) return ;
2008-09-26 14:11:08 +00:00
log_timestamp_free ( srv , oval . ptr ) ;
2008-08-22 18:51:25 +00:00
}
2008-10-02 19:46:06 +00:00
static gboolean core_option_mime_types_parse ( server * srv , plugin * p , size_t ndx , value * val , option_value * oval ) {
2008-12-09 23:23:27 +00:00
GArray * arr ;
2008-10-02 19:46:06 +00:00
UNUSED ( srv ) ;
UNUSED ( p ) ;
UNUSED ( ndx ) ;
/* default value */
if ( ! val ) {
oval - > list = g_array_new ( FALSE , TRUE , sizeof ( value ) ) ;
return TRUE ;
}
/* check if the passed val is of type (("a", "b"), ("x", y")) */
arr = val - > data . list ;
for ( guint i = 0 ; i < arr - > len ; i + + ) {
value * v = g_array_index ( arr , value * , i ) ;
value * v1 , * v2 ;
if ( v - > type ! = VALUE_LIST ) {
ERROR ( srv , " mime_types option expects a list of string tuples, entry #%u is of type %s " , i , value_type_string ( v - > type ) ) ;
return FALSE ;
}
if ( v - > data . list - > len ! = 2 ) {
ERROR ( srv , " mime_types option expects a list of string tuples, entry #%u is not a tuple " , i ) ;
return FALSE ;
}
v1 = g_array_index ( v - > data . list , value * , 0 ) ;
v2 = g_array_index ( v - > data . list , value * , 1 ) ;
if ( v1 - > type ! = VALUE_STRING | | v2 - > type ! = VALUE_STRING ) {
ERROR ( srv , " mime_types option expects a list of string tuples, entry #%u is a (%s,%s) tuple " , i , value_type_string ( v1 - > type ) , value_type_string ( v2 - > type ) ) ;
return FALSE ;
}
}
/* everything ok */
oval - > list = value_extract ( val ) . list ;
return TRUE ;
}
static void core_option_mime_types_free ( server * srv , plugin * p , size_t ndx , option_value oval ) {
UNUSED ( srv ) ;
UNUSED ( p ) ;
UNUSED ( ndx ) ;
for ( guint i = 0 ; i < oval . list - > len ; i + + )
value_free ( g_array_index ( oval . list , value * , i ) ) ;
g_array_free ( oval . list , TRUE ) ;
}
2008-12-09 23:23:27 +00:00
static handler_t core_handle_header_add ( vrequest * vr , gpointer param , gpointer * context ) {
2008-10-04 01:21:31 +00:00
GArray * l = ( GArray * ) param ;
GString * k = g_array_index ( l , value * , 0 ) - > data . string ;
GString * v = g_array_index ( l , value * , 1 ) - > data . string ;
2008-12-09 23:23:27 +00:00
UNUSED ( param ) ;
UNUSED ( context ) ;
2008-10-04 01:21:31 +00:00
2008-10-25 16:01:02 +00:00
http_header_insert ( vr - > response . headers , GSTR_LEN ( k ) , GSTR_LEN ( v ) ) ;
2008-10-04 01:21:31 +00:00
2008-10-25 16:01:02 +00:00
return HANDLER_GO_ON ;
2008-10-04 01:21:31 +00:00
}
static void core_header_free ( struct server * srv , gpointer param ) {
UNUSED ( srv ) ;
2008-10-04 18:00:10 +00:00
value_list_free ( param ) ;
2008-10-04 01:21:31 +00:00
}
static action * core_header_add ( server * srv , plugin * p , value * val ) {
GArray * l ;
UNUSED ( p ) ;
if ( val - > type ! = VALUE_LIST ) {
ERROR ( srv , " 'core_header_add' action expects a string tuple as parameter, %s given " , value_type_string ( val - > type ) ) ;
return NULL ;
}
l = val - > data . list ;
if ( l - > len ! = 2 ) {
ERROR ( srv , " 'core_header_add' action expects a string tuple as parameter, list has %u entries " , l - > len ) ;
return NULL ;
}
if ( g_array_index ( l , value * , 0 ) - > type ! = VALUE_STRING | | g_array_index ( l , value * , 0 ) - > type ! = VALUE_STRING ) {
ERROR ( srv , " %s " , " 'core_header_add' action expects a string tuple as parameter " ) ;
return NULL ;
}
2008-12-09 23:23:27 +00:00
return action_new_function ( core_handle_header_add , NULL , core_header_free , value_extract ( val ) . list ) ;
2008-10-04 01:21:31 +00:00
}
2008-12-09 23:23:27 +00:00
static handler_t core_handle_header_append ( vrequest * vr , gpointer param , gpointer * context ) {
2008-10-04 01:21:31 +00:00
GArray * l = ( GArray * ) param ;
GString * k = g_array_index ( l , value * , 0 ) - > data . string ;
GString * v = g_array_index ( l , value * , 1 ) - > data . string ;
2008-12-09 23:23:27 +00:00
UNUSED ( param ) ;
UNUSED ( context ) ;
2008-10-04 01:21:31 +00:00