[PATCH] append "-gzip" to etags processed by gzip_filter_module + not modified support
Andrew Williams
sobakasu at gmail.com
Wed May 28 06:56:04 UTC 2014
this patch modifies the etag header returned by responses processed by
the gzip filter, appending "-gzip" to the etag (instead of deleting
it). Also, If-None-Match and If-Match requests work against the
modified etag.
(the gunzip module appends "-gunzip" to the etag).
cheers
Andrew
# HG changeset patch
# User Andrew Williams <sobakasu at gmail.com>
# Date 1401259215 -34200
# Wed May 28 16:10:15 2014 +0930
# Node ID 102149a95d84250e709051b1f2c8b49a1872bd3e
# Parent adb742cf27f771771b293cc280f594038e8d9aab
append "-gzip" to etags processed by gzip_filter_module + not modified support
diff -r adb742cf27f7 -r 102149a95d84
src/http/modules/ngx_http_gunzip_filter_module.c
--- a/src/http/modules/ngx_http_gunzip_filter_module.c Tue May 27
17:58:09 2014 +0400
+++ b/src/http/modules/ngx_http_gunzip_filter_module.c Wed May 28
16:10:15 2014 +0930
@@ -115,6 +115,7 @@
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
+static ngx_str_t ngx_http_gunzip_etag_suffix = ngx_string("-gunzip");
static ngx_int_t
@@ -149,6 +150,13 @@
return ngx_http_next_header_filter(r);
}
+ ngx_int_t etag_filter_result;
+ ngx_http_update_etag(r, &ngx_http_gunzip_etag_suffix);
+ if (ngx_http_test_etag_if_match(r, ngx_http_next_header_filter,
+ &etag_filter_result)) {
+ return etag_filter_result;
+ }
+
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gunzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -165,7 +173,6 @@
ngx_http_clear_content_length(r);
ngx_http_clear_accept_ranges(r);
- ngx_http_clear_etag(r);
return ngx_http_next_header_filter(r);
}
diff -r adb742cf27f7 -r 102149a95d84
src/http/modules/ngx_http_gzip_filter_module.c
--- a/src/http/modules/ngx_http_gzip_filter_module.c Tue May 27
17:58:09 2014 +0400
+++ b/src/http/modules/ngx_http_gzip_filter_module.c Wed May 28
16:10:15 2014 +0930
@@ -229,6 +229,7 @@
static ngx_str_t ngx_http_gzip_ratio = ngx_string("gzip_ratio");
+static ngx_str_t ngx_http_gzip_etag_suffix = ngx_string("-gzip");
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
@@ -280,6 +281,13 @@
return ngx_http_next_header_filter(r);
}
+ ngx_int_t etag_filter_result;
+ ngx_http_update_etag(r, &ngx_http_gzip_etag_suffix);
+ if (ngx_http_test_etag_if_match(r, ngx_http_next_header_filter,
+ &etag_filter_result)) {
+ return etag_filter_result;
+ }
+
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -306,7 +314,6 @@
ngx_http_clear_content_length(r);
ngx_http_clear_accept_ranges(r);
- ngx_http_clear_etag(r);
return ngx_http_next_header_filter(r);
}
diff -r adb742cf27f7 -r 102149a95d84
src/http/modules/ngx_http_not_modified_filter_module.c
--- a/src/http/modules/ngx_http_not_modified_filter_module.c Tue May
27 17:58:09 2014 +0400
+++ b/src/http/modules/ngx_http_not_modified_filter_module.c Wed May
28 16:10:15 2014 +0930
@@ -12,8 +12,6 @@
static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r);
static ngx_uint_t ngx_http_test_if_modified(ngx_http_request_t *r);
-static ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r,
- ngx_table_elt_t *header);
static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
@@ -160,76 +158,6 @@
}
-static ngx_uint_t
-ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header)
-{
- u_char *start, *end, ch;
- ngx_str_t *etag, *list;
-
- list = &header->value;
-
- if (list->len == 1 && list->data[0] == '*') {
- return 1;
- }
-
- if (r->headers_out.etag == NULL) {
- return 0;
- }
-
- etag = &r->headers_out.etag->value;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http im:\"%V\" etag:%V", list, etag);
-
- start = list->data;
- end = list->data + list->len;
-
- while (start < end) {
-
- if (etag->len > (size_t) (end - start)) {
- return 0;
- }
-
- if (ngx_strncmp(start, etag->data, etag->len) != 0) {
- goto skip;
- }
-
- start += etag->len;
-
- while (start < end) {
- ch = *start;
-
- if (ch == ' ' || ch == '\t') {
- start++;
- continue;
- }
-
- break;
- }
-
- if (start == end || *start == ',') {
- return 1;
- }
-
- skip:
-
- while (start < end && *start != ',') { start++; }
- while (start < end) {
- ch = *start;
-
- if (ch == ' ' || ch == '\t' || ch == ',') {
- start++;
- continue;
- }
-
- break;
- }
- }
-
- return 0;
-}
-
-
static ngx_int_t
ngx_http_not_modified_filter_init(ngx_conf_t *cf)
{
diff -r adb742cf27f7 -r 102149a95d84 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Tue May 27 17:58:09 2014 +0400
+++ b/src/http/ngx_http_core_module.c Wed May 28 16:10:15 2014 +0930
@@ -1851,6 +1851,134 @@
}
+// update etag, append suffix
+ngx_uint_t
+ngx_http_update_etag(ngx_http_request_t *r, ngx_str_t *suffix)
+{
+ ngx_table_elt_t *etag;
+ void *old_etag_value;
+
+ etag = r->headers_out.etag;
+
+ if (etag == NULL || suffix == NULL)
+ return 0;
+
+ old_etag_value = etag->value.data;
+ etag->value.data = ngx_pnalloc(r->pool, etag->value.len +
+ suffix->len + 1);
+ ngx_cpystrn(etag->value.data, old_etag_value, etag->value.len);
+ etag->value.len = ngx_sprintf(etag->value.data + etag->value.len - 1,
+ "%s\"", suffix->data) - etag->value.data;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http updated etag: %s", etag->value.data);
+
+ return 1;
+}
+
+
+ngx_int_t
+ngx_http_test_etag_if_match(ngx_http_request_t *r,
+ ngx_http_output_header_filter_pt next_header_filter,
+ ngx_int_t *etag_filter_result)
+{
+ if (r->headers_in.if_match
+ && !ngx_http_test_if_match(r, r->headers_in.if_match)) {
+ *etag_filter_result = ngx_http_filter_finalize_request
+ (r, NULL, NGX_HTTP_PRECONDITION_FAILED);
+ return 1;
+ }
+ else if (r->headers_in.if_none_match
+ && ngx_http_test_if_match(r, r->headers_in.if_none_match)) {
+ /* not modified */
+ r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
+ r->headers_out.status_line.len = 0;
+ r->headers_out.content_type.len = 0;
+ ngx_http_clear_content_length(r);
+ ngx_http_clear_accept_ranges(r);
+
+ if (r->headers_out.content_encoding) {
+ r->headers_out.content_encoding->hash = 0;
+ r->headers_out.content_encoding = NULL;
+ }
+
+ *etag_filter_result = next_header_filter(r);
+ return 1;
+ }
+ return 0;
+}
+
+
+ngx_uint_t
+ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header)
+{
+ u_char *start, *end, ch;
+ ngx_str_t *etag, *list;
+
+ list = &header->value;
+
+ if (list->len == 1 && list->data[0] == '*') {
+ return 1;
+ }
+
+ if (r->headers_out.etag == NULL) {
+ return 0;
+ }
+
+ etag = &r->headers_out.etag->value;
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http im:\"%V\" etag:%V", list, etag);
+
+ start = list->data;
+ end = list->data + list->len;
+
+ while (start < end) {
+
+ if (etag->len > (size_t) (end - start)) {
+ return 0;
+ }
+
+ if (ngx_strncmp(start, etag->data, etag->len) != 0) {
+ goto skip;
+ }
+
+ start += etag->len;
+
+ while (start < end) {
+ ch = *start;
+
+ if (ch == ' ' || ch == '\t') {
+ start++;
+ continue;
+ }
+
+ break;
+ }
+
+ if (start == end || *start == ',') {
+ return 1;
+ }
+
+ skip:
+
+ while (start < end && *start != ',') { start++; }
+ while (start < end) {
+ ch = *start;
+
+ if (ch == ' ' || ch == '\t' || ch == ',') {
+ start++;
+ continue;
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
ngx_int_t
ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
ngx_str_t *ct, ngx_http_complex_value_t *cv)
diff -r adb742cf27f7 -r 102149a95d84 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Tue May 27 17:58:09 2014 +0400
+++ b/src/http/ngx_http_core_module.h Wed May 28 16:10:15 2014 +0930
@@ -500,7 +500,6 @@
void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t
*types_hash);
ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
void ngx_http_set_exten(ngx_http_request_t *r);
-ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
ngx_str_t *ct, ngx_http_complex_value_t *cv);
u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
@@ -527,6 +526,15 @@
(ngx_http_request_t *r, ngx_chain_t *chain);
+ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
+ngx_uint_t ngx_http_update_etag(ngx_http_request_t *r, ngx_str_t *suffix);
+ngx_int_t ngx_http_test_etag_if_match(ngx_http_request_t *r,
+ ngx_http_output_header_filter_pt next_header_filter,
+ ngx_int_t *etag_filter_result);
+ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r,
+ ngx_table_elt_t *header);
+
+
ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
More information about the nginx-devel
mailing list