summaryrefslogtreecommitdiff
path: root/src/mod_evasive.c
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2016-05-12 01:11:48 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2016-05-13 20:49:33 -0400
commit0cd7f2dda83138174527f0c96a15bb9f4c5b7830 (patch)
treed65cc6c5056d919c0f153539bfc375c52176fa28 /src/mod_evasive.c
parentbd66026fc25da317a42abf9105fb317814ec3dfb (diff)
downloadlighttpd-git-0cd7f2dda83138174527f0c96a15bb9f4c5b7830.tar.gz
[mod_evasive] 302 redirect option if limit reached (fixes #2199)
x-ref: "[mod_evasive] redirect if maximum connections exceeded" https://redmine.lighttpd.net/issues/2199
Diffstat (limited to 'src/mod_evasive.c')
-rw-r--r--src/mod_evasive.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/mod_evasive.c b/src/mod_evasive.c
index 84b264af..3aebb986 100644
--- a/src/mod_evasive.c
+++ b/src/mod_evasive.c
@@ -3,6 +3,7 @@
#include "base.h"
#include "log.h"
#include "buffer.h"
+#include "response.h"
#include "plugin.h"
@@ -30,6 +31,7 @@
typedef struct {
unsigned short max_conns;
unsigned short silent;
+ buffer *location;
} plugin_config;
typedef struct {
@@ -62,6 +64,8 @@ FREE_FUNC(mod_evasive_free) {
if (NULL == s) continue;
+ buffer_free(s->location);
+
free(s);
}
free(p->config_storage);
@@ -79,6 +83,7 @@ SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
config_values_t cv[] = {
{ "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "evasive.silent", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
+ { "evasive.location", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -91,9 +96,11 @@ SETDEFAULTS_FUNC(mod_evasive_set_defaults) {
s = calloc(1, sizeof(plugin_config));
s->max_conns = 0;
s->silent = 0;
+ s->location = buffer_init();
cv[0].destination = &(s->max_conns);
cv[1].destination = &(s->silent);
+ cv[2].destination = s->location;
p->config_storage[i] = s;
@@ -113,6 +120,7 @@ static int mod_evasive_patch_connection(server *srv, connection *con, plugin_dat
PATCH(max_conns);
PATCH(silent);
+ PATCH(location);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -130,6 +138,8 @@ static int mod_evasive_patch_connection(server *srv, connection *con, plugin_dat
PATCH(max_conns);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.silent"))) {
PATCH(silent);
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.location"))) {
+ PATCH(location);
}
}
}
@@ -190,7 +200,13 @@ URIHANDLER_FUNC(mod_evasive_uri_handler) {
"turned away. Too many connections.");
}
- con->http_status = 403;
+ if (!buffer_is_empty(p->conf.location)) {
+ response_header_overwrite(srv, con, CONST_STR_LEN("Location"), CONST_BUF_LEN(p->conf.location));
+ con->http_status = 302;
+ con->file_finished = 1;
+ } else {
+ con->http_status = 403;
+ }
con->mode = DIRECT;
return HANDLER_FINISHED;
}