[nginx] svn commit: r4745 - in trunk/src/http: . modules

mdounin at mdounin.ru mdounin at mdounin.ru
Sat Jul 7 21:20:28 UTC 2012


Author: mdounin
Date: 2012-07-07 21:20:27 +0000 (Sat, 07 Jul 2012)
New Revision: 4745
URL: http://trac.nginx.org/nginx/changeset/4745/nginx

Log:
Entity tags: basic support in not modified filter.

This includes handling of ETag headers (if present in a response) with
basic support for If-Match, If-None-Match conditionals in not modified
filter.

Note that the "r->headers_out.last_modified_time == -1" check in the not
modified filter is left as is intentionally.  It's to prevent handling
of If-* headers in case of proxy without cache (much like currently
done with If-Modified-Since).


Modified:
   trunk/src/http/modules/ngx_http_not_modified_filter_module.c
   trunk/src/http/ngx_http_request.c
   trunk/src/http/ngx_http_request.h

Modified: trunk/src/http/modules/ngx_http_not_modified_filter_module.c
===================================================================
--- trunk/src/http/modules/ngx_http_not_modified_filter_module.c	2012-07-07 21:18:30 UTC (rev 4744)
+++ trunk/src/http/modules/ngx_http_not_modified_filter_module.c	2012-07-07 21:20:27 UTC (rev 4745)
@@ -12,6 +12,8 @@
 
 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);
 
 
@@ -66,9 +68,27 @@
                                                 NGX_HTTP_PRECONDITION_FAILED);
     }
 
-    if (r->headers_in.if_modified_since
-        && !ngx_http_test_if_modified(r))
+    if (r->headers_in.if_match
+        && !ngx_http_test_if_match(r, r->headers_in.if_match))
     {
+        return ngx_http_filter_finalize_request(r, NULL,
+                                                NGX_HTTP_PRECONDITION_FAILED);
+    }
+
+    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))
+        {
+            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))
+        {
+            return ngx_http_next_header_filter(r);
+        }
+
         /* not modified */
 
         r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
@@ -140,6 +160,76 @@
 }
 
 
+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)
 {

Modified: trunk/src/http/ngx_http_request.c
===================================================================
--- trunk/src/http/ngx_http_request.c	2012-07-07 21:18:30 UTC (rev 4744)
+++ trunk/src/http/ngx_http_request.c	2012-07-07 21:20:27 UTC (rev 4745)
@@ -93,6 +93,14 @@
                  offsetof(ngx_http_headers_in_t, if_unmodified_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("If-None-Match"),
+                 offsetof(ngx_http_headers_in_t, if_none_match),
+                 ngx_http_process_unique_header_line },
+
     { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
                  ngx_http_process_user_agent },
 

Modified: trunk/src/http/ngx_http_request.h
===================================================================
--- trunk/src/http/ngx_http_request.h	2012-07-07 21:18:30 UTC (rev 4744)
+++ trunk/src/http/ngx_http_request.h	2012-07-07 21:20:27 UTC (rev 4745)
@@ -172,6 +172,8 @@
     ngx_table_elt_t                  *connection;
     ngx_table_elt_t                  *if_modified_since;
     ngx_table_elt_t                  *if_unmodified_since;
+    ngx_table_elt_t                  *if_match;
+    ngx_table_elt_t                  *if_none_match;
     ngx_table_elt_t                  *user_agent;
     ngx_table_elt_t                  *referer;
     ngx_table_elt_t                  *content_length;



More information about the nginx-devel mailing list