@ -25,6 +25,7 @@
typedef struct {
array * expire_url ;
array * expire_mimetypes ;
} plugin_config ;
typedef struct {
@ -68,6 +69,7 @@ FREE_FUNC(mod_expire_free) {
if ( NULL = = s ) continue ;
array_free ( s - > expire_url ) ;
array_free ( s - > expire_mimetypes ) ;
free ( s ) ;
}
free ( p - > config_storage ) ;
@ -219,6 +221,7 @@ SETDEFAULTS_FUNC(mod_expire_set_defaults) {
config_values_t cv [ ] = {
{ " expire.url " , NULL , T_CONFIG_ARRAY , T_CONFIG_SCOPE_CONNECTION } , /* 0 */
{ " expire.mimetypes " , NULL , T_CONFIG_ARRAY , T_CONFIG_SCOPE_CONNECTION } , /* 1 */
{ NULL , NULL , T_CONFIG_UNSET , T_CONFIG_SCOPE_UNSET }
} ;
@ -232,8 +235,10 @@ SETDEFAULTS_FUNC(mod_expire_set_defaults) {
s = calloc ( 1 , sizeof ( plugin_config ) ) ;
s - > expire_url = array_init ( ) ;
s - > expire_mimetypes = array_init ( ) ;
cv [ 0 ] . destination = s - > expire_url ;
cv [ 1 ] . destination = s - > expire_mimetypes ;
p - > config_storage [ i ] = s ;
@ -251,6 +256,17 @@ SETDEFAULTS_FUNC(mod_expire_set_defaults) {
return HANDLER_ERROR ;
}
}
for ( k = 0 ; k < s - > expire_mimetypes - > used ; k + + ) {
data_string * ds = ( data_string * ) s - > expire_mimetypes - > data [ k ] ;
/* parse lines */
if ( - 1 = = mod_expire_get_offset ( srv , p , ds - > value , NULL ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " sb " ,
" parsing expire.mimetypes failed: " , ds - > value ) ;
return HANDLER_ERROR ;
}
}
}
@ -264,6 +280,7 @@ static int mod_expire_patch_connection(server *srv, connection *con, plugin_data
plugin_config * s = p - > config_storage [ 0 ] ;
PATCH ( expire_url ) ;
PATCH ( expire_mimetypes ) ;
/* skip the first, the global context */
for ( i = 1 ; i < srv - > config_context - > used ; i + + ) {
@ -279,6 +296,8 @@ static int mod_expire_patch_connection(server *srv, connection *con, plugin_data
if ( buffer_is_equal_string ( du - > key , CONST_STR_LEN ( " expire.url " ) ) ) {
PATCH ( expire_url ) ;
} else if ( buffer_is_equal_string ( du - > key , CONST_STR_LEN ( " expire.mimetypes " ) ) ) {
PATCH ( expire_mimetypes ) ;
}
}
}
@ -287,25 +306,72 @@ static int mod_expire_patch_connection(server *srv, connection *con, plugin_data
}
# undef PATCH
URIHANDLER _FUNC( mod_expire_path _handler ) {
CONNECTION _FUNC( mod_expire_handler ) {
plugin_data * p = p_d ;
int s_len ;
data_string * ds = NULL ;
size_t s_len ;
size_t k ;
/* Add caching headers only to http_status 200 OK or 206 Partial Content */
if ( con - > http_status ! = 200 & & con - > http_status ! = 206 ) return HANDLER_GO_ON ;
/* Add caching headers only to GET or HEAD requests */
if ( con - > request . http_method ! = HTTP_METHOD_GET
& & con - > request . http_method ! = HTTP_METHOD_HEAD ) return HANDLER_GO_ON ;
/* Add caching headers only if not already present */
ds = ( data_string * ) array_get_element ( con - > response . headers , " Cache-Control " ) ;
if ( NULL ! = ds & & ! buffer_string_is_empty ( ds - > value ) ) return HANDLER_GO_ON ;
if ( buffer_is_empty ( con - > uri . path ) ) return HANDLER_GO_ON ;
mod_expire_patch_connection ( srv , con , p ) ;
s_len = buffer_string_length ( con - > uri . path ) ;
/* check expire.url */
for ( k = 0 ; k < p - > conf . expire_url - > used ; k + + ) {
data_string * ds = ( data_string * ) p - > conf . expire_url - > data [ k ] ;
int ct_len = buffer_string_length ( ds - > key ) ;
size_t ct_len ;
ds = ( data_string * ) p - > conf . expire_url - > data [ k ] ;
ct_len = buffer_string_length ( ds - > key ) ;
if ( ct_len > s_len ) continue ;
if ( buffer_is_empty ( ds - > key ) ) continue ;
if ( 0 = = strncmp ( con - > uri . path - > ptr , ds - > key - > ptr , ct_len ) ) {
break ;
}
}
/* check expire.mimetypes (if no match with expire.url) */
if ( k = = p - > conf . expire_url - > used ) {
const char * mimetype ;
ds = ( data_string * ) array_get_element ( con - > response . headers , " Content-Type " ) ;
if ( NULL ! = ds & & ! buffer_string_is_empty ( ds - > value ) ) {
mimetype = ds - > value - > ptr ;
s_len = buffer_string_length ( ds - > value ) ;
} else {
mimetype = " " ;
s_len = 0 ;
}
for ( k = 0 ; k < p - > conf . expire_mimetypes - > used ; k + + ) {
size_t ct_len ;
ds = ( data_string * ) p - > conf . expire_mimetypes - > data [ k ] ;
ct_len = buffer_string_length ( ds - > key ) ;
if ( ct_len > s_len ) continue ;
if ( buffer_is_empty ( ds - > key ) ) continue ;
/*(omit trailing '*', if present, from prefix match)*/
if ( ds - > key - > ptr [ ct_len - 1 ] = = ' * ' ) - - ct_len ;
if ( 0 = = strncmp ( mimetype , ds - > key - > ptr , ct_len ) ) {
break ;
}
}
if ( k = = p - > conf . expire_mimetypes - > used ) {
ds = NULL ;
}
}
if ( NULL ! = ds ) {
time_t ts , expires ;
stat_cache_entry * sce = NULL ;
@ -348,7 +414,6 @@ URIHANDLER_FUNC(mod_expire_path_handler) {
response_header_append ( srv , con , CONST_STR_LEN ( " Cache-Control " ) , CONST_BUF_LEN ( p - > expire_tstmp ) ) ;
return HANDLER_GO_ON ;
}
}
/* not found */
@ -363,7 +428,7 @@ int mod_expire_plugin_init(plugin *p) {
p - > name = buffer_init_string ( " expire " ) ;
p - > init = mod_expire_init ;
p - > handle_subrequest _start = mod_expire_path _handler ;
p - > handle_response _start = mod_expire_handler ;
p - > set_defaults = mod_expire_set_defaults ;
p - > cleanup = mod_expire_free ;