changeset 6180:8b6fa4842133

Moved ngx_http_parse_time() to core, renamed accordingly. The function is now called ngx_parse_http_time(), and can be used by any code to parse HTTP-style date and time. In particular, it will be used for OCSP stapling. For compatibility, a macro to map ngx_http_parse_time() to the new name provided for a while.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 11 Jun 2015 20:42:31 +0300
parents c61210e2e081
children 6893a1007a7c
files auto/sources src/core/ngx_core.h src/core/ngx_parse_time.c src/core/ngx_parse_time.h src/http/modules/ngx_http_dav_module.c src/http/modules/ngx_http_headers_filter_module.c src/http/modules/ngx_http_not_modified_filter_module.c src/http/modules/ngx_http_range_filter_module.c src/http/ngx_http.h src/http/ngx_http_core_module.c src/http/ngx_http_parse_time.c src/http/ngx_http_upstream.c
diffstat 12 files changed, 311 insertions(+), 291 deletions(-) [+]
line wrap: on
line diff
--- a/auto/sources	Thu Jun 11 20:42:24 2015 +0300
+++ b/auto/sources	Thu Jun 11 20:42:31 2015 +0300
@@ -19,6 +19,7 @@
            src/core/ngx_queue.h \
            src/core/ngx_string.h \
            src/core/ngx_parse.h \
+           src/core/ngx_parse_time.h \
            src/core/ngx_inet.h \
            src/core/ngx_file.h \
            src/core/ngx_crc.h \
@@ -53,6 +54,7 @@
            src/core/ngx_output_chain.c \
            src/core/ngx_string.c \
            src/core/ngx_parse.c \
+           src/core/ngx_parse_time.c \
            src/core/ngx_inet.c \
            src/core/ngx_file.c \
            src/core/ngx_crc32.c \
@@ -303,7 +305,6 @@
            src/http/ngx_http_script.c \
            src/http/ngx_http_upstream.c \
            src/http/ngx_http_upstream_round_robin.c \
-           src/http/ngx_http_parse_time.c \
            src/http/modules/ngx_http_static_module.c \
            src/http/modules/ngx_http_index_module.c \
            src/http/modules/ngx_http_chunked_filter_module.c \
--- a/src/core/ngx_core.h	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/core/ngx_core.h	Thu Jun 11 20:42:31 2015 +0300
@@ -54,6 +54,7 @@
 #include <ngx_process.h>
 #include <ngx_user.h>
 #include <ngx_parse.h>
+#include <ngx_parse_time.h>
 #include <ngx_log.h>
 #include <ngx_alloc.h>
 #include <ngx_palloc.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/ngx_parse_time.c	Thu Jun 11 20:42:31 2015 +0300
