--- lighttpd-1.4.13/src/mod_evasive.c~ 2006-10-10 03:02:12.749561697 +0300 +++ lighttpd-1.4.13/src/mod_evasive.c 2006-10-10 03:14:39.056335465 +0300 @@ -27,11 +27,15 @@ typedef struct { unsigned short max_conns; + unsigned short http_status_code; + unsigned int retry_after; } plugin_config; typedef struct { PLUGIN_DATA; + buffer *evasive_rftmp; + plugin_config **config_storage; plugin_config conf; @@ -42,6 +46,10 @@ p = calloc(1, sizeof(*p)); + p->evasive_rftmp = buffer_init(); + + buffer_prepare_copy(p->evasive_rftmp, 255); + return p; } @@ -52,6 +60,8 @@ if (!p) return HANDLER_GO_ON; + buffer_free(p->evasive_rftmp); + if (p->config_storage) { size_t i; for (i = 0; i < srv->config_context->used; i++) { @@ -73,6 +83,8 @@ config_values_t cv[] = { { "evasive.max-conns-per-ip", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, + { "evasive.http-status-code", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, + { "evasive.retry-after", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; @@ -84,9 +94,13 @@ plugin_config *s; s = calloc(1, sizeof(plugin_config)); - s->max_conns = 0; + s->max_conns = 0; + s->http_status_code = 503; + s->retry_after = 0; cv[0].destination = &(s->max_conns); + cv[1].destination = &(s->http_status_code); + cv[2].destination = &(s->retry_after); p->config_storage[i] = s; @@ -105,6 +119,8 @@ plugin_config *s = p->config_storage[0]; PATCH(max_conns); + PATCH(http_status_code); + PATCH(retry_after); /* skip the first, the global context */ for (i = 1; i < srv->config_context->used; i++) { @@ -118,6 +136,10 @@ if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.max-conns-per-ip"))) { PATCH(max_conns); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.http-status-code"))) { + PATCH(http_status_code); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("evasive.retry-after"))) { + PATCH(retry_after); } } } @@ -153,7 +175,10 @@ inet_ntop_cache_get_ip(srv, &(con->dst_addr)), "turned away. Too many connections."); - con->http_status = 403; + buffer_copy_long(p->evasive_rftmp, p->conf.retry_after); + + con->http_status = p->conf.http_status_code; + response_header_overwrite(srv, con, CONST_STR_LEN("Retry-After"), CONST_BUF_LEN(p->evasive_rftmp)); return HANDLER_FINISHED; } }