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

Linux Cross Reference
Nginx/http/ngx_http_parse_time.c

Version: ~ [ nginx-0.6.26 ] ~ [ nginx-0.5.35 ] ~ [ nginx-0.5.20 ] ~ [ nginx-0.5.19 ] ~

  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 

~ [ 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.