version 1.1.1.2, 2014/06/15 20:20:06
|
version 1.1.1.3, 2016/11/02 10:35:00
|
Line 1
|
Line 1
|
|
#include "first.h" |
|
|
#include "base.h" |
#include "base.h" |
#include "log.h" |
#include "log.h" |
#include "buffer.h" |
#include "buffer.h" |
Line 11
|
Line 13
|
#include <fcntl.h> |
#include <fcntl.h> |
#include <string.h> |
#include <string.h> |
|
|
|
#if (defined(HAVE_GDBM_H) || defined(USE_MEMCACHED)) && defined(HAVE_PCRE_H) |
|
|
#if defined(HAVE_GDBM_H) |
#if defined(HAVE_GDBM_H) |
# include <gdbm.h> |
# include <gdbm.h> |
#endif |
#endif |
Line 19
|
Line 23
|
# include <pcre.h> |
# include <pcre.h> |
#endif |
#endif |
|
|
#if defined(HAVE_MEMCACHE_H) | #if defined(USE_MEMCACHED) |
# include <memcache.h> | # include <libmemcached/memcached.h> |
#endif |
#endif |
|
|
/** |
/** |
Line 47 typedef struct {
|
Line 51 typedef struct {
|
GDBM_FILE db; |
GDBM_FILE db; |
#endif |
#endif |
|
|
#if defined(HAVE_MEMCACHE_H) | #if defined(USE_MEMCACHED) |
struct memcache *mc; | memcached_st *memc; |
#endif |
#endif |
|
|
unsigned short trigger_timeout; |
unsigned short trigger_timeout; |
Line 89 FREE_FUNC(mod_trigger_b4_dl_free) {
|
Line 93 FREE_FUNC(mod_trigger_b4_dl_free) {
|
for (i = 0; i < srv->config_context->used; i++) { |
for (i = 0; i < srv->config_context->used; i++) { |
plugin_config *s = p->config_storage[i]; |
plugin_config *s = p->config_storage[i]; |
|
|
if (!s) continue; | if (NULL == s) continue; |
|
|
buffer_free(s->db_filename); |
buffer_free(s->db_filename); |
buffer_free(s->download_url); |
buffer_free(s->download_url); |
Line 106 FREE_FUNC(mod_trigger_b4_dl_free) {
|
Line 110 FREE_FUNC(mod_trigger_b4_dl_free) {
|
#if defined(HAVE_GDBM_H) |
#if defined(HAVE_GDBM_H) |
if (s->db) gdbm_close(s->db); |
if (s->db) gdbm_close(s->db); |
#endif |
#endif |
#if defined(HAVE_MEMCACHE_H) | #if defined(USE_MEMCACHED) |
if (s->mc) mc_free(s->mc); | if (s->memc) memcached_free(s->memc); |
#endif |
#endif |
|
|
free(s); |
free(s); |
Line 146 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
Line 150 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *)); |
p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *)); |
|
|
for (i = 0; i < srv->config_context->used; i++) { |
for (i = 0; i < srv->config_context->used; i++) { |
|
data_config const* config = (data_config const*)srv->config_context->data[i]; |
plugin_config *s; |
plugin_config *s; |
#if defined(HAVE_PCRE_H) |
#if defined(HAVE_PCRE_H) |
const char *errptr; |
const char *errptr; |
Line 171 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
Line 176 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
|
|
p->config_storage[i] = s; |
p->config_storage[i] = s; |
|
|
if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { | if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) { |
return HANDLER_ERROR; |
return HANDLER_ERROR; |
} |
} |
#if defined(HAVE_GDBM_H) |
#if defined(HAVE_GDBM_H) |
if (!buffer_is_empty(s->db_filename)) { | if (!buffer_string_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))) { |
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"); |
"gdbm-open failed"); |
Line 185 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
Line 190 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
} |
} |
#endif |
#endif |
#if defined(HAVE_PCRE_H) |
#if defined(HAVE_PCRE_H) |
if (!buffer_is_empty(s->download_url)) { | if (!buffer_string_is_empty(s->download_url)) { |
if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr, |
if (NULL == (s->download_regex = pcre_compile(s->download_url->ptr, |
0, &errptr, &erroff, NULL))) { |
0, &errptr, &erroff, NULL))) { |
|
|
Line 196 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
Line 201 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
} |
} |
} |
} |
|
|
if (!buffer_is_empty(s->trigger_url)) { | if (!buffer_string_is_empty(s->trigger_url)) { |
if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr, |
if (NULL == (s->trigger_regex = pcre_compile(s->trigger_url->ptr, |
0, &errptr, &erroff, NULL))) { |
0, &errptr, &erroff, NULL))) { |
|
|
Line 210 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
Line 215 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
#endif |
#endif |
|
|
if (s->mc_hosts->used) { |
if (s->mc_hosts->used) { |
#if defined(HAVE_MEMCACHE_H) | #if defined(USE_MEMCACHED) |
| buffer *option_string = buffer_init(); |
size_t k; |
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[0]; |
| |
| buffer_append_string_len(option_string, CONST_STR_LEN("--SERVER=")); |
| buffer_append_string_buffer(option_string, ds->value); |
| } |
| |
| for (k = 1; k < s->mc_hosts->used; k++) { |
data_string *ds = (data_string *)s->mc_hosts->data[k]; |
data_string *ds = (data_string *)s->mc_hosts->data[k]; |
|
|
if (0 != mc_server_add4(s->mc, ds->value->ptr)) { | buffer_append_string_len(option_string, CONST_STR_LEN(" --SERVER=")); |
log_error_write(srv, __FILE__, __LINE__, "sb", | buffer_append_string_buffer(option_string, ds->value); |
"connection to host failed:", | } |
ds->value); | |
|
|
return HANDLER_ERROR; | s->memc = memcached(CONST_BUF_LEN(option_string)); |
} | |
| if (NULL == s->memc) { |
| log_error_write(srv, __FILE__, __LINE__, "sb", |
| "configuring memcached failed for option string:", |
| option_string); |
} |
} |
|
buffer_free(option_string); |
|
|
|
if (NULL == s->memc) return HANDLER_ERROR; |
#else |
#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"); |
"memcache support is not compiled in but trigger-before-download.memcache-hosts is set, aborting"); |
Line 233 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
Line 251 SETDEFAULTS_FUNC(mod_trigger_b4_dl_set_defaults) {
|
} |
} |
|
|
|
|
#if (!defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H)) || !defined(HAVE_PCRE_H) | #if (!defined(HAVE_GDBM_H) && !defined(USE_MEMCACHED)) || !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"); | "(either gdbm or libmemcached) and pcre are require, but were not found, aborting"); |
return HANDLER_ERROR; |
return HANDLER_ERROR; |
#endif |
#endif |
} |
} |
Line 260 static int mod_trigger_b4_dl_patch_connection(server *
|
Line 278 static int mod_trigger_b4_dl_patch_connection(server *
|
PATCH(deny_url); |
PATCH(deny_url); |
PATCH(mc_namespace); |
PATCH(mc_namespace); |
PATCH(debug); |
PATCH(debug); |
#if defined(HAVE_MEMCACHE_H) | #if defined(USE_MEMCACHED) |
PATCH(mc); | PATCH(memc); |
#endif |
#endif |
|
|
/* skip the first, the global context */ |
/* skip the first, the global context */ |
Line 297 static int mod_trigger_b4_dl_patch_connection(server *
|
Line 315 static int mod_trigger_b4_dl_patch_connection(server *
|
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) { |
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-namespace"))) { |
PATCH(mc_namespace); |
PATCH(mc_namespace); |
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) { |
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("trigger-before-download.memcache-hosts"))) { |
#if defined(HAVE_MEMCACHE_H) | #if defined(USE_MEMCACHED) |
PATCH(mc); | PATCH(memc); |
#endif |
#endif |
} |
} |
} |
} |
Line 320 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 338 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
|
|
if (con->mode != DIRECT) return HANDLER_GO_ON; |
if (con->mode != DIRECT) return HANDLER_GO_ON; |
|
|
if (con->uri.path->used == 0) return HANDLER_GO_ON; | if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON; |
|
|
mod_trigger_b4_dl_patch_connection(srv, con, p); |
mod_trigger_b4_dl_patch_connection(srv, con, p); |
|
|
if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON; |
if (!p->conf.trigger_regex || !p->conf.download_regex) return HANDLER_GO_ON; |
|
|
# if !defined(HAVE_GDBM_H) && !defined(HAVE_MEMCACHE_H) | # if !defined(HAVE_GDBM_H) && !defined(USE_MEMCACHED) |
return HANDLER_GO_ON; |
return HANDLER_GO_ON; |
# elif defined(HAVE_GDBM_H) && defined(HAVE_MEMCACHE_H) | # elif defined(HAVE_GDBM_H) && defined(USE_MEMCACHED) |
if (!p->conf.db && !p->conf.mc) return HANDLER_GO_ON; | if (!p->conf.db && !p->conf.memc) return HANDLER_GO_ON; |
if (p->conf.db && p->conf.mc) { | if (p->conf.db && p->conf.memc) { |
/* can't decide which one */ |
/* can't decide which one */ |
|
|
return HANDLER_GO_ON; |
return HANDLER_GO_ON; |
Line 338 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 356 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
# elif defined(HAVE_GDBM_H) |
# elif defined(HAVE_GDBM_H) |
if (!p->conf.db) return HANDLER_GO_ON; |
if (!p->conf.db) return HANDLER_GO_ON; |
# else |
# else |
if (!p->conf.mc) return HANDLER_GO_ON; | if (!p->conf.memc) return HANDLER_GO_ON; |
# endif |
# endif |
|
|
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) { |
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "X-Forwarded-For"))) { |
Line 356 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 374 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
} |
} |
|
|
/* check if URL is a trigger -> insert IP into DB */ |
/* 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_exec(p->conf.trigger_regex, NULL, CONST_BUF_LEN(con->uri.path), 0, 0, ovec, 3 * N)) < 0) { |
if (n != PCRE_ERROR_NOMATCH) { |
if (n != PCRE_ERROR_NOMATCH) { |
log_error_write(srv, __FILE__, __LINE__, "sd", |
log_error_write(srv, __FILE__, __LINE__, "sd", |
"execution error while matching:", n); |
"execution error while matching:", n); |
Line 381 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 399 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
} |
} |
} |
} |
# endif |
# endif |
# if defined(HAVE_MEMCACHE_H) | # if defined(USE_MEMCACHED) |
if (p->conf.mc) { | if (p->conf.memc) { |
size_t i; | size_t i, len; |
buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace); | buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace); |
buffer_append_string(p->tmp_buf, remote_ip); |
buffer_append_string(p->tmp_buf, remote_ip); |
|
|
for (i = 0; i < p->tmp_buf->used - 1; i++) { | len = buffer_string_length(p->tmp_buf); |
| for (i = 0; i < len; i++) { |
if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; |
if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; |
} |
} |
|
|
Line 395 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 414 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf); |
log_error_write(srv, __FILE__, __LINE__, "sb", "(debug) triggered IP:", p->tmp_buf); |
} |
} |
|
|
if (0 != mc_set(p->conf.mc, | if (MEMCACHED_SUCCESS != memcached_set(p->conf.memc, |
CONST_BUF_LEN(p->tmp_buf), |
CONST_BUF_LEN(p->tmp_buf), |
(char *)&(srv->cur_ts), sizeof(srv->cur_ts), | (const char *)&(srv->cur_ts), sizeof(srv->cur_ts), |
p->conf.trigger_timeout, 0)) { |
p->conf.trigger_timeout, 0)) { |
log_error_write(srv, __FILE__, __LINE__, "s", |
log_error_write(srv, __FILE__, __LINE__, "s", |
"insert failed"); | "insert failed"); |
} |
} |
} |
} |
# endif |
# endif |
} |
} |
|
|
/* check if URL is a download -> check IP in DB, update timestamp */ |
/* 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_exec(p->conf.download_regex, NULL, CONST_BUF_LEN(con->uri.path), 0, 0, ovec, 3 * N)) < 0) { |
if (n != PCRE_ERROR_NOMATCH) { |
if (n != PCRE_ERROR_NOMATCH) { |
log_error_write(srv, __FILE__, __LINE__, "sd", |
log_error_write(srv, __FILE__, __LINE__, "sd", |
"execution error while matching: ", n); |
"execution error while matching: ", n); |
Line 466 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 485 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
} |
} |
# endif |
# endif |
|
|
# if defined(HAVE_MEMCACHE_H) | # if defined(USE_MEMCACHED) |
if (p->conf.mc) { | if (p->conf.memc) { |
void *r; | size_t i, len; |
size_t i; | |
|
|
buffer_copy_string_buffer(p->tmp_buf, p->conf.mc_namespace); | buffer_copy_buffer(p->tmp_buf, p->conf.mc_namespace); |
buffer_append_string(p->tmp_buf, remote_ip); |
buffer_append_string(p->tmp_buf, remote_ip); |
|
|
for (i = 0; i < p->tmp_buf->used - 1; i++) { | len = buffer_string_length(p->tmp_buf); |
| for (i = 0; i < len; i++) { |
if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; |
if (p->tmp_buf->ptr[i] == ' ') p->tmp_buf->ptr[i] = '-'; |
} |
} |
|
|
Line 488 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 507 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
* and the timestamp is updated |
* and the timestamp is updated |
* |
* |
*/ |
*/ |
if (NULL == (r = mc_aget(p->conf.mc, | if (MEMCACHED_SUCCESS != memcached_exist(p->conf.memc, CONST_BUF_LEN(p->tmp_buf))) { |
CONST_BUF_LEN(p->tmp_buf) | |
))) { | |
| |
response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); |
response_header_insert(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.deny_url)); |
|
|
con->http_status = 307; |
con->http_status = 307; |
Line 500 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
Line 516 URIHANDLER_FUNC(mod_trigger_b4_dl_uri_handler) {
|
return HANDLER_FINISHED; |
return HANDLER_FINISHED; |
} |
} |
|
|
free(r); |
|
|
|
/* set a new timeout */ |
/* set a new timeout */ |
if (0 != mc_set(p->conf.mc, | if (MEMCACHED_SUCCESS != memcached_set(p->conf.memc, |
CONST_BUF_LEN(p->tmp_buf), |
CONST_BUF_LEN(p->tmp_buf), |
(char *)&(srv->cur_ts), sizeof(srv->cur_ts), | (const char *)&(srv->cur_ts), sizeof(srv->cur_ts), |
p->conf.trigger_timeout, 0)) { |
p->conf.trigger_timeout, 0)) { |
log_error_write(srv, __FILE__, __LINE__, "s", |
log_error_write(srv, __FILE__, __LINE__, "s", |
"insert failed"); | "insert failed"); |
} |
} |
} |
} |
# endif |
# endif |
Line 591 int mod_trigger_b4_dl_plugin_init(plugin *p) {
|
Line 605 int mod_trigger_b4_dl_plugin_init(plugin *p) {
|
|
|
return 0; |
return 0; |
} |
} |
|
|
|
#else |
|
|
|
#pragma message("(either gdbm or libmemcached) and pcre are required, but were not found") |
|
|
|
int mod_trigger_b4_dl_plugin_init(plugin *p); |
|
int mod_trigger_b4_dl_plugin_init(plugin *p) { |
|
UNUSED(p); |
|
return -1; |
|
} |
|
|
|
#endif |