changeset 25:a8b156554dfe

nginx-0.0.1-2002-12-11-19:57:54 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 11 Dec 2002 16:57:54 +0000
parents 77c7629a2627
children 53cb81681040
files src/http/ngx_http_parse_time.c
diffstat 1 files changed, 208 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -1,64 +1,230 @@
 
-time_t ngx_http_parse_time()
-{
-    enum {
-        sw_start = 0,
-    } state;
+#include <time.h>
 
-    state = sw_start;
+#define NGX_ERROR  -1
+
+static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
-    while () {
-        switch (state) {
+time_t ngx_http_parse_time(char *value, size_t len)
+{
+    char  *p, *end;
+    int    day, month, year, hour, min, sec;
+    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;
+
+    end = value + len;
 
-        case sw_start:
-            if (ch == ' ') {
-                ansi = 1;
-                state = sw_month;
+    for (p = value; p < end; p++) {
+        if (*p == ',')
+            break;
 
-            } else if (ch == ',')
-                state = sw_day_first_digit;
+        if (*p == ' ') {
+            fmt = isoc;
+            break;
+        }
+    }
 
+    for (p++; p < end; p++)
+        if (*p != ' ')
             break;
 
-        case sw_day_first_digit:
-            if (ch == ' ')
-                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;
 
-            if (ch >= '0' && ch <= '9') {
-                day = ch - '0';
-                state = sw_day;
-                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;
 
-        case sw_day:
-            if (ansi && ch == ' ') {
-                state = sw_hour_first_digit;
-                break;
-            }
+        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 (ch >= '0' && ch <= '9') {
-                day = ch - '0';
-                state = ansi ? sw_space_before_hour : sw_before_month;
-                break;
-            }
+    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;
 
-        case sw_before_month:
-            if (ch == ' ') {
-                rfc822 = 1;
-            }
+        year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
+               + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
+    }
+
+    printf("%d.%d.%d %d:%d:%d\n", day, month + 1, year, hour, min, sec);
+
+    if (hour > 23 || min > 60 || sec > 60)
+         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;
+    }
+
+    if (sizeof(time_t) <= 4 && year >= 2038)
+        return NGX_ERROR;
+
+    if (--month <= 0) {
+       month += 12;
+       year -= 1;
+    }
 
-            if (ch == '-') {
-                rfc850 = 1;
-            }
+    return year / 4 - year / 100 + year / 400
+           + 367 * month / 12 + day + year * 365 - 719499;
+}
+
+char zero[] = "Sun, 01 Jan 1970 08:49:30";
+char one[]  = "Sunday, 11-Dec-02 08:49:30";
+char two[]  = "Sun Mar 1 08:49:37 2000";
+char thr[]  = "Sun Dec 11 08:49:37 2002";
+
+main()
+{
+    int rc;
 
-        case sw_space_before_hour:
+    rc = ngx_http_parse_time(zero, sizeof(zero) - 1);
+    printf("rc: %d\n", rc);
 
+    rc = ngx_http_parse_time(one, sizeof(one) - 1);
+    printf("rc: %d\n", rc);
 
-        }
-    }
+    rc = ngx_http_parse_time(two, sizeof(two) - 1);
+    printf("rc: %d\n", rc);
+
+    rc = ngx_http_parse_time(thr, sizeof(thr) - 1);
+    printf("rc: %d\n", rc);
 }