From 2a968febb423d9c79df9df52d0afca44c9b5445a Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Wed, 3 Dec 2008 23:36:45 +0300 Subject: [PATCH 1/3] Implement support ETag headers (apache-style): add to r->headers_out: etag, etag_size, etag_time, etag_uniq Implement support If-Match header Cc: catap@catap.ru --- src/http/modules/ngx_http_empty_gif_module.c | 9 ++++ src/http/modules/ngx_http_flv_module.c | 4 ++ src/http/modules/ngx_http_gzip_static_module.c | 4 ++ .../modules/ngx_http_not_modified_filter_module.c | 33 ++++++++++++- src/http/modules/ngx_http_range_filter_module.c | 35 ++++++++++++-- src/http/modules/ngx_http_ssi_filter_module.c | 1 + src/http/modules/ngx_http_static_module.c | 4 ++ src/http/modules/ngx_http_sub_filter_module.c | 1 + src/http/modules/ngx_http_xslt_filter_module.c | 1 + src/http/ngx_http_core_module.c | 1 + src/http/ngx_http_core_module.h | 10 ++++ src/http/ngx_http_header_filter_module.c | 38 +++++++++++++++ src/http/ngx_http_request.c | 7 +++ src/http/ngx_http_request.h | 5 ++ src/http/ngx_http_special_response.c | 2 + src/http/ngx_http_variables.c | 49 ++++++++++++++++++++ 16 files changed, 198 insertions(+), 6 deletions(-) diff --git a/src/http/modules/ngx_http_empty_gif_module.c b/src/http/modules/ngx_http_empty_gif_module.c index 8450cae71e3e50cef5651f1d443d96bd9ff1e270..cbe64a88ecf23a8aec1e2c489c06e466e31a2804 100644 --- a/src/http/modules/ngx_http_empty_gif_module.c +++ b/src/http/modules/ngx_http_empty_gif_module.c @@ -130,6 +130,11 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r) r->headers_out.content_length_n = sizeof(ngx_empty_gif); r->headers_out.last_modified_time = 23349600; + r->headers_out.etag_size = 40; + r->headers_out.etag_time = 5; + r->headers_out.etag_uniq = 6535; + + return ngx_http_send_header(r); } @@ -150,6 +155,10 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r) r->headers_out.content_length_n = sizeof(ngx_empty_gif); r->headers_out.last_modified_time = 23349600; + r->headers_out.etag_size = 40; + r->headers_out.etag_time = 5; + r->headers_out.etag_uniq = 6535; + rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c index 3cc7d81768be86b0582e3e8ec0398062eb81d274..8e72e9e72365d7ade1b5e22a962266c61881fe41 100644 --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -197,6 +197,10 @@ ngx_http_flv_handler(ngx_http_request_t *r) r->headers_out.content_length_n = len; r->headers_out.last_modified_time = of.mtime; + r->headers_out.etag_size = of.size; + r->headers_out.etag_time = of.mtime; + r->headers_out.etag_uniq = of.uniq; + if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c index affb766ac74617a1d18e2657887d554747505e45..cf89b367c8ee6b04418373510d9fc67d9794fe18 100644 --- a/src/http/modules/ngx_http_gzip_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -190,6 +190,10 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r) r->headers_out.content_length_n = of.size; r->headers_out.last_modified_time = of.mtime; + r->headers_out.etag_size = of.size; + r->headers_out.etag_time = of.mtime; + r->headers_out.etag_uniq = of.uniq; + if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } 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 389a3a93a4ee54e3a0bceadcf165bc352697b225..fd57128fc6d75b6084a437d046f16b384976226f 100644 --- a/src/http/modules/ngx_http_not_modified_filter_module.c +++ b/src/http/modules/ngx_http_not_modified_filter_module.c @@ -50,17 +50,44 @@ 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) { + u_char *p, *etag; time_t ims; ngx_http_core_loc_conf_t *clcf; if (r->headers_out.status != NGX_HTTP_OK || r != r->main - || r->headers_in.if_modified_since == NULL - || r->headers_out.last_modified_time == -1) + || ((r->headers_in.if_modified_since == NULL + || r->headers_out.last_modified_time == -1) + && (r->headers_in.if_match == NULL + || r->headers_out.etag_size == -1 + || r->headers_out.etag_time == -1 + || r->headers_out.etag_uniq == (ngx_file_uniq_t) -1))) { return ngx_http_next_header_filter(r); } + if (r->headers_in.if_match) { + etag = ngx_palloc(r->pool, NGX_OFF_T_LEN + sizeof("_") - 1 + + NGX_TIME_T_LEN + sizeof("_") - 1 + NGX_INT_T_LEN); + + if (etag == NULL) { + return NGX_ERROR; + } + + p = ngx_sprintf(etag, "%XO-%XM-%Xd", + r->headers_out.etag_size, + r->headers_out.etag_time, + r->headers_out.etag_uniq); + + if (ngx_strncmp(r->headers_in.if_match->value.data, etag, + (ngx_uint_t)(etag - p) > r->headers_in.if_match->value.len ? + (ngx_uint_t)(etag - p) : r->headers_in.if_match->value.len)) { + return ngx_http_next_header_filter(r); + } + + goto not_modified; + } + ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data, r->headers_in.if_modified_since->value.len); @@ -78,6 +105,8 @@ ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r) } } + not_modified: + r->headers_out.status = NGX_HTTP_NOT_MODIFIED; r->headers_out.content_type.len = 0; ngx_http_clear_content_length(r); diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c index 4a15637f589783e8a6694f407aa4c222e45bcfce..711f1ebc7da8885c16694586429fa1f2feec555e 100644 --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -146,6 +146,7 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) { time_t if_range; + u_char *p, *etag; ngx_int_t rc; ngx_http_range_filter_ctx_t *ctx; @@ -172,13 +173,39 @@ ngx_http_range_header_filter(ngx_http_request_t *r) if_range = ngx_http_parse_time(r->headers_in.if_range->value.data, r->headers_in.if_range->value.len); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http ir:%d lm:%d", - if_range, r->headers_out.last_modified_time); + if (if_range != NGX_ERROR) { + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http ir:%d lm:%d", + if_range, r->headers_out.last_modified_time); + + if (if_range != r->headers_out.last_modified_time) { + goto next_filter; + } + } + } - if (if_range != r->headers_out.last_modified_time) { + if (r->headers_in.if_range && r->headers_out.etag_size != -1 + && r->headers_out.etag_time != -1 + && r->headers_out.etag_uniq != (ngx_file_uniq_t) -1) { + etag = ngx_palloc(r->pool, NGX_OFF_T_LEN + sizeof("_") - 1 + + NGX_TIME_T_LEN + sizeof("_") - 1 + NGX_INT_T_LEN); + + if (etag == NULL) { + return NGX_ERROR; + } + + p = ngx_sprintf(etag, "%XO-%XM-%Xd", + r->headers_out.etag_size, + r->headers_out.etag_time, + r->headers_out.etag_uniq); + + if (ngx_strncmp(r->headers_in.if_match->value.data, etag, + (ngx_uint_t)(etag - p) > r->headers_in.if_match->value.len ? + (ngx_uint_t)(etag - p) : r->headers_in.if_match->value.len)) { goto next_filter; } + } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t)); diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c index 04ab042003f8028b033d35b709f803b3c4fd6c92..40f3931910b06b99d020e0b477ee7edeb4b2dafb 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -360,6 +360,7 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r) if (r == r->main) { ngx_http_clear_content_length(r); ngx_http_clear_last_modified(r); + ngx_http_clear_etag(r); } return ngx_http_next_header_filter(r); diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c index 9ff1f817f875e2b207fdb9e355ab1f7186b31f69..1131bd4e5231518ea34be6f913a2a37fe112abcb 100644 --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -213,6 +213,10 @@ ngx_http_static_handler(ngx_http_request_t *r) r->headers_out.content_length_n = of.size; r->headers_out.last_modified_time = of.mtime; + r->headers_out.etag_size = of.size; + r->headers_out.etag_time = of.mtime; + r->headers_out.etag_uniq = of.uniq; + if (ngx_http_set_content_type(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c index f40a3c654a01d42f810255f9079f294d4fe1f51f..2cdccdeb9f6ba4104e2b8b094a7e3e942b592dda 100644 --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -161,6 +161,7 @@ ngx_http_sub_header_filter(ngx_http_request_t *r) if (r == r->main) { ngx_http_clear_content_length(r); ngx_http_clear_last_modified(r); + ngx_http_clear_etag(r); } return ngx_http_next_header_filter(r); diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c index f65ab4208236f21454c0a07d63a3af4bd35eaa9e..d8721a4dc705209067d9604dd3f04bfabcd092fb 100644 --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -346,6 +346,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, } ngx_http_clear_last_modified(r); + ngx_http_clear_etag_modified(r); } rc = ngx_http_next_header_filter(r); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index b4bd40a93f7ce38a4a81e38741fd33146a5005ef..602b4722bdef4992ba451b06281270a0f772d7c1 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1878,6 +1878,7 @@ ngx_http_subrequest(ngx_http_request_t *r, ngx_http_clear_content_length(sr); ngx_http_clear_accept_ranges(sr); ngx_http_clear_last_modified(sr); + ngx_http_clear_etag(sr); sr->request_body = r->request_body; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 032d07a6be78da05fba1a972a7760f53acdc7914..801efaa5c077bd28da6028c7198c36fad8ac46f0 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -451,5 +451,15 @@ extern ngx_uint_t ngx_http_max_module; r->headers_out.last_modified = NULL; \ } +#define ngx_http_clear_etag(r) \ + \ + r->headers_out.etag_size = -1; \ + r->headers_out.etag_time = -1; \ + r->headers_out.etag_uniq = (ngx_file_uniq_t) -1; \ + if (r->headers_out.etag) { \ + r->headers_out.etag->hash = 0; \ + r->headers_out.etag = NULL; \ + } + #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */ diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c index de953339115a917e5fa32294960ba3059882f2f9..b7b1c6185dbf3918fb790f73793668d6f2ddc722 100644 --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -188,6 +188,20 @@ ngx_http_header_filter(ngx_http_request_t *r) } } + if (r->headers_out.etag_size != -1 || + r->headers_out.etag_time != -1 || + r->headers_out.etag_uniq != (ngx_file_uniq_t) -1) { + if (r->headers_out.status != NGX_HTTP_OK + && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT + && r->headers_out.status != NGX_HTTP_NOT_MODIFIED) + { + r->headers_out.etag_size = -1; + r->headers_out.etag_time = -1; + r->headers_out.etag_uniq = (ngx_file_uniq_t) -1; + r->headers_out.etag = NULL; + } + } + len = sizeof("HTTP/1.x ") - 1 + sizeof(CRLF) - 1 /* the end of the header */ + sizeof(CRLF) - 1; @@ -214,6 +228,10 @@ ngx_http_header_filter(ngx_http_request_t *r) r->headers_out.last_modified = NULL; r->headers_out.content_length = NULL; r->headers_out.content_length_n = -1; + r->headers_out.etag_size = 1; + r->headers_out.etag_time = 1; + r->headers_out.etag_uniq = 1; + r->headers_out.etag = NULL; } } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { @@ -276,6 +294,15 @@ ngx_http_header_filter(ngx_http_request_t *r) len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; } + if (r->headers_out.etag == NULL + && r->headers_out.etag_size != -1 + && r->headers_out.etag_time != -1 + && r->headers_out.etag_uniq != (ngx_file_uniq_t) -1) + { + len += sizeof("ETag: ") - 1 + NGX_OFF_T_LEN + sizeof("_") - 1 + + NGX_TIME_T_LEN + sizeof("_") - 1 + NGX_INT_T_LEN + sizeof(CRLF) - 1; + } + if (r->headers_out.location && r->headers_out.location->value.len && r->headers_out.location->value.data[0] == '/') @@ -457,6 +484,17 @@ ngx_http_header_filter(ngx_http_request_t *r) *b->last++ = CR; *b->last++ = LF; } + if (r->headers_out.etag == NULL + && r->headers_out.etag_size != -1 + && r->headers_out.etag_time != -1 + && r->headers_out.etag_uniq != (ngx_file_uniq_t) -1) + { + b->last = ngx_sprintf(b->last, "ETag: %XO-%XM-%Xd" CRLF, + r->headers_out.etag_size, + r->headers_out.etag_time, + r->headers_out.etag_uniq); + } + if (host.data) { p = b->last + sizeof("Location: ") - 1; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index ab4c0e08fa3cf3e712c7a5d2cd4ead1bf31bfe4a..43021dcb95bfda60661dd9c3245659134f2465d0 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -83,6 +83,10 @@ ngx_http_header_t ngx_http_headers_in[] = { offsetof(ngx_http_headers_in_t, if_modified_since), ngx_http_process_unique_header_line }, + { ngx_string("If-Match"), + offsetof(ngx_http_headers_in_t, if_match), + ngx_http_process_unique_header_line }, + { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), ngx_http_process_user_agent }, @@ -450,6 +454,9 @@ ngx_http_init_request(ngx_event_t *rev) r->headers_in.keep_alive_n = -1; r->headers_out.content_length_n = -1; r->headers_out.last_modified_time = -1; + r->headers_out.etag_size = -1; + r->headers_out.etag_time = -1; + r->headers_out.etag_uniq = (ngx_file_uniq_t) -1; r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index f0e0eade18568c6082a67e3b393028f0ad054955..bae17ba0ff70ede49d0c457659795ff138db82c6 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -162,6 +162,7 @@ typedef struct { ngx_table_elt_t *host; ngx_table_elt_t *connection; ngx_table_elt_t *if_modified_since; + ngx_table_elt_t *if_match; ngx_table_elt_t *user_agent; ngx_table_elt_t *referer; ngx_table_elt_t *content_length; @@ -253,6 +254,10 @@ typedef struct { off_t content_length_n; time_t date_time; time_t last_modified_time; + + off_t etag_size; + time_t etag_time; + ngx_file_uniq_t etag_uniq; } ngx_http_headers_out_t; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 84932683917221c7147fdafb7b4ab417f257c4ac..025b4fb140acea2fa297d28e1f7bd39ae60a352a 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -585,6 +585,7 @@ ngx_http_send_special_response(ngx_http_request_t *r, ngx_http_clear_accept_ranges(r); ngx_http_clear_last_modified(r); + ngx_http_clear_etag(r); rc = ngx_http_send_header(r); @@ -683,6 +684,7 @@ ngx_http_send_refresh(ngx_http_request_t *r) ngx_http_clear_accept_ranges(r); ngx_http_clear_last_modified(r); + ngx_http_clear_etag(r); rc = ngx_http_send_header(r); diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c index 998c4ce35a87dc9860f06efb5048b723cc8f4f52..41fedcaa8a5770614a17fd7ac2075ad7c7d9c949 100644 --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -71,6 +71,8 @@ static ngx_int_t ngx_http_variable_sent_content_length(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_sent_last_modified(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_sent_etag(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_sent_keep_alive(ngx_http_request_t *r, @@ -213,6 +215,9 @@ static ngx_http_variable_t ngx_http_core_variables[] = { { ngx_string("sent_http_last_modified"), NULL, ngx_http_variable_sent_last_modified, 0, 0, 0 }, + { ngx_string("sent_http_etag"), NULL, + ngx_http_variable_sent_etag, 0, 0, 0 }, + { ngx_string("sent_http_connection"), NULL, ngx_http_variable_sent_connection, 0, 0, 0 }, @@ -1308,6 +1313,50 @@ ngx_http_variable_sent_last_modified(ngx_http_request_t *r, static ngx_int_t +ngx_http_variable_sent_etag(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + if (r->headers_out.etag) { + v->len = r->headers_out.etag->value.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = r->headers_out.etag->value.data; + + return NGX_OK; + } + + if (r->headers_out.etag_size >= 0 && + r->headers_out.etag_time >= 0 && + (ngx_int_t)r->headers_out.etag_uniq >= 0) { + p = ngx_pnalloc(r->pool, + sizeof("ETag: ") - 1 + NGX_OFF_T_LEN + sizeof("_") - 1 + + NGX_TIME_T_LEN + sizeof("_") - 1 + NGX_INT_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "ETag: %XO-%XM-%Xd", + r->headers_out.etag_size, + r->headers_out.etag_time, + r->headers_out.etag_uniq) - p; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; + } + + v->not_found = 1; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { -- 1.5.6.5 From 84f733af4b6cef8764b1cabec72076afd69a2ffb Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Sun, 22 Feb 2009 01:55:45 +0300 Subject: [PATCH 2/3] Fix a typo :( Cc: catap@catap.ru --- src/http/modules/ngx_http_xslt_filter_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c index d8721a4dc705209067d9604dd3f04bfabcd092fb..fae78393e57635f0152718fb437fd70fb0731da6 100644 --- a/src/http/modules/ngx_http_xslt_filter_module.c +++ b/src/http/modules/ngx_http_xslt_filter_module.c @@ -346,7 +346,7 @@ ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, } ngx_http_clear_last_modified(r); - ngx_http_clear_etag_modified(r); + ngx_http_clear_etag(r); } rc = ngx_http_next_header_filter(r); -- 1.5.6.5 From b76b16528843d266f08fd9a16dc280eba0b01190 Mon Sep 17 00:00:00 2001 From: Kirill A. Korinskiy Date: Tue, 3 Mar 2009 18:24:20 +0300 Subject: [PATCH 3/3] Fix Segmentation fault Cc: catap@catap.ru If client request If-range and do not send If-match header nginx can get segmentation fault --- src/http/modules/ngx_http_range_filter_module.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c index e33494fc8d9ace24abcf38fc33c7b24f5a65cd10..11613f6667ddbe87b540963a3abbec2db154de8b 100644 --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -201,8 +201,8 @@ ngx_http_range_header_filter(ngx_http_request_t *r) r->headers_out.etag_uniq); if (ngx_strncmp(r->headers_in.if_match->value.data, etag, - (ngx_uint_t)(etag - p) > r->headers_in.if_match->value.len ? - (ngx_uint_t)(etag - p) : r->headers_in.if_match->value.len)) { + (ngx_uint_t)(etag - p) > r->headers_in.if_range->value.len ? + (ngx_uint_t)(etag - p) : r->headers_in.if_range->value.len)) { goto next_filter; } -- 1.5.6.5