--- httplint/httplint.c 2004/03/11 19:05:02 55 +++ httplint/httplint.c 2004/03/12 21:54:02 56 @@ -32,6 +32,7 @@ bool start; +bool html = false; CURL *curl; int status_code; char error_buffer[CURL_ERROR_SIZE]; @@ -83,8 +84,6 @@ void header_via(const char *s); void header_set_cookie(const char *s); void die(const char *error); -void warning(const char *message); -void error(const char *message); void print(const char *s, size_t len); void lookup(const char *key); @@ -129,14 +128,19 @@ */ int main(int argc, char *argv[]) { - int i; + int i = 1; if (argc < 2) - die("Usage: httplint url [url ...]"); + die("Usage: httplint [--html] url [url ...]"); init(); - for (i = 1; i != argc; i++) + if (1 < argc && strcmp(argv[1], "--html") == 0) { + html = true; + i++; + } + + for (; i != argc; i++) check_url(argv[i]); curl_global_cleanup(); @@ -263,19 +267,39 @@ for (i = 0; i != sizeof header_table / sizeof header_table[0]; i++) header_table[i].count = 0; - printf("Checking URL %s\n", url); - if (strncmp(url, "http", 4)) - warning("this is not an http or https url"); + if (!html) + printf("Checking URL %s\n", url); + if (strncmp(url, "http", 4)) { + if (html) + printf("

"); + printf("Warning: this is not an http or https url"); + if (html) + printf("

"); + printf("\n"); + } if (curl_easy_setopt(curl, CURLOPT_URL, url)) die("Failed to set curl options"); + if (html) + printf("\n"); if (code != CURLE_OK && code != CURLE_WRITE_ERROR) { - error(error_buffer); + if (html) + printf("

"); + printf("Error: "); + print(error_buffer, strlen(error_buffer)); + printf("."); + if (html) + printf("

"); + printf("\n"); return; } else { printf("\n"); + if (html) + printf(""); } @@ -298,16 +325,20 @@ UNUSED(stream); - printf("* "); + printf(html ? "
  • " : "* "); print(ptr, size); - printf("\n"); + printf(html ? "
  • \n"); return size; } if (sizeof s <= size) { - warning("header too long: ignored\n"); + lookup("headertoolong"); + if (html) + printf("\n"); return size; } strncpy(s, ptr, size); @@ -318,7 +349,9 @@ if (s[0] == 0) { /* empty header indicates end of headers */ - puts("End of headers."); + lookup("endofheaders"); + if (html) + printf("\n"); return 0; } else if (start) { @@ -336,6 +369,8 @@ check_header(name, skip_lws(value)); } + if (html) + printf("\n"); return size; } @@ -567,7 +602,11 @@ do { r = regexec(preg, s, 20, pmatch, 0); if (r) { + if (html) + printf("
  • "); printf(" Failed to match list item %i\n", items + 1); + if (html) + printf("
  • \n"); return false; } @@ -580,7 +619,11 @@ if (*s == 0) break; if (*s != ',') { + if (html) + printf("
  • "); printf(" Expecting , after list item %i\n", items); + if (html) + printf("
  • \n"); return false; } while (*s == ',') @@ -588,11 +631,15 @@ } while (*s != 0); if (items < n || m < items) { + if (html) + printf("
  • "); printf(" %i items in list, but there should be ", items); if (m == UINT_MAX) printf("at least %i\n", n); else printf("between %i and %i\n", n, m); + if (html) + printf("
  • \n"); return false; } @@ -662,7 +709,13 @@ (int (*)(const void *, const void *)) strcasecmp); if (!dir) { - printf(" Cache-Control directive '%s':\n", name); + if (html) + printf("
  • "); + printf(" Cache-Control directive '"); + print(name, strlen(name)); + printf("':\n"); + if (html) + printf("
  • \n"); lookup("unknowncachecont"); } } @@ -707,7 +760,11 @@ sizeof content_coding_list[0], (int (*)(const void *, const void *)) strcasecmp); if (!dir) { + if (html) + printf("
  • "); printf(" Content-Encoding '%s':\n", name); + if (html) + printf("
  • \n"); lookup("unknowncontenc"); } } @@ -922,7 +979,11 @@ sizeof transfer_coding_list[0], (int (*)(const void *, const void *)) strcasecmp); if (!dir) { + if (html) + printf("
  • "); printf(" Transfer-Encoding '%s':\n", name); + if (html) + printf("
  • \n"); lookup("unknowntransenc"); } } @@ -986,7 +1047,7 @@ else s2 = s; - if (strncmp(s2, "expires=", 8) == 0) { + if (strncasecmp(s2, "expires=", 8) == 0) { s2 += 8; r = regexec(&re_cookie_expires, s2, 20, pmatch, 0); if (r == 0) { @@ -1009,15 +1070,19 @@ lookup("cookiebaddate"); ok = false; } - } else if (strncmp(s2, "domain=", 7) == 0) { - } else if (strncmp(s2, "path=", 5) == 0) { + } else if (strncasecmp(s2, "domain=", 7) == 0) { + } else if (strncasecmp(s2, "path=", 5) == 0) { if (s2[5] != '/') { lookup("cookiebadpath"); ok = false; } - } else if (strcmp(s, "secure") == 0) { + } else if (strcasecmp(s, "secure") == 0) { } else { + if (html) + printf("
  • "); printf(" Set-Cookie field '%s':\n", s2); + if (html) + printf("
  • \n"); lookup("cookieunknownfield"); ok = false; } @@ -1044,34 +1109,27 @@ /** - * Print a warning message. - */ -void warning(const char *message) -{ - printf("Warning: %s\n", message); -} - - -/** - * Print an error message. - */ -void error(const char *message) -{ - printf("Error: %s\n", message); -} - - -/** * Print a string which contains control characters. */ void print(const char *s, size_t len) { size_t i; for (i = 0; i != len; i++) { - if (31 < s[i] && s[i] < 127) + if (html && s[i] == '<') + printf("<"); + else if (html && s[i] == '>') + printf(">"); + else if (html && s[i] == '&') + printf("&"); + else if (31 < s[i] && s[i] < 127) putchar(s[i]); - else + else { + if (html) + printf(""); printf("[%.2x]", s[i]); + if (html) + printf(""); + } } } @@ -1146,10 +1204,12 @@ "will be deleted by browsers." }, { "cookieunknownfield", "Warning: This is not a standard Set-Cookie " "field." }, + { "endofheaders", "End of headers." }, { "futurehttp", "Warning: I only understand HTTP/1.1. Check for a newer " "version of this tool." }, { "futurelastmod", "Error: The specified Last-Modified date-time is in " "the future." }, + { "headertoolong", "Warning: Header too long: ignored." }, { "missingcolon", "Error: Headers must be of the form 'Name: value'." }, { "missingcontenttype", "Warning: No Content-Type header was present. The " "client will have to guess the media type or ask " @@ -1213,22 +1273,49 @@ else s = key; - printf(" "); - x = 4; - while (*s) { - spc = strchr(s, ' '); - if (!spc) - spc = s + strlen(s); - if (75 < x + (spc - s)) { - printf("\n "); - x = 4; - } - x += spc - s + 1; - printf("%.*s ", spc - s, s); - if (*spc) - s = spc + 1; + if (html) { + if (strncmp(s, "Warning:", 8) == 0) + printf("
  • "); + else if (strncmp(s, "Error:", 6) == 0) + printf("
  • "); + else if (strncmp(s, "OK", 2) == 0) + printf("
  • "); else - s = spc; + printf("
  • "); + for (; *s; s++) { + if (strncmp(s, "http://", 7) == 0) { + spc = strchr(s, ' '); + printf("%.*s", spc - s, s, spc - s, s); + s = spc; + } + switch (*s) { + case '<': printf("<"); break; + case '>': printf(">"); break; + case '&': printf("&"); break; + default: printf("%c", *s); break; + } + } + printf("
  • \n"); + + } else { + printf(" "); + x = 4; + while (*s) { + spc = strchr(s, ' '); + if (!spc) + spc = s + strlen(s); + if (75 < x + (spc - s)) { + printf("\n "); + x = 4; + } + x += spc - s + 1; + printf("%.*s ", spc - s, s); + if (*spc) + s = spc + 1; + else + s = spc; + } + printf("\n\n"); } - printf("\n\n"); } +