/[james]/httplint/httplint.c
ViewVC logotype

Diff of /httplint/httplint.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 40 by james, Mon Dec 15 15:07:31 2003 UTC revision 43 by james, Wed Dec 17 21:54:46 2003 UTC
# Line 36  CURL *curl; Line 36  CURL *curl;
36  int status_code;  int status_code;
37  char error_buffer[CURL_ERROR_SIZE];  char error_buffer[CURL_ERROR_SIZE];
38  regex_t re_status_line, re_token, re_token_value, re_content_type, re_ugly,  regex_t re_status_line, re_token, re_token_value, re_content_type, re_ugly,
39      re_absolute_uri, re_etag, re_server, re_transfer_coding, re_upgrade;      re_absolute_uri, re_etag, re_server, re_transfer_coding, re_upgrade,
40        re_rfc1123, re_rfc1036, re_asctime;
41    
42    
43  void init(void);  void init(void);
# Line 47  size_t data_callback(void *ptr, size_t s Line 48  size_t data_callback(void *ptr, size_t s
48  void check_status_line(const char *s);  void check_status_line(const char *s);
49  void check_header(const char *name, const char *value);  void check_header(const char *name, const char *value);
50  bool parse_date(const char *s, struct tm *tm);  bool parse_date(const char *s, struct tm *tm);
51    int month(const char *s);
52    time_t mktime_from_utc(struct tm *t);
53  const char *skip_lws(const char *s);  const char *skip_lws(const char *s);
54  bool parse_list(const char *s, regex_t *preg, unsigned int n, unsigned int m,  bool parse_list(const char *s, regex_t *preg, unsigned int n, unsigned int m,
55      void (*callback)(const char *s, regmatch_t pmatch[]));      void (*callback)(const char *s, regmatch_t pmatch[]));
# Line 202  void init(void) Line 205  void init(void)
205        "^([-0-9a-zA-Z_.](/[-0-9a-zA-Z_.])?)+$",        "^([-0-9a-zA-Z_.](/[-0-9a-zA-Z_.])?)+$",
206        REG_EXTENDED);        REG_EXTENDED);
207    regcomp_wrapper(&re_ugly,    regcomp_wrapper(&re_ugly,
208        "^[a-zA-Z0-9]+://[^/]+[/a-zA-Z0-9-_]*$",        "^[a-zA-Z0-9]+://[^/]+[-/a-zA-Z0-9_]*$",
209          REG_EXTENDED);
210      regcomp_wrapper(&re_rfc1123,
211          "^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), ([0123][0-9]) "
212          "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([0-9]{4}) "
213          "([012][0-9]):([0-5][0-9]):([0-5][0-9]) GMT$",
214          REG_EXTENDED);
215      regcomp_wrapper(&re_rfc1036,
216          "^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), "
217          "([0123][0-9])-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-"
218          "([0-9][0-9]) ([012][0-9]):([0-5][0-9]):([0-5][0-9]) GMT$",
219          REG_EXTENDED);
220      regcomp_wrapper(&re_asctime,
221          "^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) "
222          "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([ 12][0-9]) "
223          "([012][0-9]):([0-5][0-9]):([0-5][0-9]) ([0-9]{4})$",
224        REG_EXTENDED);        REG_EXTENDED);
225  }  }
226    
# Line 390  void check_header(const char *name, cons Line 408  void check_header(const char *name, cons
408   */   */
409  bool parse_date(const char *s, struct tm *tm)  bool parse_date(const char *s, struct tm *tm)
410  {  {
411    char *r;    int r;
412    int len = strlen(s);    int len = strlen(s);
413      regmatch_t pmatch[20];
414    
415    if (len == 29) {    if (len == 29) {
416      /* RFC 1123 */      /* RFC 1123 */
417      r = strptime(s, "%a, %d %b %Y %H:%M:%S GMT", tm);      r = regexec(&re_rfc1123, s, 20, pmatch, 0);
418      if (r == s + len)      if (r == 0) {
419          tm->tm_mday = atoi(s + pmatch[2].rm_so);
420          tm->tm_mon = month(s + pmatch[3].rm_so);
421          tm->tm_year = atoi(s + pmatch[4].rm_so) - 1900;
422          tm->tm_hour = atoi(s + pmatch[5].rm_so);
423          tm->tm_min = atoi(s + pmatch[6].rm_so);
424          tm->tm_sec = atoi(s + pmatch[7].rm_so);
425        return true;        return true;
426        }
427    
428    } else if (len == 24) {    } else if (len == 24) {
429      /* asctime() format */      /* asctime() format */
430      r = strptime(s, "%a %b %d %H:%M:%S %Y", tm);      r = regexec(&re_asctime, s, 20, pmatch, 0);
431      if (r == s + len) {      if (r == 0) {
432        lookup("asctime");        if (s[pmatch[3].rm_so] == ' ')
433        return true;          tm->tm_mday = atoi(s + pmatch[3].rm_so + 1);
434      }        else
435      r = strptime(s, "%a %b  %d %H:%M:%S %Y", tm);          tm->tm_mday = atoi(s + pmatch[3].rm_so);
436      if (r == s + len) {        tm->tm_mon = month(s + pmatch[2].rm_so);
437          tm->tm_year = atoi(s + pmatch[7].rm_so) - 1900;
438          tm->tm_hour = atoi(s + pmatch[4].rm_so);
439          tm->tm_min = atoi(s + pmatch[5].rm_so);
440          tm->tm_sec = atoi(s + pmatch[6].rm_so);
441        lookup("asctime");        lookup("asctime");
442        return true;        return true;
443      }      }
444    
445    } else {    } else {
446      /* RFC 1036 */      /* RFC 1036 */
447      r = strptime(s, "%a, %d-%b-%y %H:%M:%S GMT", tm);      r = regexec(&re_rfc1036, s, 20, pmatch, 0);
448      if (r == s + len) {      if (r == 0) {
449          tm->tm_mday = atoi(s + pmatch[2].rm_so);
450          tm->tm_mon = month(s + pmatch[3].rm_so);
451          tm->tm_year = 100 + atoi(s + pmatch[4].rm_so);
452          tm->tm_hour = atoi(s + pmatch[5].rm_so);
453          tm->tm_min = atoi(s + pmatch[6].rm_so);
454          tm->tm_sec = atoi(s + pmatch[7].rm_so);
455        lookup("rfc1036");        lookup("rfc1036");
456        return true;        return true;
457      }      }
# Line 428  bool parse_date(const char *s, struct tm Line 464  bool parse_date(const char *s, struct tm
464    
465    
466  /**  /**
467     * Convert a month name to the month number.
468     */
469    int month(const char *s)
470    {
471      switch (s[0]) {
472        case 'J':
473          switch (s[1]) {
474            case 'a':
475              return 0;
476            case 'u':
477              return s[2] == 'n' ? 5 : 6;
478          }
479        case 'F':
480          return 1;
481        case 'M':
482          return s[2] == 'r' ? 2 : 4;
483        case 'A':
484          return s[1] == 'p' ? 3 : 7;
485        case 'S':
486          return 8;
487        case 'O':
488          return 9;
489        case 'N':
490          return 10;
491        case 'D':
492          return 11;
493      }
494      return 0;
495    }
496    
497    
498    /**
499     * UTC version of mktime, from
500     *   http://lists.debian.org/deity/2002/deity-200204/msg00082.html
501     */
502    time_t mktime_from_utc(struct tm *t)
503    {
504      time_t tl, tb;
505      struct tm *tg;
506    
507      tl = mktime (t);
508      if (tl == -1)
509        {
510          t->tm_hour--;
511          tl = mktime (t);
512          if (tl == -1)
513            return -1; /* can't deal with output from strptime */
514          tl += 3600;
515        }
516      tg = gmtime (&tl);
517      tg->tm_isdst = 0;
518      tb = mktime (tg);
519      if (tb == -1)
520        {
521          tg->tm_hour--;
522          tb = mktime (tg);
523          if (tb == -1)
524            return -1; /* can't deal with output from gmtime */
525          tb += 3600;
526        }
527      return (tl - (tb - tl));
528    }
529    
530    
531    /**
532   * Skip optional LWS (linear white space) [2.2]   * Skip optional LWS (linear white space) [2.2]
533   */   */
534  const char *skip_lws(const char *s)  const char *skip_lws(const char *s)
# Line 681  void header_date(const char *s) Line 782  void header_date(const char *s)
782    time0 = time(0);    time0 = time(0);
783    if (!parse_date(s, &tm))    if (!parse_date(s, &tm))
784      return;      return;
785    time1 = mktime(&tm);    time1 = mktime_from_utc(&tm);
786    
787    diff = difftime(time0, time1);    diff = difftime(time0, time1);
788    if (10 < fabs(diff))    if (10 < fabs(diff))

Legend:
Removed from v.40  
changed lines
  Added in v.43

  ViewVC Help
Powered by ViewVC 1.1.26