diff options
author | Arno Töll <arno@debian.org> | 2012-11-21 23:03:44 +0100 |
---|---|---|
committer | Arno Töll <arno@debian.org> | 2012-11-21 23:03:44 +0100 |
commit | c99b717062c6228c4ac6df3831702f81c9806df4 (patch) | |
tree | 8cc83ebb36aa5b7f8691152db83071784fbfc1c7 /src/mod_trigger_b4_dl.c | |
parent | 1b24d86e6b2179692e60091dec59f797cd308b9e (diff) | |
download | lighttpd-c99b717062c6228c4ac6df3831702f81c9806df4.tar.gz |
Imported Upstream version 1.4.13~r1370upstream/1.4.13_r1370
Diffstat (limited to 'src/mod_trigger_b4_dl.c')
-rw-r--r-- | src/mod_trigger_b4_dl.c | 246 |
1 files changed, 123 insertions, 123 deletions
diff --git a/src/mod_trigger_b4_dl.c b/src/mod_trigger_b4_dl.c index bc49b1e..8281ec0 100644 --- a/src/mod_trigger_b4_dl.c +++ b/src/mod_trigger_b4_dl.c @@ -24,18 +24,18 @@ /** * this is a trigger_b4_dl for a lighttpd plugin - * + * */ /* plugin config for all request/connections */ typedef struct { buffer *db_filename; - + buffer *trigger_url; buffer *download_url; buffer *deny_url; - + array *mc_hosts; buffer *mc_namespace; #if defined(HAVE_PCRE_H) @@ -46,58 +46,58 @@ typedef struct { GDBM_FILE db; #endif -#if defined(HAVE_MEMCACHE_H) +#if defined(HAVE_MEMCACHE_H) struct memcache *mc; #endif - + unsigned short trigger_timeout; unsigned short debug; } plugin_config; typedef struct { PLUGIN_DATA; - + buffer *tmp_buf; - + plugin_config **config_storage; - - plugin_config conf; + + plugin_config conf; } plugin_data; /* init the plugin data */ INIT_FUNC(mod_trigger_b4_dl_init) { plugin_data *p; - + p = calloc(1, sizeof(*p)); - + p->tmp_buf = buffer_init(); - + return p; } /* detroy the plugin data */ FREE_FUNC(mod_trigger_b4_dl_free) { plugin_data *p = p_d; - + UNUSED(srv); if (!p) return HANDLER_GO_ON; - + if (p->config_storage) { size_t i; for (i = 0; i < srv->config_context->used; i++) { plugin_config *s = p->config_storage[i]; if (!s) continue; - + buffer_free(s->db_filename); buffer_free(s->download_url); buffer_free(s->trigger_url); buffer_free(s->deny_url); - + buffer_free(s->mc_namespace); array_free(s->mc_hosts); - + #if defined(HAVE_PCRE_H) if (s->trigger_regex) pcre_free(s->trigger_regex); if (s->download_regex) pcre_free(s->download_regex); @@ -108,16 +108,16 @@ FREE_FUNC(mod_trigger_b4_dl_free) { #if defined(HAVE_MEMCACHE_H) if (s->mc) mc_free(s->mc); #endif - + free(s); } free(p->config_storage); } - + buffer_free(p->tmp_buf); - + free(p); - + return HANDLER_GO_ON; } @@ -126,9 +126,9 @@ FREE_FUNC(mod_trigger_b4_dl_free) { SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { plugin_data *p = p_d; size_t i = 0; - - - config_values_t cv[] = { + + + config_values_t cv[] = { { "trigger-before-download.gdbm-filename", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ { "trigger-before-download.trigger-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 1 */ { "trigger-before-download.download-url", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */ @@ -139,18 +139,18 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { { "trigger-before-download.debug", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; - + if (!p) return HANDLER_ERROR; - + p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); - + for (i = 0; i < srv->config_context->used; i++) { plugin_config *s; #if defined(HAVE_PCRE_H) const char *errptr; int erroff; #endif - + s = calloc(1, sizeof(plugin_config)); s->db_filename = buffer_init(); s->download_url = buffer_init(); @@ -158,7 +158,7 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { s->deny_url = buffer_init(); s->mc_hosts = array_init(); s->mc_namespace = buffer_init(); - + cv[0].destination = s->db_filename; cv[1].destination = s->trigger_url; cv[2].destination = s->download_url; @@ -167,41 +167,41 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { cv[5].destination = s->mc_hosts; cv[6].destination = s->mc_namespace; cv[7].destination = &(s->debug); - + p->config_storage[i] = s; - + if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { return HANDLER_ERROR; } #if defined(HAVE_GDBM_H) if (!buffer_is_empty(s->db_filename)) { if (NULL == (s->db = gdbm_open(s->db_filename->ptr, 4096, GDBM_WRCREAT | GDBM_NOLOCK, S_IRUSR | S_IWUSR, 0))) { - log_error_write(srv, __FILE__, __LINE__, "s", + log_error_write(srv, __FILE__, __LINE__, "s", "gdbm-open failed"); return HANDLER_ERROR; } } #endif -#if defined(HAVE_PCRE_H) +#if defined(HAVE_PCRE_H) if (!buffer_is_empty(s->download_url)) { if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr, 0, &errptr, &erroff, NULL))) { - - log_error_write(srv, __FILE__, __LINE__, "sbss", - "compiling regex for download-url failed:", + + log_error_write(srv, __FILE__, __LINE__, "sbss", + "compiling regex for download-url failed:", s->download_url, "pos:", erroff); return HANDLER_ERROR; } } - + if (!buffer_is_empty(s->trigger_url)) { if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr, 0, &errptr, &erroff, NULL))) { - - log_error_write(srv, __FILE__, __LINE__, "sbss", - "compiling regex for trigger-url failed:", + + log_error_write(srv, __FILE__, __LINE__, "sbss", + "compiling regex for trigger-url failed:", s->trigger_url, "pos:", erroff); - + return HANDLER_ERROR; } } @@ -211,33 +211,33 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { #if defined(HAVE_MEMCACHE_H) size_t k; s->mc = mc_new(); - + for (k = 0; k < s->mc_hosts->used; k++) { data_string *ds = (data_string *)s->mc_hosts->data[k]; - + if (0 != mc_server_add4(s->mc, ds->value->ptr)) { - log_error_write(srv, __FILE__, __LINE__, "sb", - "connection to host failed:", + log_error_write(srv, __FILE__, __LINE__, "sb", + "connection to host failed:", ds->value); - + return HANDLER_ERROR; } } #else - log_error_write(srv, __FILE__, __LINE__, "s", + log_error_write(srv, __FILE__, __LINE__, "s", "memcache support is not compiled in but trigger-before-download.memcache-hosts is set, aborting"); return HANDLER_ERROR; #endif } - + #if (!defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)) || !defined(HAVE_PCRE_H) - log_error_write(srv, __FILE__, __LINE__, "s", + log_error_write(srv, __FILE__, __LINE__, "s", "(either gdbm or libmemcache) and pcre are require, but were not found, aborting"); return HANDLER_ERROR; #endif } - + return HANDLER_GO_ON; } @@ -246,14 +246,14 @@ SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) { static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plugin_data *p) { size_t i, j; plugin_config *s = p->config_storage[0]; - + #if defined(HAVE_GDBM) PATCH(db); -#endif +#endif #if defined(HAVE_PCRE_H) PATCH(download_regex); PATCH(trigger_regex); -#endif +#endif PATCH(trigger_timeout); PATCH(deny_url); PATCH(mc_namespace); @@ -261,15 +261,15 @@ static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plug #if defined(HAVE_MEMCACHE_H) PATCH(mc); #endif - + /* skip the first, the global context */ for (i = 1; i < srv->config_context->used; i++) { data_config *dc = (data_config *)srv->config_context->data[i]; s = p->config_storage[i]; - + /* condition didn't match */ if (!config_check_cond(srv, con, dc)) continue; - + /* merge config */ for (j = 0; j < dc->value->used; j++) { data_unset *du = dc->value->data[j]; @@ -301,7 +301,7 @@ static int mod_trigger_b4_dl_patch_connection(server *srv, connection *con, plug } } } - + return 0; } #undef PATCH @@ -315,20 +315,20 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { int n; # define N 10 int ovec[N * 3]; - + if (con->uri.path->used == 0) return HANDLER_GO_ON; - + mod_trigger_b4_dl_patch_connection(srv, con, p); - + if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON; - + # if !defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H) return HANDLER_GO_ON; # elif defined(HAVE_GDBM_H) && defined(HAVE_MEMCACHE_H) if (!p->conf.db && !p->conf.mc) return HANDLER_GO_ON; if (p->conf.db && p->conf.mc) { /* can't decide which one */ - + return HANDLER_GO_ON; } # elif defined(HAVE_GDBM_H) @@ -336,12 +336,12 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { # else if (!p->conf.mc) return HANDLER_GO_ON; # endif - + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) { /* X-Forwarded-For contains the ip behind the proxy */ - + remote_ip = ds->value->ptr; - + /* memcache can't handle spaces */ } else { remote_ip = inet_ntop_cache_get_ip(srv, &(con->dst_addr)); @@ -350,13 +350,13 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "ss", "(debug) remote-ip:", remote_ip); } - + /* check if URL is a trigger -> insert IP into DB */ if ((n = pcre_exec(p->conf.trigger_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) { if (n != PCRE_ERROR_NOMATCH) { log_error_write(srv, __FILE__, __LINE__, "sd", "execution error while matching:", n); - + return HANDLER_ERROR; } } else { @@ -364,34 +364,34 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { if (p->conf.db) { /* the trigger matched */ datum key, val; - + key.dptr = (char *)remote_ip; key.dsize = strlen(remote_ip); - + val.dptr = (char *)&(srv->cur_ts); val.dsize = sizeof(srv->cur_ts); - + if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) { log_error_write(srv, __FILE__, __LINE__, "s", "insert failed"); } } # endif -# if defined(HAVE_MEMCACHE_H) +# if defined(HAVE_MEMCACHE_H) if (p->conf.mc) { size_t i; buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace); buffer_append_string(p->tmp_buf, remote_ip); - + for (i = 0; i < p->tmp_buf->used - 1; i++) { if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; } - + if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf); } - if (0 != mc_set(p->conf.mc, + if (0 != mc_set(p->conf.mc, CONST_BUF_LEN(p->tmp_buf), (char *)&(srv->cur_ts), sizeof(srv->cur_ts), p->conf.trigger_timeout, 0)) { @@ -401,7 +401,7 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { } # endif } - + /* check if URL is a download -> check IP in DB, update timestamp */ if ((n = pcre_exec(p->conf.download_regex, NULL, con->uri.path->ptr, con->uri.path->used - 1, 0, 0, ovec, 3 * N)) < 0) { if (n != PCRE_ERROR_NOMATCH) { @@ -411,93 +411,93 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { } } else { /* the download uri matched */ -# if defined(HAVE_GDBM_H) +# if defined(HAVE_GDBM_H) if (p->conf.db) { datum key, val; time_t last_hit; - + key.dptr = (char *)remote_ip; key.dsize = strlen(remote_ip); - + val = gdbm_fetch(p->conf.db, key); - + if (val.dptr == NULL) { /* not found, redirect */ - + response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); - + con->http_status = 307; - + return HANDLER_FINISHED; } - + last_hit = *(time_t *)(val.dptr); - + free(val.dptr); - + if (srv->cur_ts - last_hit > p->conf.trigger_timeout) { /* found, but timeout, redirect */ - + response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); con->http_status = 307; - + if (p->conf.db) { if (0 != gdbm_delete(p->conf.db, key)) { log_error_write(srv, __FILE__, __LINE__, "s", "delete failed"); } } - + return HANDLER_FINISHED; } - + val.dptr = (char *)&(srv->cur_ts); val.dsize = sizeof(srv->cur_ts); - + if (0 != gdbm_store(p->conf.db, key, val, GDBM_REPLACE)) { log_error_write(srv, __FILE__, __LINE__, "s", "insert failed"); } } # endif - -# if defined(HAVE_MEMCACHE_H) + +# if defined(HAVE_MEMCACHE_H) if (p->conf.mc) { void *r; size_t i; - + buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace); buffer_append_string(p->tmp_buf, remote_ip); - + for (i = 0; i < p->tmp_buf->used - 1; i++) { if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; } - + if (p->conf.debug) { log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) checking IP:", p->tmp_buf); } /** - * + * * memcached is do expiration for us, as long as we can fetch it every thing is ok - * and the timestamp is updated - * + * and the timestamp is updated + * */ - if (NULL == (r = mc_aget(p->conf.mc, + if (NULL == (r = mc_aget(p->conf.mc, CONST_BUF_LEN(p->tmp_buf) ))) { - + response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); - + con->http_status = 307; - + return HANDLER_FINISHED; } - + free(r); - + /* set a new timeout */ - if (0 != mc_set(p->conf.mc, + if (0 != mc_set(p->conf.mc, CONST_BUF_LEN(p->tmp_buf), (char *)&(srv->cur_ts), sizeof(srv->cur_ts), p->conf.trigger_timeout, 0)) { @@ -507,13 +507,13 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { } # endif } - + #else UNUSED(srv); UNUSED(con); UNUSED(p_d); #endif - + return HANDLER_GO_ON; } @@ -521,21 +521,21 @@ URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) { TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) { plugin_data *p = p_d; size_t i; - + /* check DB each minute */ if (srv->cur_ts % 60 != 0) return HANDLER_GO_ON; - + /* cleanup */ for (i = 0; i < srv->config_context->used; i++) { plugin_config *s = p->config_storage[i]; datum key, val, okey; - + if (!s->db) continue; - + okey.dptr = NULL; - - /* according to the manual this loop + delete does delete all entries on its way - * + + /* according to the manual this loop + delete does delete all entries on its way + * * we don't care as the next round will remove them. We don't have to perfect here. */ for (key = gdbm_firstkey(s->db); key.dptr; key = gdbm_nextkey(s->db, okey)) { @@ -544,21 +544,21 @@ TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) { free(okey.dptr); okey.dptr = NULL; } - + val = gdbm_fetch(s->db, key); - + last_hit = *(time_t *)(val.dptr); - + free(val.dptr); - + if (srv->cur_ts - last_hit > s->trigger_timeout) { gdbm_delete(s->db, key); } - + okey = key; } if (okey.dptr) free(okey.dptr); - + /* reorg once a day */ if ((srv->cur_ts % (60 * 60 * 24) != 0)) gdbm_reorganize(s->db); } @@ -571,7 +571,7 @@ TRIGGER_FUNC(mod_trigger_b4_dl_handle_trigger) { int mod_trigger_b4_dl_plugin_init(plugin *p) { p->version = LIGHTTPD_VERSION_ID; p->name = buffer_init_string("trigger_b4_dl"); - + p->init = mod_trigger_b4_dl_init; p->handle_uri_clean = mod_trigger_b4_dl_uri_handler; p->set_defaults = mod_trigger_b4_dl_set_defaults; @@ -579,8 +579,8 @@ int mod_trigger_b4_dl_plugin_init(plugin *p) { p->handle_trigger = mod_trigger_b4_dl_handle_trigger; #endif p->cleanup = mod_trigger_b4_dl_free; - + p->data = NULL; - + return 0; } |