]> granicus.if.org Git - apache/commitdiff
After a long discussion in dev@ I reviewed my previous commit to only warn
authorLuca Toscano <elukey@apache.org>
Fri, 26 Aug 2016 11:00:44 +0000 (11:00 +0000)
committerLuca Toscano <elukey@apache.org>
Fri, 26 Aug 2016 11:00:44 +0000 (11:00 +0000)
the admins about Last-Modified header violations rather than trying
to interpret datestrings (like the ones not in GMT).

I also added explicit comments to summarize the current assumptions,
so it will be easier for somebody in the future to modify the code.

The following use cases are covered:
1) (F)CGI backend sends a Last-Modified header not in GMT and considered in the future by httpd (like now() in the EU/Paris timezone)
2) (F)CGI backend sends a Last-Modified header not in GMT and not considered in the future by httpd (like now() + 2 hours in the PST timezone)
3) (F)CGI backend sends a Last-Modified header in GMT but with a datetime in the future

Suggestions and opinion are really welcome.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1757818 13f79535-47bb-0310-9956-ffa450edef68

server/util_script.c

index 443dfb60b88a404279f254578b64ca59125a1b8a..0f12bacc2419007bea2accd5e0a4583f0921dd40 100644 (file)
@@ -673,25 +673,45 @@ AP_DECLARE(int) ap_scan_script_header_err_core_ex(request_rec *r, char *buffer,
          * pass it on blindly because of restrictions on future or invalid values.
          */
         else if (!ap_cstr_casecmp(w, "Last-Modified")) {
-            apr_time_t parsed_date = apr_date_parse_rfc(l);
+            apr_time_t parsed_date = apr_date_parse_http(l);
             if (parsed_date != APR_DATE_BAD) {
-                apr_time_t last_modified_date = parsed_date;
-                apr_time_t now = apr_time_now();
-                if (parsed_date > now) {
-                    last_modified_date = now;
-                }
-                ap_update_mtime(r, last_modified_date);
+                ap_update_mtime(r, parsed_date);
                 ap_set_last_modified(r);
-                if (APLOGrtrace1(r) &&
-                        (parsed_date > now ||
-                         parsed_date != apr_date_parse_http(l))) {
-                    ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
-                                  "The Last-Modified header value '%s' (%s) "
-                                  "has been replaced with '%s'", l,
-                                  parsed_date > now ? "in the future"
-                                                    : "non GMT",
-                                  apr_table_get(r->headers_out,
-                                                "Last-Modified"));
+                if (APLOGrtrace1(r)) {
+                    apr_time_t last_modified_date = apr_date_parse_http(apr_table_get(r->headers_out,
+                                                                                      "Last-Modified"));
+                    /*
+                     * A Last-Modified header value coming from a (F)CGI source
+                     * is considered HTTP input so we assume the GMT timezone.
+                     * The following logs should inform the admin about violations
+                     * and related actions taken by httpd.
+                     * The apr_date_parse_rfc function is 'timezone aware'
+                     * and it will be used to generate a more informative set of logs
+                     * (we don't use it as a replacement of apr_date_parse_http
+                     * for the aforementioned reason).
+                     */
+                    apr_time_t parsed_date_tz_aware = apr_date_parse_rfc(l);
+
+                    /* 
+                     * The parsed Last-Modified header datestring has been replaced by httpd.
+                     */
+                    if (parsed_date > last_modified_date) {
+                        ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
+                                      "The Last-Modified header value %s (%s) "
+                                      "has been replaced with '%s'", l,
+                                      parsed_date != parsed_date_tz_aware ? "not in GMT"
+                                                                          : "in the future",
+                                      apr_table_get(r->headers_out, "Last-Modified"));
+                    /* 
+                     * Last-Modified header datestring not in GMT and not considered in the future
+                     * by httpd (like now() + 1 hour in the PST timezone). No action is taken but
+                     * the admin is warned about the violation.
+                     */
+                    } else if (parsed_date != parsed_date_tz_aware) {
+                        ap_log_rerror(SCRIPT_LOG_MARK, APLOG_TRACE1, 0, r,
+                                      "The Last-Modified header value is not set "
+                                      "within the GMT timezone (as required)");
+                    }
                 }
             }
             else {