Mercurial > hg > nginx
view src/http/ngx_http_parse_time.c @ 5520:a336cbc3dd44
SPDY: send output queue after processing of read event.
During the processing of input some control frames can be added to the queue.
And if there were no writing streams at the moment, these control frames might
be left unsent for a long time (or even forever).
This long delay is especially critical for PING replies since a client can
consider connection as broken and then resend exactly the same request over
a new connection, which is not safe in case of non-idempotent HTTP methods.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Wed, 15 Jan 2014 17:16:38 +0400 |
parents | 4c36e15651f7 |
children |
line wrap: on
line source
/* * 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; }