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

Diff of /httplint/httplint.c

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

revision 47 by james, Thu Dec 18 00:52:50 2003 UTC revision 48 by james, Fri Feb 20 20:13:07 2004 UTC
# Line 37  int status_code; Line 37  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;      re_rfc1123, re_rfc1036, re_asctime, re_cookie_nameval, re_cookie_expires;
41    
42    
43  void init(void);  void init(void);
# Line 81  void header_transfer_encoding_callback(c Line 81  void header_transfer_encoding_callback(c
81  void header_upgrade(const char *s);  void header_upgrade(const char *s);
82  void header_vary(const char *s);  void header_vary(const char *s);
83  void header_via(const char *s);  void header_via(const char *s);
84    void header_set_cookie(const char *s);
85  void die(const char *error);  void die(const char *error);
86  void warning(const char *message);  void warning(const char *message);
87  void error(const char *message);  void error(const char *message);
# Line 114  struct header_entry { Line 115  struct header_entry {
115    { "Pragma", header_pragma, 0, 0 },    { "Pragma", header_pragma, 0, 0 },
116    { "Retry-After", header_retry_after, 0, 0 },    { "Retry-After", header_retry_after, 0, 0 },
117    { "Server", header_server, 0, 0 },    { "Server", header_server, 0, 0 },
118      { "Set-Cookie", header_set_cookie, 0, 0 },
119    { "Trailer", header_trailer, 0, 0 },    { "Trailer", header_trailer, 0, 0 },
120    { "Transfer-Encoding", header_transfer_encoding, 0, 0 },    { "Transfer-Encoding", header_transfer_encoding, 0, 0 },
121    { "Upgrade", header_upgrade, 0, 0 },    { "Upgrade", header_upgrade, 0, 0 },
# Line 222  void init(void) Line 224  void init(void)
224        "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([ 12][0-9]) "        "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([ 12][0-9]) "
225        "([012][0-9]):([0-5][0-9]):([0-5][0-9]) ([0-9]{4})$",        "([012][0-9]):([0-5][0-9]):([0-5][0-9]) ([0-9]{4})$",
226        REG_EXTENDED);        REG_EXTENDED);
227      regcomp_wrapper(&re_cookie_nameval,
228          "^[^;, ]+=[^;, ]*$",
229          REG_EXTENDED);
230      regcomp_wrapper(&re_cookie_expires,
231          "^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), ([0123][0-9])-"
232          "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-([0-9]{4}) "
233          "([012][0-9]):([0-5][0-9]):([0-5][0-9]) GMT$",
234          REG_EXTENDED);
235  }  }
236    
237    
# Line 941  void header_via(const char *s) Line 951  void header_via(const char *s)
951    lookup("via");    lookup("via");
952  }  }
953    
954    /* http://wp.netscape.com/newsref/std/cookie_spec.html */
955    void header_set_cookie(const char *s)
956    {
957      bool ok = true;
958      int r;
959      const char *semi = strchr(s, ';');
960      const char *s2;
961      struct tm tm;
962      double diff;
963      time_t time0, time1;
964      regmatch_t pmatch[20];
965    
966      if (semi)
967        s2 = strndup(s, semi - s);
968      else
969        s2 = s;
970    
971      r = regexec(&re_cookie_nameval, s2, 0, 0, 0);
972      if (r) {
973        lookup("cookiebadnameval");
974        ok = false;
975      }
976      
977      if (!semi)
978        return;
979    
980      s = skip_lws(semi + 1);
981    
982      while (*s) {
983        semi = strchr(s, ';');
984        if (semi)
985          s2 = strndup(s, semi - s);
986        else
987          s2 = s;
988    
989        if (strncmp(s2, "expires=", 8) == 0) {
990          s2 += 8;
991          r = regexec(&re_cookie_expires, s2, 20, pmatch, 0);
992          if (r == 0) {
993            tm.tm_mday = atoi(s2 + pmatch[2].rm_so);
994            tm.tm_mon = month(s2 + pmatch[3].rm_so);
995            tm.tm_year = atoi(s2 + pmatch[4].rm_so) - 1900;
996            tm.tm_hour = atoi(s2 + pmatch[5].rm_so);
997            tm.tm_min = atoi(s2 + pmatch[6].rm_so);
998            tm.tm_sec = atoi(s2 + pmatch[7].rm_so);
999    
1000            time0 = time(0);
1001            time1 = mktime_from_utc(&tm);
1002    
1003            diff = difftime(time0, time1);
1004            if (10 < diff) {
1005              lookup("cookiepastdate");
1006              ok = false;
1007            }
1008          } else {
1009            lookup("cookiebaddate");
1010            ok = false;
1011          }
1012        } else if (strncmp(s2, "domain=", 7) == 0) {
1013        } else if (strncmp(s2, "path=", 5) == 0) {
1014          if (s2[5] != '/') {
1015            lookup("cookiebadpath");
1016            ok = false;
1017          }
1018        } else if (strcmp(s, "secure") == 0) {
1019        } else {
1020          printf("    Set-Cookie field '%s':\n", s2);
1021          lookup("cookieunknownfield");
1022          ok = false;
1023        }
1024    
1025        if (semi)
1026          s = skip_lws(semi + 1);
1027        else
1028          break;
1029      }
1030    
1031      if (ok)
1032        lookup("ok");
1033    }
1034    
1035    
1036  /**  /**
1037   * Print an error message and exit.   * Print an error message and exit.
# Line 1045  struct message_entry { Line 1136  struct message_entry {
1136                    "of header names, or \"*\"." },                    "of header names, or \"*\"." },
1137    { "contentrange", "Warning: The Content-Range header should not be returned "    { "contentrange", "Warning: The Content-Range header should not be returned "
1138                      "by the server for this request." },                      "by the server for this request." },
1139      { "cookiebaddate", "Error: The expires date must be in the form "
1140                         "\"Wdy, DD-Mon-YYYY HH:MM:SS GMT\"." },
1141      { "cookiebadnameval", "Error: A Set-Cookie header must start with "
1142                            "name=value, each excluding semi-colon, comma and "
1143                            "white space." },
1144      { "cookiebadpath", "Error: The path does not start with \"/\"." },
1145      { "cookiepastdate", "Warning: The expires date is in the past. The cookie "
1146                          "will be deleted by browsers." },
1147      { "cookieunknownfield", "Warning: This is not a standard Set-Cookie "
1148                              "field." },
1149    { "futurehttp", "Warning: I only understand HTTP/1.1. Check for a newer "    { "futurehttp", "Warning: I only understand HTTP/1.1. Check for a newer "
1150                    "version of this tool." },                    "version of this tool." },
1151    { "futurelastmod", "Error: The specified Last-Modified date-time is in "    { "futurelastmod", "Error: The specified Last-Modified date-time is in "

Legend:
Removed from v.47  
changed lines
  Added in v.48

  ViewVC Help
Powered by ViewVC 1.1.26