nginx refactoring

Refactoring on the nginx module, including:
 - Better handling larger posts;
 - Now using nginx echo module during the regression tests.
 - Better interacting with neginx chain rules
 - Separation of the request handling and content filters.
 - Better handling nginx sessions and resource counts to allow a
   more efficient garbage collector.
 - Handling both http/1.0 and 1.1, including keep-alive.
 - Tests are now capable to test nginx as a proxy or end-server.
 - Tested agains nginx 1.6 and 1.7.
This commit is contained in:
Felipe Zimmerle
2014-04-28 06:28:11 -07:00
parent fda20322fb
commit a3433c3d17

View File

@@ -21,6 +21,7 @@
/* Those are defined twice, lets keep it defined just once by `undef` /* Those are defined twice, lets keep it defined just once by `undef`
* the first one. * the first one.
*/ */
*/
#undef CR #undef CR
#undef LF #undef LF
#undef CRLF #undef CRLF
@@ -228,7 +229,6 @@ ngx_pstrdup0(ngx_pool_t *pool, ngx_str_t *src)
return dst; return dst;
} }
/* /*
* MultiplyDeBruijnBitPosition * MultiplyDeBruijnBitPosition
* http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
@@ -563,6 +563,10 @@ ngx_http_modsecurity_load_request_body(ngx_http_request_t *r)
ngx_http_modsecurity_ctx_t *ctx; ngx_http_modsecurity_ctx_t *ctx;
ngx_chain_t *chain; ngx_chain_t *chain;
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: loading request body.");
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: loading request body."); "ModSec: loading request body.");
@@ -598,7 +602,6 @@ ngx_http_modsecurity_load_request_body(ngx_http_request_t *r)
return NGX_OK; return NGX_OK;
} }
static ngx_inline ngx_int_t static ngx_inline ngx_int_t
ngx_http_modsecurity_save_request_body(ngx_http_request_t *r) ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
{ {
@@ -607,7 +610,6 @@ ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
apr_off_t content_length; apr_off_t content_length;
ngx_buf_t *buf; ngx_buf_t *buf;
#endif #endif
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity); ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
#ifdef MOVE_REQUEST_CHAIN_TO_MODSEC #ifdef MOVE_REQUEST_CHAIN_TO_MODSEC
@@ -619,10 +621,8 @@ ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
apr_brigade_cleanup(ctx->brigade); apr_brigade_cleanup(ctx->brigade);
buf->last += content_length; buf->last += content_length;
r->header_in = buf; r->header_in = buf;
if (r->headers_in.content_length) { if (r->headers_in.content_length) {
ngx_str_t *str = NULL; ngx_str_t *str = NULL;
str = &r->headers_in.content_length->value; str = &r->headers_in.content_length->value;
str->data = ngx_palloc(r->pool, NGX_OFF_T_LEN); str->data = ngx_palloc(r->pool, NGX_OFF_T_LEN);
if (str->data == NULL) { if (str->data == NULL) {
@@ -631,11 +631,7 @@ ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
} }
str->len = ngx_snprintf(str->data, NGX_OFF_T_LEN, "%O", str->len = ngx_snprintf(str->data, NGX_OFF_T_LEN, "%O",
content_length) - str->data; content_length) - str->data;
}
r->headers_in.content_length_n = content_length; r->headers_in.content_length_n = content_length;
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: Content length: %O, Content length n: %O", content_length, "ModSec: Content length: %O, Content length n: %O", content_length,
r->headers_in.content_length_n); r->headers_in.content_length_n);
@@ -643,6 +639,9 @@ ngx_http_modsecurity_save_request_body(ngx_http_request_t *r)
apr_brigade_cleanup(ctx->brigade); apr_brigade_cleanup(ctx->brigade);
#endif #endif
r->headers_in.content_length_n = content_length;
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSec: Content length: %O, Content length n: %O", content_length, r->headers_in.content_length_n);
return NGX_OK; return NGX_OK;
} }
@@ -1151,19 +1150,25 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: ModSecurity is not enabled or not a main request."); "ModSec: ModSecurity is not enabled or not a main request.");
ctx = ngx_http_modsecurity_create_ctx(r);
return NGX_DECLINED; return NGX_DECLINED;
if (ngx_http_set_pool_ctx(r, ctx, ngx_http_modsecurity) != NGX_OK) {
return NGX_ERROR;
} }
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity); ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: Recovering ctx: %p", ctx); "ModSec: Recovering ctx: %p", ctx);
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: ctx is null, nothing we can do, returning.");
if (ctx == NULL) { if (ctx == NULL) {
ctx = ngx_http_modsecurity_create_ctx(r); ctx = ngx_http_modsecurity_create_ctx(r);
ngx_http_set_ctx(r, ctx, ngx_http_modsecurity); ngx_http_set_ctx(r, ctx, ngx_http_modsecurity);
"ModSec: ctx is now: %p / count: %d", ctx, r->main->count);
if (ngx_http_set_pool_ctx(r, ctx, ngx_http_modsecurity) != NGX_OK) { if (ngx_http_set_pool_ctx(r, ctx, ngx_http_modsecurity) != NGX_OK) {
return NGX_ERROR; return NGX_ERROR;
} }
@@ -1181,12 +1186,9 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: ctx is now: %p / count: %d", ctx, r->main->count); "ModSec: ctx is now: %p / count: %d", ctx, r->main->count);
if (modsecContextState(ctx->req) == MODSEC_DISABLED) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: ModSecurity was disabled, returning....", ctx); "ModSec: ModSecurity was disabled, returning....", ctx);
return NGX_DECLINED;
}
if (ctx->waiting_more_body == 1) { if (ctx->waiting_more_body == 1) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: waiting for more data before proceed. / count: %d", "ModSec: waiting for more data before proceed. / count: %d",
@@ -1194,6 +1196,7 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) {
return NGX_DONE; return NGX_DONE;
} }
ngx_http_modsecurity_request_read);
if (ctx->body_requested == 0) { if (ctx->body_requested == 0) {
ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1218,12 +1221,16 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) {
} }
if (ctx->waiting_more_body == 0 && ctx->request_processed == 0) { if (ctx->waiting_more_body == 0 && ctx->request_processed == 0) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: request is ready to be processed.");
ngx_http_modsecurity_process_request(r);
ctx->request_processed = 1;
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: request is ready to be processed."); "ModSec: request is ready to be processed.");
rc = ngx_http_modsecurity_process_request(r); rc = ngx_http_modsecurity_process_request(r);
ctx->request_processed = 1; ctx->request_processed = 1;
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: returning a special response after process " \ "ModSec: returning a special response after process " \
@@ -1232,8 +1239,10 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) {
return rc; return rc;
} }
void
ngx_http_modsecurity_request_read(ngx_http_request_t *r)
{
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ModSec: returning NGX_DECLINED." ); "ModSec: returning NGX_DECLINED." );
@@ -1435,7 +1444,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
} }
return ngx_http_next_body_filter(r, out); return ngx_http_next_body_filter(r, out);
#endif
return NGX_OK; return NGX_OK;
} }
#endif #endif