@@ -0,0 +1,276 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+static ngx_uint_t  mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+time_t
+ngx_parse_http_time(u_char *value, size_t len)
+{
+    u_char      *p, *end;
+    ngx_int_t    month;
+    ngx_uint_t   day, year, hour, min, sec;
+    uint64_t     time;
+    enum {
+        no = 0,
+        rfc822,   /* Tue, 10 Nov 2002 23:50:13   */
+        rfc850,   /* Tuesday, 10-Dec-02 23:50:13 */
+        isoc      /* Tue Dec 10 23:50:13 2002    */
+    } fmt;
+
+    fmt = 0;
+    end = value + len;
+
+#if (NGX_SUPPRESS_WARN)
+    day = 32;
+    year = 2038;
+#endif
+
+    for (p = value; p < end; p++) {
+        if (*p == ',') {
+            break;
+        }
+
+        if (*p == ' ') {
+            fmt = isoc;
+            break;
+        }
+    }
+
+    for (p++; p < end; p++)
+        if (*p != ' ') {
+            break;
+        }
+
+    if (end - p < 18) {
+        return NGX_ERROR;
+        }
+
+    if (fmt != isoc) {
+        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
+            return NGX_ERROR;
+        }
+
+        day = (*p - '0') * 10 + *(p + 1) - '0';
+        p += 2;
+
+        if (*p == ' ') {
+            if (end - p < 18) {
+                return NGX_ERROR;
+            }
+            fmt = rfc822;
+
+        } else if (*p == '-') {
+            fmt = rfc850;
+
+        } else {
+            return NGX_ERROR;
+        }
+
+        p++;
+    }
+
+    switch (*p) {
+
+    case 'J':
+        month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
+        break;
+
+    case 'F':
+        month = 1;
+        break;
+
+    case 'M':
+        month = *(p + 2) == 'r' ? 2 : 4;
+        break;
+
+    case 'A':
+        month = *(p + 1) == 'p' ? 3 : 7;
+        break;
+
+    case 'S':
+        month = 8;
+        break;
+
+    case 'O':
+        month = 9;
+        break;
+
+    case 'N':
+        month = 10;
+        break;
+
+    case 'D':
+        month = 11;
+        break;
+
+    default:
+        return NGX_ERROR;
+    }
+
+    p += 3;
+
+    if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
+        return NGX_ERROR;
+    }
+
+    p++;
+
+    if (fmt == rfc822) {
+        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
+            || *(p + 2) < '0' || *(p + 2) > '9'
+            || *(p + 3) < '0' || *(p + 3) > '9')
+        {
+            return NGX_ERROR;
+        }
+
+        year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
+               + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
+        p += 4;
+
+    } else if (fmt == rfc850) {
+        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
+            return NGX_ERROR;
+        }
+
+        year = (*p - '0') * 10 + *(p + 1) - '0';
+        year += (year < 70) ? 2000 : 1900;
+        p += 2;
+    }
+
+    if (fmt == isoc) {
+        if (*p == ' ') {
+            p++;
+        }
+
+        if (*p < '0' || *p > '9') {
+            return NGX_ERROR;
+        }
+
+        day = *p++ - '0';
+
+        if (*p != ' ') {
+            if (*p < '0' || *p > '9') {
+                return NGX_ERROR;
+            }
+
+            day = day * 10 + *p++ - '0';
+        }
+
+        if (end - p < 14) {
+            return NGX_ERROR;
+        }
+    }
+
+    if (*p++ != ' ') {
+        return NGX_ERROR;
+    }
+
+    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
+        return NGX_ERROR;
+    }
+
+    hour = (*p - '0') * 10 + *(p + 1) - '0';
+    p += 2;
+
+    if (*p++ != ':') {
+        return NGX_ERROR;
+    }
+
+    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
+        return NGX_ERROR;
+    }
+
+    min = (*p - '0') * 10 + *(p + 1) - '0';
+    p += 2;
+
+    if (*p++ != ':') {
+        return NGX_ERROR;
+    }
+
+    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
+        return NGX_ERROR;
+    }
+
+    sec = (*p - '0') * 10 + *(p + 1) - '0';
+
+    if (fmt == isoc) {
+        p += 2;
+
+        if (*p++ != ' ') {
+            return NGX_ERROR;
+        }
+
+        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
+            || *(p + 2) < '0' || *(p + 2) > '9'
+            || *(p + 3) < '0' || *(p + 3) > '9')
+        {
+            return NGX_ERROR;
+        }
+
+        year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
+               + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
+    }
+
+    if (hour > 23 || min > 59 || sec > 59) {
+         return NGX_ERROR;
+    }
+
+    if (day == 29 && month == 1) {
+        if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
+            return NGX_ERROR;
+        }
+
+    } else if (day > mday[month]) {
+        return NGX_ERROR;
+    }
+
+    /*
+     * shift new year to March 1 and start months from 1 (not 0),
+     * it is needed for Gauss' formula
+     */
+
+    if (--month <= 0) {
+        month += 12;
+        year -= 1;
+    }
+
+    /* Gauss' formula for Gregorian days since March 1, 1 BC */
+
+    time = (uint64_t) (
+            /* days in years including leap years since March 1, 1 BC */
+
+            365 * year + year / 4 - year / 100 + year / 400
+
+            /* days before the month */
+
+            + 367 * month / 12 - 30
+
+            /* days before the day */
+
+            + day - 1
+
+            /*
+             * 719527 days were between March 1, 1 BC and March 1, 1970,
+             * 31 and 28 days were in January and February 1970
+             */
+
+            - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
+
+#if (NGX_TIME_T_SIZE <= 4)
+
+    if (time > 0x7fffffff) {
+        return NGX_ERROR;
+    }
+
+#endif
+
+    return (time_t) time;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/ngx_parse_time.h	Thu Jun 11 20:42:31 2015 +0300
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#ifndef _NGX_PARSE_TIME_H_INCLUDED_
+#define _NGX_PARSE_TIME_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+time_t ngx_parse_http_time(u_char *value, size_t len);
+
+/* compatibility */
+#define ngx_http_parse_time(value, len)  ngx_parse_http_time(value, len)
+
+
+#endif /* _NGX_PARSE_TIME_H_INCLUDED_ */
--- a/src/http/modules/ngx_http_dav_module.c	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/modules/ngx_http_dav_module.c	Thu Jun 11 20:42:31 2015 +0300
@@ -255,7 +255,7 @@
     ext.log = r->connection->log;
 
     if (r->headers_in.date) {
-        date = ngx_http_parse_time(r->headers_in.date->value.data,
+        date = ngx_parse_http_time(r->headers_in.date->value.data,
                                    r->headers_in.date->value.len);
 
         if (date != NGX_ERROR) {
--- a/src/http/modules/ngx_http_headers_filter_module.c	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/modules/ngx_http_headers_filter_module.c	Thu Jun 11 20:42:31 2015 +0300
@@ -498,7 +498,7 @@
     }
 
     r->headers_out.last_modified_time =
-        (value->len) ? ngx_http_parse_time(value->data, value->len) : -1;
+        (value->len) ? ngx_parse_http_time(value->data, value->len) : -1;
 
     return NGX_OK;
 }
--- a/src/http/modules/ngx_http_not_modified_filter_module.c	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/modules/ngx_http_not_modified_filter_module.c	Thu Jun 11 20:42:31 2015 +0300
@@ -118,7 +118,7 @@
         return 0;
     }
 
-    iums = ngx_http_parse_time(r->headers_in.if_unmodified_since->value.data,
+    iums = ngx_parse_http_time(r->headers_in.if_unmodified_since->value.data,
                                r->headers_in.if_unmodified_since->value.len);
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -148,7 +148,7 @@
         return 1;
     }
 
-    ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
+    ims = ngx_parse_http_time(r->headers_in.if_modified_since->value.data,
                               r->headers_in.if_modified_since->value.len);
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
--- a/src/http/modules/ngx_http_range_filter_module.c	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/modules/ngx_http_range_filter_module.c	Thu Jun 11 20:42:31 2015 +0300
@@ -204,7 +204,7 @@
             goto next_filter;
         }
 
