1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_types.h>
10
11
12 static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
13
14 time_t
15 ngx_http_parse_time(u_char *value, size_t len)
16 {
17 u_char *p, *end;
18 int day, month, year, hour, min, sec;
19 enum {
20 no = 0,
21 rfc822, /* Tue, 10 Nov 2002 23:50:13 */
22 rfc850, /* Tuesday, 10-Dec-02 23:50:13 */
23 isoc /* Tue Dec 10 23:50:13 2002 */
24 } fmt;
25
26 fmt = 0;
27 end = value + len;
28
29 #if (NGX_SUPPRESS_WARN)
30 day = 32;
31 year = 2038;
32 #endif
33
34 for (p = value; p < end; p++) {
35 if (*p == ',') {
36 break;
37 }
38
39 if (*p == ' ') {
40 fmt = isoc;
41 break;
42 }
43 }
44
45 for (p++; p < end; p++)
46 if (*p != ' ') {
47 break;
48 }
49
50 if (end - p < 18) {
51 return NGX_ERROR;
52 }
53
54 if (fmt != isoc) {
55 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9') {
56 return NGX_ERROR;
57 }
58
59 day = (*p - '') * 10 + *(p + 1) - '';
60 p += 2;
61
62 if (*p == ' ') {
63 if (end - p < 18) {
64 return NGX_ERROR;
65 }
66 fmt = rfc822;
67
68 } else if (*p == '-') {
69 fmt = rfc850;
70
71 } else {
72 return NGX_ERROR;
73 }
74
75 p++;
76 }
77
78 switch (*p) {
79
80 case 'J':
81 month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
82 break;
83
84 case 'F':
85 month = 1;
86 break;
87
88 case 'M':
89 month = *(p + 2) == 'r' ? 2 : 4;
90 break;
91
92 case 'A':
93 month = *(p + 1) == 'p' ? 3 : 7;
94 break;
95
96 case 'S':
97 month = 8;
98 break;
99
100 case 'O':
101 month = 9;
102 break;
103
104 case 'N':
105 month = 10;
106 break;
107
108 case 'D':
109 month = 11;
110 break;
111
112 default:
113 return NGX_ERROR;
114 }
115
116 p += 3;
117
118 if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
119 return NGX_ERROR;
120 }
121
122 p++;
123
124 if (fmt == rfc822) {
125 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9'
126 || *(p + 2) < '' || *(p + 2) > '9'
127 || *(p + 3) < '' || *(p + 3) > '9')
128 {
129 return NGX_ERROR;
130 }
131
132 year = (*p - '') * 1000 + (*(p + 1) - '') * 100
133 + (*(p + 2) - '') * 10 + *(p + 3) - '';
134 p += 4;
135
136 } else if (fmt == rfc850) {
137 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9') {
138 return NGX_ERROR;
139 }
140
141 year = (*p - '') * 10 + *(p + 1) - '';
142 year += (year < 70) ? 2000 : 1900;
143 p += 2;
144 }
145
146 if (fmt == isoc) {
147 if (*p == ' ') {
148 p++;
149 }
150
151 if (*p < '' || *p > '9') {
152 return NGX_ERROR;
153 }
154
155 day = *p++ - '';
156
157 if (*p != ' ') {
158 if (*p < '' || *p > '9') {
159 return NGX_ERROR;
160 }
161
162 day = day * 10 + *p++ - '';
163 }
164
165 if (end - p < 14) {
166 return NGX_ERROR;
167 }
168 }
169
170 if (*p++ != ' ') {
171 return NGX_ERROR;
172 }
173
174 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9') {
175 return NGX_ERROR;
176 }
177
178 hour = (*p - '') * 10 + *(p + 1) - '';
179 p += 2;
180
181 if (*p++ != ':') {
182 return NGX_ERROR;
183 }
184
185 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9') {
186 return NGX_ERROR;
187 }
188
189 min = (*p - '') * 10 + *(p + 1) - '';
190 p += 2;
191
192 if (*p++ != ':') {
193 return NGX_ERROR;
194 }
195
196 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9') {
197 return NGX_ERROR;
198 }
199
200 sec = (*p - '') * 10 + *(p + 1) - '';
201
202 if (fmt == isoc) {
203 p += 2;
204
205 if (*p++ != ' ') {
206 return NGX_ERROR;
207 }
208
209 if (*p < '' || *p > '9' || *(p + 1) < '' || *(p + 1) > '9'
210 || *(p + 2) < '' || *(p + 2) > '9'
211 || *(p + 3) < '' || *(p + 3) > '9')
212 {
213 return NGX_ERROR;
214 }
215
216 year = (*p - '') * 1000 + (*(p + 1) - '') * 100
217 + (*(p + 2) - '') * 10 + *(p + 3) - '';
218 }
219
220 if (hour > 23 || min > 59 || sec > 59) {
221 return NGX_ERROR;
222 }
223
224 if (day == 29 && month == 1) {
225 if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
226 return NGX_ERROR;
227 }
228
229 } else if (day > mday[month]) {
230 return NGX_ERROR;
231 }
232
233 #if (NGX_TIME_T_SIZE <= 4)
234
235 if (year >= 2038) {
236 return NGX_ERROR;
237 }
238
239 #endif
240
241 /*
242 * shift new year to March 1 and start months from 1 (not 0),
243 * it is needed for Gauss's formula
244 */
245
246 if (--month <= 0) {
247 month += 12;
248 year -= 1;
249 }
250
251 /* Gauss's formula for Grigorian days from March 1, 1 BC */
252
253 return (365 * year + year / 4 - year / 100 + year / 400
254 + 367 * month / 12 - 31
255 + day
256
257 /*
258 * 719527 days were between March 1, 1 BC and March 1, 1970,
259 * 31 and 28 days were in January and February 1970
260 */
261
262 - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
263 }
264
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.