# HG changeset patch
# User Karthik Uthaman <uthamank@amazon.com>
# Date 1585336898 25200
#      Fri Mar 27 12:21:38 2020 -0700
# Node ID bd4865191aa41c7e505c8e260776640c7b134ca9
# Parent  0cb942c1c1aa98118076e72e0b89940e85e6291c
Fix the precedence of conditional headers as per RF-7232

https://tools.ietf.org/html/rfc7232#section-3.4
A recipient MUST ignore If-Unmodified-Since if the request contains
an If-Match header field; the condition in If-Match is considered to
be a more accurate replacement for the condition in
If-Unmodified-Since, and the two are only combined for the sake of
interoperating with older intermediaries that might not implement
If-Match.

https://tools.ietf.org/html/rfc7232#section-3.3 and
A recipient MUST ignore If-Modified-Since if the request contains an
If-None-Match header field; the condition in If-None-Match is
considered to be a more accurate replacement for the condition in
If-Modified-Since, and the two are only combined for the sake of
interoperating with older intermediaries that might not implement
If-None-Match.

Along with those I have followed the precedence guidance provided in
https://tools.ietf.org/html/rfc7232#section-6 to change the order of
conditional headers being evaluated in nginx.

diff -r 0cb942c1c1aa -r bd4865191aa4 src/http/modules/ngx_http_not_modified_filter_module.c
--- a/src/http/modules/ngx_http_not_modified_filter_module.c	Fri Mar 13 02:12:10 2020 +0300
+++ b/src/http/modules/ngx_http_not_modified_filter_module.c	Fri Mar 27 12:21:38 2020 -0700
@@ -61,13 +61,6 @@
         return ngx_http_next_header_filter(r);
     }
 
-    if (r->headers_in.if_unmodified_since
-        && !ngx_http_test_if_unmodified(r))
-    {
-        return ngx_http_filter_finalize_request(r, NULL,
-                                                NGX_HTTP_PRECONDITION_FAILED);
-    }
-
     if (r->headers_in.if_match
         && !ngx_http_test_if_match(r, r->headers_in.if_match, 0))
     {
@@ -75,16 +68,33 @@
                                                 NGX_HTTP_PRECONDITION_FAILED);
     }
 
+    /* https://tools.ietf.org/html/rfc7232#section-3.4 states that 
+     * If-Unmodified-Since header should be ignored in the presence of 
+     * If-Match header
+     */
+    if (!r->headers_in.if_match
+        && r->headers_in.if_unmodified_since
+        && !ngx_http_test_if_unmodified(r))
+    {
+        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))
+        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);
         }
 
-        if (r->headers_in.if_none_match
-            && !ngx_http_test_if_match(r, r->headers_in.if_none_match, 1))
+        /* https://tools.ietf.org/html/rfc7232#section-3.3 states that
+         * If-Modified-Since header should be ignored in the presence of
+         * If-None-Match 
+         */
+        if (!r->headers_in.if_none_match 
+            && r->headers_in.if_modified_since
+            && ngx_http_test_if_modified(r))
         {
             return ngx_http_next_header_filter(r);
         }
