Remove some chars from tokens[] per RFC.

- Treat ' ' specially, as apparently IIS6.0 can send this in headers.
  Allow this character through if we're not in strict mode.
- Move some test code around so that test indices don't break when
  HTTP_PARSER_STRICT changes.

Fixes #13.
v0.10
Peter Griess 13 years ago
parent b47c44d7a6
commit 48a4364fdd

@ -133,9 +133,9 @@ static const char tokens[256] = {
/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */
' ', '!', '"', '#', '$', '%', '&', '\'', 0, '!', 0, '#', '$', '%', '&', '\'',
/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */
0, 0, '*', '+', 0, '-', '.', '/', 0, 0, '*', '+', 0, '-', '.', 0,
/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */
'0', '1', '2', '3', '4', '5', '6', '7', '0', '1', '2', '3', '4', '5', '6', '7',
/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */
@ -155,7 +155,7 @@ static const char tokens[256] = {
/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
'x', 'y', 'z', 0, '|', '}', '~', 0 }; 'x', 'y', 'z', 0, '|', 0, '~', 0 };
static const int8_t unhex[256] = static const int8_t unhex[256] =
@ -311,15 +311,16 @@ enum header_states
#define CR '\r' #define CR '\r'
#define LF '\n' #define LF '\n'
#define LOWER(c) (unsigned char)(c | 0x20) #define LOWER(c) (unsigned char)(c | 0x20)
#define TOKEN(c) (tokens[(unsigned char)c])
#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') #define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z')
#define IS_NUM(c) ((c) >= '0' && (c) <= '9') #define IS_NUM(c) ((c) >= '0' && (c) <= '9')
#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c))
#if HTTP_PARSER_STRICT #if HTTP_PARSER_STRICT
#define TOKEN(c) (tokens[(unsigned char)c])
#define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)]) #define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)])
#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') #define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
#else #else
#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c])
#define IS_URL_CHAR(c) \ #define IS_URL_CHAR(c) \
(normal_url_char[(unsigned char) (c)] || ((c) & 0x80)) (normal_url_char[(unsigned char) (c)] || ((c) & 0x80))
#define IS_HOST_CHAR(c) \ #define IS_HOST_CHAR(c) \

147
test.c

