|
25 | 25 | #include <ngx_http.h>
|
26 | 26 |
|
27 | 27 | static ngx_int_t ngx_http_modsecurity_init(ngx_conf_t *cf);
|
| 28 | +static ngx_int_t ngx_http_modsecurity_add_variables(ngx_conf_t *cf); |
28 | 29 | static void *ngx_http_modsecurity_create_main_conf(ngx_conf_t *cf);
|
29 | 30 | static char *ngx_http_modsecurity_init_main_conf(ngx_conf_t *cf, void *conf);
|
30 | 31 | static void *ngx_http_modsecurity_create_conf(ngx_conf_t *cf);
|
31 | 32 | static char *ngx_http_modsecurity_merge_conf(ngx_conf_t *cf, void *parent, void *child);
|
32 | 33 | static void ngx_http_modsecurity_cleanup_instance(void *data);
|
33 | 34 | static void ngx_http_modsecurity_cleanup_rules(void *data);
|
34 | 35 |
|
| 36 | +static ngx_int_t ngx_http_modsecurity_req_headers_phase_time(ngx_http_request_t *r, |
| 37 | + ngx_http_variable_value_t *v, uintptr_t data); |
| 38 | +static ngx_int_t ngx_http_modsecurity_req_body_phase_time(ngx_http_request_t *r, |
| 39 | + ngx_http_variable_value_t *v, uintptr_t data); |
| 40 | +static ngx_int_t ngx_http_modsecurity_resp_headers_phase_time(ngx_http_request_t *r, |
| 41 | + ngx_http_variable_value_t *v, uintptr_t data); |
| 42 | +static ngx_int_t ngx_http_modsecurity_resp_body_phase_time(ngx_http_request_t *r, |
| 43 | + ngx_http_variable_value_t *v, uintptr_t data); |
| 44 | +static ngx_int_t ngx_http_modsecurity_time_variable(ngx_http_request_t *r, |
| 45 | + ngx_http_variable_value_t *v, uintptr_t data, ngx_msec_int_t usec); |
35 | 46 |
|
36 | 47 | /*
|
37 | 48 | * PCRE malloc/free workaround, based on
|
@@ -268,6 +279,11 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r)
|
268 | 279 | return NULL;
|
269 | 280 | }
|
270 | 281 |
|
| 282 | + ctx->req_headers_phase_time = -1; |
| 283 | + ctx->req_body_phase_time = -1; |
| 284 | + ctx->resp_headers_phase_time = -1; |
| 285 | + ctx->resp_body_phase_time = -1; |
| 286 | + |
271 | 287 | mmcf = ngx_http_get_module_main_conf(r, ngx_http_modsecurity_module);
|
272 | 288 | mcf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity_module);
|
273 | 289 |
|
@@ -490,7 +506,7 @@ static ngx_command_t ngx_http_modsecurity_commands[] = {
|
490 | 506 |
|
491 | 507 |
|
492 | 508 | static ngx_http_module_t ngx_http_modsecurity_ctx = {
|
493 |
| - NULL, /* preconfiguration */ |
| 509 | + ngx_http_modsecurity_add_variables, /* preconfiguration */ |
494 | 510 | ngx_http_modsecurity_init, /* postconfiguration */
|
495 | 511 |
|
496 | 512 | ngx_http_modsecurity_create_main_conf, /* create main configuration */
|
@@ -520,6 +536,27 @@ ngx_module_t ngx_http_modsecurity_module = {
|
520 | 536 | };
|
521 | 537 |
|
522 | 538 |
|
| 539 | +static ngx_http_variable_t ngx_http_modsecurity_vars[] = { |
| 540 | + { ngx_string("modsecurity_req_headers_phase_time"), NULL, |
| 541 | + ngx_http_modsecurity_req_headers_phase_time, 0, |
| 542 | + NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
| 543 | + |
| 544 | + { ngx_string("modsecurity_req_body_phase_time"), NULL, |
| 545 | + ngx_http_modsecurity_req_body_phase_time, 0, |
| 546 | + NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
| 547 | + |
| 548 | + { ngx_string("modsecurity_resp_headers_phase_time"), NULL, |
| 549 | + ngx_http_modsecurity_resp_headers_phase_time, 0, |
| 550 | + NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
| 551 | + |
| 552 | + { ngx_string("modsecurity_resp_body_phase_time"), NULL, |
| 553 | + ngx_http_modsecurity_resp_body_phase_time, 0, |
| 554 | + NGX_HTTP_VAR_NOCACHEABLE, 0 }, |
| 555 | + |
| 556 | + ngx_http_null_variable |
| 557 | +}; |
| 558 | + |
| 559 | + |
523 | 560 | static ngx_int_t
|
524 | 561 | ngx_http_modsecurity_init(ngx_conf_t *cf)
|
525 | 562 | {
|
@@ -596,6 +633,23 @@ ngx_http_modsecurity_init(ngx_conf_t *cf)
|
596 | 633 | return NGX_OK;
|
597 | 634 | }
|
598 | 635 |
|
| 636 | +static ngx_int_t |
| 637 | +ngx_http_modsecurity_add_variables(ngx_conf_t *cf) { |
| 638 | + ngx_http_variable_t *var, *v; |
| 639 | + |
| 640 | + for (v = ngx_http_modsecurity_vars; v->name.len; v++) { |
| 641 | + var = ngx_http_add_variable(cf, &v->name, v->flags); |
| 642 | + if (var == NULL) { |
| 643 | + return NGX_ERROR; |
| 644 | + } |
| 645 | + |
| 646 | + var->get_handler = v->get_handler; |
| 647 | + var->data = v->data; |
| 648 | + } |
| 649 | + |
| 650 | + return NGX_OK; |
| 651 | +}; |
| 652 | + |
599 | 653 |
|
600 | 654 | static void *
|
601 | 655 | ngx_http_modsecurity_create_main_conf(ngx_conf_t *cf)
|
@@ -788,4 +842,92 @@ ngx_http_modsecurity_cleanup_rules(void *data)
|
788 | 842 | }
|
789 | 843 |
|
790 | 844 |
|
| 845 | +static ngx_int_t |
| 846 | +ngx_http_modsecurity_req_headers_phase_time(ngx_http_request_t *r, |
| 847 | + ngx_http_variable_value_t *v, uintptr_t data) |
| 848 | +{ |
| 849 | + ngx_http_modsecurity_ctx_t *ctx; |
| 850 | + |
| 851 | + ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module); |
| 852 | + if (ctx == NULL) { |
| 853 | + return NGX_ERROR; |
| 854 | + } |
| 855 | + return ngx_http_modsecurity_time_variable(r, v, data, ctx->req_headers_phase_time); |
| 856 | +} |
| 857 | + |
| 858 | + |
| 859 | +static ngx_int_t |
| 860 | +ngx_http_modsecurity_req_body_phase_time(ngx_http_request_t *r, |
| 861 | + ngx_http_variable_value_t *v, uintptr_t data) |
| 862 | +{ |
| 863 | + ngx_http_modsecurity_ctx_t *ctx; |
| 864 | + |
| 865 | + ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module); |
| 866 | + if (ctx == NULL) { |
| 867 | + return NGX_ERROR; |
| 868 | + } |
| 869 | + return ngx_http_modsecurity_time_variable(r, v, data, ctx->req_body_phase_time); |
| 870 | +} |
| 871 | + |
| 872 | + |
| 873 | +static ngx_int_t |
| 874 | +ngx_http_modsecurity_resp_headers_phase_time(ngx_http_request_t *r, |
| 875 | + ngx_http_variable_value_t *v, uintptr_t data) |
| 876 | +{ |
| 877 | + ngx_http_modsecurity_ctx_t *ctx; |
| 878 | + |
| 879 | + ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module); |
| 880 | + if (ctx == NULL) { |
| 881 | + return NGX_ERROR; |
| 882 | + } |
| 883 | + return ngx_http_modsecurity_time_variable(r, v, data, ctx->resp_headers_phase_time); |
| 884 | +} |
| 885 | + |
| 886 | + |
| 887 | +static ngx_int_t |
| 888 | +ngx_http_modsecurity_resp_body_phase_time(ngx_http_request_t *r, |
| 889 | + ngx_http_variable_value_t *v, uintptr_t data) |
| 890 | +{ |
| 891 | + ngx_http_modsecurity_ctx_t *ctx; |
| 892 | + |
| 893 | + ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity_module); |
| 894 | + if (ctx == NULL) { |
| 895 | + return NGX_ERROR; |
| 896 | + } |
| 897 | + return ngx_http_modsecurity_time_variable(r, v, data, ctx->resp_body_phase_time); |
| 898 | +} |
| 899 | + |
| 900 | +static ngx_int_t |
| 901 | +ngx_http_modsecurity_time_variable(ngx_http_request_t *r, |
| 902 | + ngx_http_variable_value_t *v, uintptr_t data, ngx_msec_int_t usec) |
| 903 | +{ |
| 904 | + u_char *p; |
| 905 | + |
| 906 | + p = ngx_pnalloc(r->pool, NGX_TIME_T_LEN + 7); |
| 907 | + if (p == NULL) { |
| 908 | + return NGX_ERROR; |
| 909 | + } |
| 910 | + |
| 911 | + if(usec == -1) { |
| 912 | + v->len = ngx_sprintf(p, "-") - p; |
| 913 | + } else { |
| 914 | + v->len = ngx_sprintf(p, "%T.%06M", (time_t) usec / 1000000, usec % 1000000) - p; |
| 915 | + } |
| 916 | + |
| 917 | + v->valid = 1; |
| 918 | + v->no_cacheable = 0; |
| 919 | + v->not_found = 0; |
| 920 | + v->data = p; |
| 921 | + |
| 922 | + return NGX_OK; |
| 923 | +} |
| 924 | + |
| 925 | + |
| 926 | +ngx_msec_int_t |
| 927 | +ngx_http_modsecurity_compute_processing_time(struct timeval tv) { |
| 928 | + struct timeval current_tv; |
| 929 | + ngx_gettimeofday(¤t_tv); |
| 930 | + return (ngx_msec_int_t) ((current_tv.tv_sec - tv.tv_sec) * 1000000 + (current_tv.tv_usec - tv.tv_usec)); |
| 931 | +}; |
| 932 | + |
791 | 933 | /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|
0 commit comments