ngx_http_parse_time.c

来自「Nginx是一个高性能的HTTP和反向代理服务器」· C语言 代码 · 共 273 行

C
273
字号
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_types.h>static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };time_tngx_http_parse_time(u_char *value, size_t len){    u_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;    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;    }#if (NGX_TIME_T_SIZE <= 4)    if (year >= 2038) {        return NGX_ERROR;    }#endif    /*     * 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 Grigorian days since March 1, 1 BC */    return (            /* 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;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?