diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c index 032ba96fd..8cddecc25 100644 --- a/src/http/modules/ngx_http_not_modified_filter_module.c +++ b/src/http/modules/ngx_http_not_modified_filter_module.c @@ -54,6 +54,8 @@ static ngx_http_output_header_filter_pt ngx_http_next_header_filter; static ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r) { + ngx_http_core_loc_conf_t *clcf; + if (r->headers_out.status != NGX_HTTP_OK || r != r->main || r->disable_not_modified) @@ -77,19 +79,58 @@ ngx_http_not_modified_header_filter(ngx_http_request_t *r) if (r->headers_in.if_modified_since || r->headers_in.if_none_match) { - if (r->headers_in.if_modified_since - && ngx_http_test_if_modified(r)) - { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->not_modified_check == NGX_HTTP_NMC_STRICT) { + if (r->headers_in.if_modified_since + && ngx_http_test_if_modified(r)) + { + return ngx_http_next_header_filter(r); + } + + if (r->headers_in.if_none_match + && !ngx_http_test_if_match(r, r->headers_in.if_none_match, 1)) + { + return ngx_http_next_header_filter(r); + } + + } else if (clcf->not_modified_check == NGX_HTTP_NMC_PREFER_INM) { + if (r->headers_in.if_none_match) { + if (ngx_http_test_if_match(r, r->headers_in.if_none_match, 1)) + { + goto not_modified; + } + + return ngx_http_next_header_filter(r); + } + + if (r->headers_in.if_modified_since + && ngx_http_test_if_modified(r)) + { + return ngx_http_next_header_filter(r); + } + + } else if (clcf->not_modified_check == NGX_HTTP_NMC_ANY) { + + if (r->headers_in.if_modified_since + && !ngx_http_test_if_modified(r)) + { + goto not_modified; + } + + if (r->headers_in.if_none_match + && ngx_http_test_if_match(r, r->headers_in.if_none_match, 1)) + { + goto not_modified; + } + + return ngx_http_next_header_filter(r); + + } else { /* NGX_HTTP_NMC_OFF */ return ngx_http_next_header_filter(r); } - if (r->headers_in.if_none_match - && !ngx_http_test_if_match(r, r->headers_in.if_none_match, 1)) - { - return ngx_http_next_header_filter(r); - } - - /* not modified */ +not_modified: r->headers_out.status = NGX_HTTP_NOT_MODIFIED; r->headers_out.status_line.len = 0; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 92c3eae8a..f94f24775 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -129,6 +129,15 @@ static ngx_conf_enum_t ngx_http_core_server_tokens[] = { }; +static ngx_conf_enum_t ngx_http_core_not_modified_check[] = { + { ngx_string("off"), NGX_HTTP_NMC_OFF }, + { ngx_string("any"), NGX_HTTP_NMC_ANY }, + { ngx_string("strict"), NGX_HTTP_NMC_STRICT }, + { ngx_string("prefer_if_none_match"), NGX_HTTP_NMC_PREFER_INM }, + { ngx_null_string, 0 } +}; + + static ngx_conf_enum_t ngx_http_core_if_modified_since[] = { { ngx_string("off"), NGX_HTTP_IMS_OFF }, { ngx_string("exact"), NGX_HTTP_IMS_EXACT }, @@ -642,6 +651,13 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_loc_conf_t, server_tokens), &ngx_http_core_server_tokens }, + { ngx_string("not_modified_check"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, not_modified_check), + &ngx_http_core_not_modified_check }, + { ngx_string("if_modified_since"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_enum_slot, @@ -3592,6 +3608,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf) clcf->client_body_timeout = NGX_CONF_UNSET_MSEC; clcf->satisfy = NGX_CONF_UNSET_UINT; clcf->auth_delay = NGX_CONF_UNSET_MSEC; + clcf->not_modified_check = NGX_CONF_UNSET_UINT; clcf->if_modified_since = NGX_CONF_UNSET_UINT; clcf->max_ranges = NGX_CONF_UNSET_UINT; clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT; @@ -3812,6 +3829,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, NGX_HTTP_SATISFY_ALL); ngx_conf_merge_msec_value(conf->auth_delay, prev->auth_delay, 0); + ngx_conf_merge_uint_value(conf->not_modified_check, + prev->not_modified_check, NGX_HTTP_NMC_STRICT); ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, NGX_HTTP_IMS_EXACT); ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges, diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index e7e266bf8..7d225cc17 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -60,6 +60,12 @@ typedef struct ngx_thread_pool_s ngx_thread_pool_t; #define NGX_HTTP_SERVER_TOKENS_BUILD 2 +#define NGX_HTTP_NMC_OFF 0 +#define NGX_HTTP_NMC_ANY 1 +#define NGX_HTTP_NMC_STRICT 2 +#define NGX_HTTP_NMC_PREFER_INM 3 + + typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t; typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; @@ -384,6 +390,7 @@ struct ngx_http_core_loc_conf_s { ngx_uint_t keepalive_disable; /* keepalive_disable */ ngx_uint_t satisfy; /* satisfy */ ngx_uint_t lingering_close; /* lingering_close */ + ngx_uint_t not_modified_check; /* not_modified_check */ ngx_uint_t if_modified_since; /* if_modified_since */ ngx_uint_t max_ranges; /* max_ranges */ ngx_uint_t client_body_in_file_only; /* client_body_in_file_only */