~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/ngx_http_parse_time.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.