@ -593,29 +593,35 @@ const struct message requests[] =
,.body= "" ,.body= ""
} }
#if !HTTP_PARSER_STRICT #define PATCH_REQ 24
#define UTF8_PATH_REQ 24 , {.name = "PATCH request"
, {.name= "utf-8 path request"
,.type= HTTP_REQUEST ,.type= HTTP_REQUEST
,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n" ,.raw= "PATCH /file.txt HTTP/1.1\r\n"
"Host: github.com\r\n" "Host: www.example.com\r\n"
"Content-Type: application/example\r\n"
"If-Match: \"e0023aa4e\"\r\n"
"Content-Length: 10\r\n"
"\r\n" "\r\n"
"cccccccccc"
,.should_keep_alive= TRUE ,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE ,.message_complete_on_eof= FALSE
,.http_major= 1 ,.http_major= 1
,.http_minor= 1 ,.http_minor= 1
,.method= HTTP_GET ,.method= HTTP_PATCH
,.request_url= "/δ¶/δt/pope?q=1#narf" ,.request_url= "/file.txt"
,.num_headers= 1 ,.num_headers= 4
,.headers= { {"Host", "github.com" } ,.headers= { { "Host", "www.example.com" }
, { "Content-Type", "application/example" }
, { "If-Match", "\"e0023aa4e\"" }
, { "Content-Length", "10" }
} }
,.body= "" ,.body= "cccccccccc"
} }
#define HOSTNAME_UNDERSCORE 25 #define CONNECT_CAPS_REQUEST 25
, {.name = "hostname underscore" , {.name = "connect caps request"
,.type= HTTP_REQUEST ,.type= HTTP_REQUEST
,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n" ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n"
"User-agent: Mozilla/1.1N\r\n" "User-agent: Mozilla/1.1N\r\n"
"Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
"\r\n" "\r\n"
@ -624,7 +630,7 @@ const struct message requests[] =
,.http_major= 1 ,.http_major= 1
,.http_minor= 0 ,.http_minor= 0
,.method= HTTP_CONNECT ,.method= HTTP_CONNECT
,.request_url= "home_0.netscape.com:443" ,.request_url= "HOME0.NETSCAPE.COM:443"
,.num_headers= 2 ,.num_headers= 2
,.upgrade="" ,.upgrade=""
,.headers= { { "User-agent", "Mozilla/1.1N" } ,.headers= { { "User-agent", "Mozilla/1.1N" }
@ -632,37 +638,30 @@ const struct message requests[] =
} }
,.body= "" ,.body= ""
} }
#endif /* !HTTP_PARSER_STRICT */
#define PATCH_REQ 26 #if !HTTP_PARSER_STRICT
, {.name = "PATCH request" #define UTF8_PATH_REQ 26
, {.name= "utf-8 path request"
,.type= HTTP_REQUEST ,.type= HTTP_REQUEST
,.raw= "PATCH /file.txt HTTP/1.1\r\n" ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n"
"Host: www.example.com\r\n" "Host: github.com\r\n"
"Content-Type: application/example\r\n"
"If-Match: \"e0023aa4e\"\r\n"
"Content-Length: 10\r\n"
"\r\n" "\r\n"
"cccccccccc"
,.should_keep_alive= TRUE ,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE ,.message_complete_on_eof= FALSE
,.http_major= 1 ,.http_major= 1
,.http_minor= 1 ,.http_minor= 1
,.method= HTTP_PATCH ,.method= HTTP_GET
,.request_url= "/file.txt" ,.request_url= "/δ¶/δt/pope?q=1#narf"
,.num_headers= 4 ,.num_headers= 1
,.headers= { { "Host", "www.example.com" } ,.headers= { {"Host", "github.com" }
, { "Content-Type", "application/example" }
, { "If-Match", "\"e0023aa4e\"" }
, { "Content-Length", "10" }
} }
,.body= "cccccccccc" ,.body= ""
} }
#define CONNECT_CAPS_REQUEST 27 #define HOSTNAME_UNDERSCORE 27
, {.name = "connect caps request" , {.name = "hostname underscore"
,.type= HTTP_REQUEST ,.type= HTTP_REQUEST
,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n" ,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n"
"User-agent: Mozilla/1.1N\r\n" "User-agent: Mozilla/1.1N\r\n"
"Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n"
"\r\n" "\r\n"
@ -671,7 +670,7 @@ const struct message requests[] =
,.http_major= 1 ,.http_major= 1
,.http_minor= 0 ,.http_minor= 0
,.method= HTTP_CONNECT ,.method= HTTP_CONNECT
,.request_url= "HOME0.NETSCAPE.COM:443" ,.request_url= "home_0.netscape.com:443"
,.num_headers= 2 ,.num_headers= 2
,.upgrade="" ,.upgrade=""
,.headers= { { "User-agent", "Mozilla/1.1N" } ,.headers= { { "User-agent", "Mozilla/1.1N" }
@ -679,6 +678,7 @@ const struct message requests[] =
} }
,.body= "" ,.body= ""
} }
#endif /* !HTTP_PARSER_STRICT */
, {.name= NULL } /* sentinel */ , {.name= NULL } /* sentinel */
}; };
@ -945,40 +945,7 @@ const struct message responses[] =
,.body= "" ,.body= ""
} }
#define SPACE_IN_FIELD_RES 9 #define RES_FIELD_UNDERSCORE 9
/* Should handle spaces in header fields */
, {.name= "field space"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Server: Microsoft-IIS/6.0\r\n"
"X-Powered-By: ASP.NET\r\n"
"en-US Content-Type: text/xml\r\n" /* this is the problem */
"Content-Type: text/xml\r\n"
"Content-Length: 16\r\n"
"Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
"Connection: keep-alive\r\n"
"\r\n"
"<xml>hello</xml>" /* fake body */
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.num_headers= 7
,.headers=
{ { "Server", "Microsoft-IIS/6.0" }
, { "X-Powered-By", "ASP.NET" }
, { "en-US Content-Type", "text/xml" }
, { "Content-Type", "text/xml" }
, { "Content-Length", "16" }
, { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
, { "Connection", "keep-alive" }
}
,.body= "<xml>hello</xml>"
}
#define RES_FIELD_UNDERSCORE 10
/* Should handle spaces in header fields */ /* Should handle spaces in header fields */
, {.name= "field underscore" , {.name= "field underscore"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
@ -1018,7 +985,7 @@ const struct message responses[] =
,.body= "" ,.body= ""
} }
#define NON_ASCII_IN_STATUS_LINE 11 #define NON_ASCII_IN_STATUS_LINE 10
/* Should handle non-ASCII in status line */ /* Should handle non-ASCII in status line */
, {.name= "non-ASCII in status line" , {.name= "non-ASCII in status line"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
@ -1041,7 +1008,7 @@ const struct message responses[] =
,.body= "" ,.body= ""
} }
#define HTTP_VERSION_0_9 12 #define HTTP_VERSION_0_9 11
/* Should handle HTTP/0.9 */ /* Should handle HTTP/0.9 */
, {.name= "http version 0.9" , {.name= "http version 0.9"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
@ -1058,7 +1025,7 @@ const struct message responses[] =
,.body= "" ,.body= ""
} }
#define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 13 #define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12
/* The client should wait for the server's EOF. That is, when neither /* The client should wait for the server's EOF. That is, when neither
* content-length nor transfer-encoding is specified, the end of body * content-length nor transfer-encoding is specified, the end of body
* is specified by the EOF. * is specified by the EOF.
@ -1081,7 +1048,7 @@ const struct message responses[] =
,.body= "hello world" ,.body= "hello world"
} }
#define NO_HEADERS_NO_BODY_204 14 #define NO_HEADERS_NO_BODY_204 13
, {.name= "204 no headers no body" , {.name= "204 no headers no body"
,.type= HTTP_RESPONSE ,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 204 No Content\r\n\r\n" ,.raw= "HTTP/1.1 204 No Content\r\n\r\n"
@ -1096,6 +1063,40 @@ const struct message responses[] =
,.body= "" ,.body= ""
} }
#if !HTTP_PARSER_STRICT
#define SPACE_IN_FIELD_RES 14
/* Should handle spaces in header fields */
, {.name= "field space"
,.type= HTTP_RESPONSE
,.raw= "HTTP/1.1 200 OK\r\n"
"Server: Microsoft-IIS/6.0\r\n"
"X-Powered-By: ASP.NET\r\n"
"en-US Content-Type: text/xml\r\n" /* this is the problem */
"Content-Type: text/xml\r\n"
"Content-Length: 16\r\n"
"Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n"
"Connection: keep-alive\r\n"
"\r\n"
"<xml>hello</xml>" /* fake body */
,.should_keep_alive= TRUE
,.message_complete_on_eof= FALSE
,.http_major= 1
,.http_minor= 1
,.status_code= 200
,.num_headers= 7
,.headers=
{ { "Server", "Microsoft-IIS/6.0" }
, { "X-Powered-By", "ASP.NET" }
, { "en-US Content-Type", "text/xml" }
, { "Content-Type", "text/xml" }
, { "Content-Length", "16" }
, { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" }
, { "Connection", "keep-alive" }
}
,.body= "<xml>hello</xml>"
}
#endif /* !HTTP_PARSER_STRICT */
, {.name= NULL } /* sentinel */ , {.name= NULL } /* sentinel */
}; };

Loading…
Cancel
Save