-        if_range_time = ngx_http_parse_time(if_range->data, if_range->len);
+        if_range_time = ngx_parse_http_time(if_range->data, if_range->len);
 
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "http ir:%d lm:%d",
--- a/src/http/ngx_http.h	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/ngx_http.h	Thu Jun 11 20:42:31 2015 +0300
@@ -148,9 +148,6 @@
 void ngx_http_clean_header(ngx_http_request_t *r);
 
 
-time_t ngx_http_parse_time(u_char *value, size_t len);
-
-
 ngx_int_t ngx_http_discard_request_body(ngx_http_request_t *r);
 void ngx_http_discarded_request_body_handler(ngx_http_request_t *r);
 void ngx_http_block_reading(ngx_http_request_t *r);
--- a/src/http/ngx_http_core_module.c	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/ngx_http_core_module.c	Thu Jun 11 20:42:31 2015 +0300
@@ -2195,7 +2195,7 @@
             return NGX_DECLINED;
         }
 
-        expires = ngx_http_parse_time(e->value.data, e->value.len);
+        expires = ngx_parse_http_time(e->value.data, e->value.len);
         if (expires == NGX_ERROR) {
             return NGX_DECLINED;
         }
@@ -2203,7 +2203,7 @@
         d = r->headers_out.date;
 
         if (d) {
-            date = ngx_http_parse_time(d->value.data, d->value.len);
+            date = ngx_parse_http_time(d->value.data, d->value.len);
             if (date == NGX_ERROR) {
                 return NGX_DECLINED;
             }
--- a/src/http/ngx_http_parse_time.c	Thu Jun 11 20:42:24 2015 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_uint_t  mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-time_t
-ngx_http_parse_time(u_char *value, size_t len)
-{
-    u_char      *p, *end;
-    ngx_int_t    month;
-    ngx_uint_t   day, year, hour, min, sec;
-    uint64_t     time;
-    enum {
-        no = 0,
-        rfc822,   /* Tue, 10 Nov 2002 23:50:13   */
-        rfc850,   /* Tuesday, 10-Dec-02 23:50:13 */
-        isoc      /* Tue Dec 10 23:50:13 2002    */
-    } fmt;
-
-    fmt = 0;
-    end = value + len;
-
-#if (NGX_SUPPRESS_WARN)
-    day = 32;
-    year = 2038;
-#endif
-
-    for (p = value; p < end; p++) {
-        if (*p == ',') {
-            break;
-        }
-
-        if (*p == ' ') {
-            fmt = isoc;
-            break;
-        }
-    }
-
-    for (p++; p < end; p++)
-        if (*p != ' ') {
-            break;
-        }
-
-    if (end - p < 18) {
-        return NGX_ERROR;
-        }
-
-    if (fmt != isoc) {
-        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
-            return NGX_ERROR;
-        }
-
-        day = (*p - '0') * 10 + *(p + 1) - '0';
-        p += 2;
-
-        if (*p == ' ') {
-            if (end - p < 18) {
-                return NGX_ERROR;
-            }
-            fmt = rfc822;
-
-        } else if (*p == '-') {
-            fmt = rfc850;
-
-        } else {
-            return NGX_ERROR;
-        }
-
-        p++;
-    }
-
-    switch (*p) {
-
-    case 'J':
-        month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
-        break;
-
-    case 'F':
-        month = 1;
-        break;
-
-    case 'M':
-        month = *(p + 2) == 'r' ? 2 : 4;
-        break;
-
-    case 'A':
-        month = *(p + 1) == 'p' ? 3 : 7;
-        break;
-
-    case 'S':
-        month = 8;
-        break;
-
-    case 'O':
-        month = 9;
-        break;
-
-    case 'N':
-        month = 10;
-        break;
-
-    case 'D':
-        month = 11;
-        break;
-
-    default:
-        return NGX_ERROR;
-    }
-
-    p += 3;
-
-    if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
-        return NGX_ERROR;
-    }
-
-    p++;
-
-    if (fmt == rfc822) {
-        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
-            || *(p + 2) < '0' || *(p + 2) > '9'
-            || *(p + 3) < '0' || *(p + 3) > '9')
-        {
-            return NGX_ERROR;
-        }
-
-        year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
-               + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
-        p += 4;
-
-    } else if (fmt == rfc850) {
-        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
-            return NGX_ERROR;
-        }
-
-        year = (*p - '0') * 10 + *(p + 1) - '0';
-        year += (year < 70) ? 2000 : 1900;
-        p += 2;
-    }
-
-    if (fmt == isoc) {
-        if (*p == ' ') {
-            p++;
-        }
-
-        if (*p < '0' || *p > '9') {
-            return NGX_ERROR;
-        }
-
-        day = *p++ - '0';
-
-        if (*p != ' ') {
-            if (*p < '0' || *p > '9') {
-                return NGX_ERROR;
-            }
-
-            day = day * 10 + *p++ - '0';
-        }
-
-        if (end - p < 14) {
-            return NGX_ERROR;
-        }
-    }
-
-    if (*p++ != ' ') {
-        return NGX_ERROR;
-    }
-
-    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
-        return NGX_ERROR;
-    }
-
-    hour = (*p - '0') * 10 + *(p + 1) - '0';
-    p += 2;
-
-    if (*p++ != ':') {
-        return NGX_ERROR;
-    }
-
-    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
-        return NGX_ERROR;
-    }
-
-    min = (*p - '0') * 10 + *(p + 1) - '0';
-    p += 2;
-
-    if (*p++ != ':') {
-        return NGX_ERROR;
-    }
-
-    if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
-        return NGX_ERROR;
-    }
-
-    sec = (*p - '0') * 10 + *(p + 1) - '0';
-
-    if (fmt == isoc) {
-        p += 2;
-
-        if (*p++ != ' ') {
-            return NGX_ERROR;
-        }
-
-        if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
-            || *(p + 2) < '0' || *(p + 2) > '9'
-            || *(p + 3) < '0' || *(p + 3) > '9')
-        {
-            return NGX_ERROR;
-        }
-
-        year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
-               + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
-    }
-
-    if (hour > 23 || min > 59 || sec > 59) {
-         return NGX_ERROR;
-    }
-
-    if (day == 29 && month == 1) {
-        if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
-            return NGX_ERROR;
-        }
-
-    } else if (day > mday[month]) {
-        return NGX_ERROR;
-    }
-
-    /*
-     * shift new year to March 1 and start months from 1 (not 0),
-     * it is needed for Gauss' formula
-     */
-
-    if (--month <= 0) {
-        month += 12;
-        year -= 1;
-    }
-
-    /* Gauss' formula for Gregorian days since March 1, 1 BC */
-
-    time = (uint64_t) (
-            /* days in years including leap years since March 1, 1 BC */
-
-            365 * year + year / 4 - year / 100 + year / 400
-
-            /* days before the month */
-
-            + 367 * month / 12 - 30
-
-            /* days before the day */
-
-            + day - 1
-
-            /*
-             * 719527 days were between March 1, 1 BC and March 1, 1970,
-             * 31 and 28 days were in January and February 1970
-             */
-
-            - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
-
-#if (NGX_TIME_T_SIZE <= 4)
-
-    if (time > 0x7fffffff) {
-        return NGX_ERROR;
-    }
-
-#endif
-
-    return (time_t) time;
-}
--- a/src/http/ngx_http_upstream.c	Thu Jun 11 20:42:24 2015 +0300
+++ b/src/http/ngx_http_upstream.c	Thu Jun 11 20:42:31 2015 +0300
@@ -3731,7 +3731,7 @@
 
     if (u->headers_in.last_modified) {
 
-        lm = ngx_http_parse_time(u->headers_in.last_modified->value.data,
+        lm = ngx_parse_http_time(u->headers_in.last_modified->value.data,
                                  u->headers_in.last_modified->value.len);
 
         if (lm != NGX_ERROR) {
@@ -4128,7 +4128,7 @@
 #if (NGX_HTTP_CACHE)
 
     if (u->cacheable) {
-        u->headers_in.last_modified_time = ngx_http_parse_time(h->value.data,
+        u->headers_in.last_modified_time = ngx_parse_http_time(h->value.data,
                                                                h->value.len);
     }
 
@@ -4292,7 +4292,7 @@
         return NGX_OK;
     }
 
-    expires = ngx_http_parse_time(h->value.data, h->value.len);
+    expires = ngx_parse_http_time(h->value.data, h->value.len);
 
     if (expires == NGX_ERROR || expires < ngx_time()) {
         u->cacheable = 0;