Created
February 14, 2020 00:35
-
-
Save sam-github/ef76356f58acc36c4066aa8b105d1133 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- ../http-parser/test.c 2020-02-13 15:17:21.151617855 -0800 | |
+++ test/compat/compat.c 2020-02-13 16:24:50.336415270 -0800 | |
@@ -47,6 +47,7 @@ | |
struct message { | |
const char *name; // for debugging purposes | |
+ int skip; // Test fails compatibility | |
const char *raw; | |
enum http_parser_type type; | |
enum http_method method; | |
@@ -262,8 +263,8 @@ | |
,.type= HTTP_REQUEST | |
,.raw= "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n" | |
"Accept: */*\r\n" | |
- "Content-Length: \r\n" | |
- " 5\r\n" | |
+ "Content-Length: 5\r\n" | |
+ "\r\n" | |
"World" | |
,.should_keep_alive= TRUE | |
,.message_complete_on_eof= FALSE | |
@@ -810,7 +811,7 @@ | |
/* see https://github.com/ry/http-parser/issues/47 */ | |
#define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29 | |
-, {.name = "eat CRLF between requests, no \"Connection: close\" header" | |
+, {.name = "eat CRLF between requests, no \"Connection: close\" header", .skip = 1 // INCOMPAT llhttp dislikes the trailing CRLF? | |
,.raw= "POST / HTTP/1.1\r\n" | |
"Host: www.example.com\r\n" | |
"Content-Type: application/x-www-form-urlencoded\r\n" | |
@@ -837,7 +838,7 @@ | |
/* see https://github.com/ry/http-parser/issues/47 */ | |
#define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30 | |
-, {.name = "eat CRLF between requests even if \"Connection: close\" is set" | |
+, {.name = "eat CRLF between requests even if \"Connection: close\" is set", .skip = 1 // INCOMPAT llhttp dislikes the trailing CRLF? | |
,.raw= "POST / HTTP/1.1\r\n" | |
"Host: www.example.com\r\n" | |
"Content-Type: application/x-www-form-urlencoded\r\n" | |
@@ -1220,7 +1221,7 @@ | |
} | |
#define POST_MULTI_LINE_TE_LAST_CHUNKED 44 | |
-, {.name= "post - multi line coding transfer-encoding chunked body" | |
+, {.name= "post - multi line coding transfer-encoding chunked body", .skip = 1 // INCOMPAT, llhttp doesn't like the wrapped transfer-encoding header field | |
,.type= HTTP_REQUEST | |
,.raw= "POST / HTTP/1.1\r\n" | |
"Transfer-Encoding: deflate,\r\n" | |
@@ -1360,7 +1361,8 @@ | |
} | |
#define NO_REASON_PHRASE 3 | |
-, {.name= "301 no response phrase" | |
+, {.name= "301 no response phrase", .skip = 1 // INCOMPAT llhttp doesn't call status cb when reason missing | |
+ /* reason phrase is supposed to be ignored, this might be a bug */ | |
,.type= HTTP_RESPONSE | |
,.raw= "HTTP/1.1 301\r\n\r\n" | |
,.should_keep_alive = FALSE | |
@@ -1822,7 +1824,7 @@ | |
} | |
#define EMPTY_REASON_PHRASE_AFTER_SPACE 20 | |
-, {.name= "empty reason phrase after space" | |
+, {.name= "empty reason phrase after space", .skip = 1 // INCOMPAT llhttp doesn't call status cb if reason is missing | |
,.type= HTTP_RESPONSE | |
,.raw= "HTTP/1.1 200 \r\n" | |
"\r\n" | |
@@ -2151,6 +2153,7 @@ | |
void | |
check_body_is_final (const http_parser *p) | |
{ | |
+#if 0 | |
if (messages[num_messages].body_is_final) { | |
fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " | |
"on last on_body callback call " | |
@@ -2159,6 +2162,7 @@ | |
abort(); | |
} | |
messages[num_messages].body_is_final = http_body_is_final(p); | |
+#endif | |
} | |
int | |
@@ -2221,6 +2225,7 @@ | |
abort(); | |
} | |
+#if 0 | |
if (messages[num_messages].body_size && | |
http_body_is_final(p) && | |
!messages[num_messages].body_is_final) | |
@@ -2231,6 +2236,7 @@ | |
assert(0); | |
abort(); | |
} | |
+#endif | |
messages[num_messages].message_complete_cb_called = TRUE; | |
@@ -2616,6 +2622,7 @@ | |
printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); | |
printf("expected %d\n", expected); | |
printf(" found %d\n", found); | |
+ if(m->skip) return 1; | |
return 0; | |
} | |
return 1; | |
@@ -2671,6 +2678,7 @@ | |
MESSAGE_CHECK_STR_EQ(expected, m, request_url); | |
+#if 0 | |
/* Check URL components; we can't do this w/ CONNECT since it doesn't | |
* send us a well-formed URL. | |
*/ | |
@@ -2699,6 +2707,7 @@ | |
MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH); | |
MESSAGE_CHECK_NUM_EQ(expected, m, port); | |
} | |
+#endif | |
if (connect) { | |
check_num_eq(m, "body_size", 0, m->body_size); | |
@@ -2803,7 +2812,11 @@ | |
print_error (const char *raw, size_t error_location) | |
{ | |
fprintf(stderr, "\n*** %s ***\n\n", | |
+#if 0 | |
http_errno_description(HTTP_PARSER_ERRNO(&parser))); | |
+#else | |
+ llhttp_get_error_reason(&parser)); | |
+#endif | |
int this_line = 0, char_len = 0; | |
size_t i, j, len = strlen(raw), error_location_line = 0; | |
@@ -2857,10 +2870,13 @@ | |
const char *name; | |
const char *url; | |
int is_connect; | |
+#if 0 | |
struct http_parser_url u; | |
+#endif | |
int rv; | |
}; | |
+#if 0 | |
const struct url_test url_tests[] = | |
{ {.name="proxy request" | |
,.url="http://hostname/" | |
@@ -3413,7 +3429,9 @@ | |
} | |
#endif | |
}; | |
+#endif | |
+#if 0 | |
void | |
dump_url (const char *url, const struct http_parser_url *u) | |
{ | |
@@ -3434,10 +3452,12 @@ | |
url + u->field_data[i].off); | |
} | |
} | |
+#endif | |
void | |
test_parse_url (void) | |
{ | |
+#if 0 | |
struct http_parser_url u; | |
const struct url_test *test; | |
unsigned int i; | |
@@ -3479,26 +3499,34 @@ | |
} | |
} | |
} | |
+#endif | |
} | |
void | |
test_method_str (void) | |
{ | |
+#if 0 | |
assert(0 == strcmp("GET", http_method_str(HTTP_GET))); | |
assert(0 == strcmp("<unknown>", http_method_str(1337))); | |
+#endif | |
} | |
void | |
test_status_str (void) | |
{ | |
+#if 0 | |
assert(0 == strcmp("OK", http_status_str(HTTP_STATUS_OK))); | |
assert(0 == strcmp("Not Found", http_status_str(HTTP_STATUS_NOT_FOUND))); | |
assert(0 == strcmp("<unknown>", http_status_str(1337))); | |
+#endif | |
} | |
void | |
test_message (const struct message *message) | |
{ | |
+ printf("** test message: %s\n", message->name); | |
+ if (message->skip) { printf("INCOMPATIBLE (skip)\n"); return; } | |
+ | |
size_t raw_len = strlen(message->raw); | |
size_t msg1len; | |
for (msg1len = 0; msg1len < raw_len; msg1len++) { | |
@@ -3515,11 +3543,13 @@ | |
read = parse(msg1, msg1len); | |
+#if 0 | |
if (!messages[0].headers_complete_cb_called && parser.nread != read) { | |
assert(parser.nread == read); | |
print_error(msg1, read); | |
abort(); | |
} | |
+#endif | |
if (message->upgrade && parser.upgrade && num_messages > 0) { | |
messages[num_messages - 1].upgrade = msg1 + read; | |
@@ -3555,7 +3585,8 @@ | |
test: | |
if (num_messages != 1) { | |
- printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); | |
+ printf("\n*** num_messages %d != 1 after testing '%s' ***\n\n", num_messages, message->name); | |
+ if (!message->skip) | |
abort(); | |
} | |
@@ -3715,7 +3746,7 @@ | |
size_t buflen = strlen(buf); | |
parsed = http_parser_execute(&parser, &settings_null, buf, buflen); | |
- if (parsed != buflen) { | |
+ /*if (parsed != buflen)*/ { | |
assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH); | |
return; | |
} | |
@@ -3742,7 +3773,7 @@ | |
size_t buflen = strlen(buf); | |
parsed = http_parser_execute(&parser, &settings_null, buf, buflen); | |
- if (parsed != buflen) { | |
+ /*if (parsed != buflen)*/ { | |
assert(HTTP_PARSER_ERRNO(&parser) == HPE_UNEXPECTED_CONTENT_LENGTH); | |
return; | |
} | |
@@ -3782,6 +3813,7 @@ | |
void | |
test_no_overflow_parse_url (void) | |
{ | |
+#if 0 | |
int rv; | |
struct http_parser_url u; | |
@@ -3801,11 +3833,13 @@ | |
u.port); | |
abort(); | |
} | |
+#endif | |
} | |
void | |
test_header_overflow_error (int req) | |
{ | |
+#if 0 | |
http_parser parser; | |
http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); | |
size_t parsed; | |
@@ -3829,6 +3863,7 @@ | |
fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n"); | |
abort(); | |
+#endif | |
} | |
@@ -3843,7 +3878,9 @@ | |
parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); | |
assert(parsed == strlen(buf)); | |
+#if 0 | |
assert(parser.nread == strlen(buf)); | |
+#endif | |
} | |
@@ -3854,6 +3891,11 @@ | |
http_parser_init(&parser, HTTP_RESPONSE); | |
http_parser_execute(&parser, &settings_null, buf, buflen); | |
+ if (expect_ok == 2) { // INCOMPATIBLE - used to be HPE_INVALID_CONTENT_LENGTH | |
+ if (HTTP_PARSER_ERRNO(&parser) != HPE_INVALID_CHUNK_SIZE) | |
+ printf("errno => %s\n", http_errno_name(HTTP_PARSER_ERRNO(&parser))); | |
+ assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CHUNK_SIZE); | |
+ } else | |
if (expect_ok) | |
assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK); | |
else | |
@@ -3872,7 +3914,7 @@ | |
const char c[] = X(18446744073709551616); /* 2^64 */ | |
#undef X | |
test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ | |
- test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ | |
+ test_content_length_overflow(b, sizeof(b) - 1, 1 /*INCOMPAT, was fail*/); /* expect failure */ | |
test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ | |
} | |
@@ -3890,8 +3932,8 @@ | |
const char c[] = X(10000000000000000); /* 2^64 */ | |
#undef X | |
test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ | |
- test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ | |
- test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ | |
+ test_content_length_overflow(b, sizeof(b) - 1, 1 /*INCOMPAT, was fail*/); /* expect failure */ | |
+ test_content_length_overflow(c, sizeof(c) - 1, 2 /*INCOMPAT, was HPE_INVALID_CONTENT_LENGTH*/); /* expect failure */ | |
} | |
void | |
@@ -4034,10 +4076,12 @@ | |
read = parse(buf1, buf1_len); | |
+#if 0 | |
if (!messages[0].headers_complete_cb_called && parser.nread != read) { | |
print_error(buf1, read); | |
goto error; | |
} | |
+#endif | |
if (parser.upgrade) goto test; | |
@@ -4190,6 +4234,7 @@ | |
void | |
test_message_connect (const struct message *msg) | |
{ | |
+ printf("** test connect response: %s\n", msg->name); | |
char *buf = (char*) msg->raw; | |
size_t buflen = strlen(msg->raw); | |
@@ -4202,6 +4247,7 @@ | |
abort(); | |
} | |
+ if (!msg->skip) | |
if(!message_eq(0, 1, msg)) abort(); | |
} | |
@@ -4214,6 +4260,9 @@ | |
unsigned minor; | |
unsigned patch; | |
+ setvbuf(stdout, NULL, _IOLBF, 0); | |
+ setvbuf(stderr, NULL, _IOLBF, 0); | |
+ | |
version = http_parser_version(); | |
major = (version >> 16) & 255; | |
minor = (version >> 8) & 255; | |
@@ -4289,38 +4338,35 @@ | |
"POST / HTTP/1.1\r\n" | |
"Content-Length: 42\r\n" | |
" Hello world!\r\n", | |
- HPE_INVALID_CONTENT_LENGTH, | |
+ HPE_UNEXPECTED_CONTENT_LENGTH, // INCOMPAT, http-parser says HPE_INVALID_CONTENT_LENGTH, which is slightly more correct | |
HTTP_REQUEST); | |
test_simple_type( | |
"POST / HTTP/1.1\r\n" | |
- "Content-Length:\r\n" | |
- " 42\r\n", | |
- HPE_OK, | |
- HTTP_REQUEST); | |
- | |
- test_simple_type( | |
- "POST / HTTP/1.1\r\n" | |
- "Content-Length:\r\n" | |
- " 42\r\n", | |
- HPE_OK, | |
+ "Content-Length: 42\r\n" | |
+ " \r\n", | |
+ HPE_UNEXPECTED_CONTENT_LENGTH, // INCOMPAT, http-parser accepted, llhttp thinks its an invalid content-length field fold? | |
HTTP_REQUEST); | |
//// RESPONSES | |
- test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); | |
+ test_simple_type("HTP/1.1 200 OK\r\n\r\n", HPE_INVALID_CONSTANT, HTTP_RESPONSE); /* INCOMPAT (but correct) used to be INVALID_VERSION */ | |
test_simple_type("HTTP/01.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); | |
test_simple_type("HTTP/11.1 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); | |
test_simple_type("HTTP/1.01 200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); | |
test_simple_type("HTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); | |
test_simple_type("\rHTTP/1.1\t200 OK\r\n\r\n", HPE_INVALID_VERSION, HTTP_RESPONSE); | |
- for (i = 5; i < ARRAY_SIZE(responses); i++) { | |
+ for (i = 0; i < ARRAY_SIZE(responses); i++) { | |
+ printf("-- test_message(responses[%d])\n", i); | |
test_message(&responses[i]); | |
} | |
for (i = 0; i < ARRAY_SIZE(responses); i++) { | |
- test_message_pause(&responses[i]); | |
+ /* on_status() called on paused parser */ | |
+ /* INCOMPAT? Or a problem with how settings are changed per-execute | |
+ * in old http-parser, but set on init in llhttp? */ | |
+ //test_message_pause(&responses[i]); | |
} | |
for (i = 0; i < ARRAY_SIZE(responses); i++) { | |
@@ -4332,6 +4378,9 @@ | |
for (j = 0; j < ARRAY_SIZE(responses); j++) { | |
if (!responses[j].should_keep_alive) continue; | |
for (k = 0; k < ARRAY_SIZE(responses); k++) { | |
+ printf("** test_multiple3(%d, %d, %d)\n", i, j, k); | |
+ if(responses[i].skip || responses[j].skip || responses[k].skip) | |
+ continue; | |
test_multiple3(&responses[i], &responses[j], &responses[k]); | |
} | |
} | |
@@ -4375,10 +4424,10 @@ | |
printf("response scan 1/2 "); | |
- test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] | |
+ /*test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] | |
, &responses[NO_BODY_HTTP10_KA_204] | |
, &responses[NO_REASON_PHRASE] | |
- ); | |
+ ); aborts, reason TBD */ | |
printf("response scan 2/2 "); | |
test_scan( &responses[BONJOUR_MADAME_FR] | |
@@ -4393,7 +4442,7 @@ | |
test_simple("GET / IHTTP/1.0\r\n\r\n", HPE_INVALID_CONSTANT); | |
test_simple("GET / ICE/1.0\r\n\r\n", HPE_INVALID_CONSTANT); | |
- test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION); | |
+ test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_CONSTANT); /* INCOMPAT (but correct), used to be INVALID_VERSION */ | |
test_simple("GET / HTTP/01.1\r\n\r\n", HPE_INVALID_VERSION); | |
test_simple("GET / HTTP/11.1\r\n\r\n", HPE_INVALID_VERSION); | |
test_simple("GET / HTTP/1.01\r\n\r\n", HPE_INVALID_VERSION); | |
@@ -4563,7 +4612,10 @@ | |
} | |
for (i = 0; i < ARRAY_SIZE(requests); i++) { | |
- test_message_pause(&requests[i]); | |
+ /* on_request_url() called on paused parser */ | |
+ /* INCOMPAT? Or a problem with how settings are changed per-execute | |
+ * in old http-parser, but set on init in llhttp? */ | |
+ //test_message_pause(&requests[i]); | |
} | |
for (i = 0; i < ARRAY_SIZE(requests); i++) { | |
@@ -4571,6 +4623,7 @@ | |
for (j = 0; j < ARRAY_SIZE(requests); j++) { | |
if (!requests[j].should_keep_alive) continue; | |
for (k = 0; k < ARRAY_SIZE(requests); k++) { | |
+ if (requests[i].skip || requests[j].skip || requests[k].skip) continue; | |
test_multiple3(&requests[i], &requests[j], &requests[k]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment