Update http-parser to f2c26ee500ab3921010fa7ec66243365611e77dd
This commit is contained in:
parent
046ec307c3
commit
631f977236
|
@ -1812,6 +1812,9 @@ reexecute:
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
parser->upgrade = 1;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
parser->flags |= F_SKIPBODY;
|
parser->flags |= F_SKIPBODY;
|
||||||
break;
|
break;
|
||||||
|
@ -2250,12 +2253,13 @@ http_parse_host_char(enum http_host_state s, const char ch) {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
|
http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
|
||||||
assert(u->field_set & (1 << UF_HOST));
|
|
||||||
enum http_host_state s;
|
enum http_host_state s;
|
||||||
|
|
||||||
const char *p;
|
const char *p;
|
||||||
size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
|
size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
|
||||||
|
|
||||||
|
assert(u->field_set & (1 << UF_HOST));
|
||||||
|
|
||||||
u->field_data[UF_HOST].len = 0;
|
u->field_data[UF_HOST].len = 0;
|
||||||
|
|
||||||
s = found_at ? s_http_userinfo_start : s_http_host_start;
|
s = found_at ? s_http_userinfo_start : s_http_host_start;
|
||||||
|
|
|
@ -26,8 +26,8 @@ extern "C" {
|
||||||
|
|
||||||
/* Also update SONAME in the Makefile whenever you change these. */
|
/* Also update SONAME in the Makefile whenever you change these. */
|
||||||
#define HTTP_PARSER_VERSION_MAJOR 2
|
#define HTTP_PARSER_VERSION_MAJOR 2
|
||||||
#define HTTP_PARSER_VERSION_MINOR 6
|
#define HTTP_PARSER_VERSION_MINOR 7
|
||||||
#define HTTP_PARSER_VERSION_PATCH 2
|
#define HTTP_PARSER_VERSION_PATCH 0
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#if defined(_WIN32) && !defined(__MINGW32__) && \
|
#if defined(_WIN32) && !defined(__MINGW32__) && \
|
||||||
|
@ -77,6 +77,11 @@ typedef struct http_parser_settings http_parser_settings;
|
||||||
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
|
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
|
||||||
* chunked' headers that indicate the presence of a body.
|
* chunked' headers that indicate the presence of a body.
|
||||||
*
|
*
|
||||||
|
* Returning `2` from on_headers_complete will tell parser that it should not
|
||||||
|
* expect neither a body nor any futher responses on this connection. This is
|
||||||
|
* useful for handling responses to a CONNECT request which may not contain
|
||||||
|
* `Upgrade` or `Connection: upgrade` headers.
|
||||||
|
*
|
||||||
* http_data_cb does not return data chunks. It will be called arbitrarily
|
* http_data_cb does not return data chunks. It will be called arbitrarily
|
||||||
* many times for each string. E.G. you might get 10 callbacks for "on_url"
|
* many times for each string. E.G. you might get 10 callbacks for "on_url"
|
||||||
* each providing just a few characters more data.
|
* each providing just a few characters more data.
|
||||||
|
|
|
@ -2173,6 +2173,20 @@ pause_chunk_complete_cb (http_parser *p)
|
||||||
return chunk_complete_cb(p);
|
return chunk_complete_cb(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
connect_headers_complete_cb (http_parser *p)
|
||||||
|
{
|
||||||
|
headers_complete_cb(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
connect_message_complete_cb (http_parser *p)
|
||||||
|
{
|
||||||
|
messages[num_messages].should_keep_alive = http_should_keep_alive(parser);
|
||||||
|
return message_complete_cb(p);
|
||||||
|
}
|
||||||
|
|
||||||
static http_parser_settings settings_pause =
|
static http_parser_settings settings_pause =
|
||||||
{.on_message_begin = pause_message_begin_cb
|
{.on_message_begin = pause_message_begin_cb
|
||||||
,.on_header_field = pause_header_field_cb
|
,.on_header_field = pause_header_field_cb
|
||||||
|
@ -2212,6 +2226,19 @@ static http_parser_settings settings_count_body =
|
||||||
,.on_chunk_complete = chunk_complete_cb
|
,.on_chunk_complete = chunk_complete_cb
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static http_parser_settings settings_connect =
|
||||||
|
{.on_message_begin = message_begin_cb
|
||||||
|
,.on_header_field = header_field_cb
|
||||||
|
,.on_header_value = header_value_cb
|
||||||
|
,.on_url = request_url_cb
|
||||||
|
,.on_status = response_status_cb
|
||||||
|
,.on_body = dontcall_body_cb
|
||||||
|
,.on_headers_complete = connect_headers_complete_cb
|
||||||
|
,.on_message_complete = connect_message_complete_cb
|
||||||
|
,.on_chunk_header = chunk_header_cb
|
||||||
|
,.on_chunk_complete = chunk_complete_cb
|
||||||
|
};
|
||||||
|
|
||||||
static http_parser_settings settings_null =
|
static http_parser_settings settings_null =
|
||||||
{.on_message_begin = 0
|
{.on_message_begin = 0
|
||||||
,.on_header_field = 0
|
,.on_header_field = 0
|
||||||
|
@ -2275,6 +2302,14 @@ size_t parse_pause (const char *buf, size_t len)
|
||||||
return nparsed;
|
return nparsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t parse_connect (const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t nparsed;
|
||||||
|
currently_parsing_eof = (len == 0);
|
||||||
|
nparsed = http_parser_execute(parser, &settings_connect, buf, len);
|
||||||
|
return nparsed;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
check_str_eq (const struct message *m,
|
check_str_eq (const struct message *m,
|
||||||
const char *prop,
|
const char *prop,
|
||||||
|
@ -2331,7 +2366,7 @@ do { \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
int
|
int
|
||||||
message_eq (int index, const struct message *expected)
|
message_eq (int index, int connect, const struct message *expected)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct message *m = &messages[index];
|
struct message *m = &messages[index];
|
||||||
|
@ -2346,8 +2381,10 @@ message_eq (int index, const struct message *expected)
|
||||||
MESSAGE_CHECK_STR_EQ(expected, m, response_status);
|
MESSAGE_CHECK_STR_EQ(expected, m, response_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive);
|
if (!connect) {
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof);
|
MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive);
|
||||||
|
MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof);
|
||||||
|
}
|
||||||
|
|
||||||
assert(m->message_begin_cb_called);
|
assert(m->message_begin_cb_called);
|
||||||
assert(m->headers_complete_cb_called);
|
assert(m->headers_complete_cb_called);
|
||||||
|
@ -2385,16 +2422,22 @@ message_eq (int index, const struct message *expected)
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, port);
|
MESSAGE_CHECK_NUM_EQ(expected, m, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expected->body_size) {
|
if (connect) {
|
||||||
|
check_num_eq(m, "body_size", 0, m->body_size);
|
||||||
|
} else if (expected->body_size) {
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, body_size);
|
MESSAGE_CHECK_NUM_EQ(expected, m, body_size);
|
||||||
} else {
|
} else {
|
||||||
MESSAGE_CHECK_STR_EQ(expected, m, body);
|
MESSAGE_CHECK_STR_EQ(expected, m, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(m->num_chunks == m->num_chunks_complete);
|
if (connect) {
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks_complete);
|
check_num_eq(m, "num_chunks_complete", 0, m->num_chunks_complete);
|
||||||
for (i = 0; i < m->num_chunks && i < MAX_CHUNKS; i++) {
|
} else {
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, chunk_lengths[i]);
|
assert(m->num_chunks == m->num_chunks_complete);
|
||||||
|
MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks_complete);
|
||||||
|
for (i = 0; i < m->num_chunks && i < MAX_CHUNKS; i++) {
|
||||||
|
MESSAGE_CHECK_NUM_EQ(expected, m, chunk_lengths[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MESSAGE_CHECK_NUM_EQ(expected, m, num_headers);
|
MESSAGE_CHECK_NUM_EQ(expected, m, num_headers);
|
||||||
|
@ -3201,7 +3244,7 @@ test_message (const struct message *message)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!message_eq(0, message)) abort();
|
if(!message_eq(0, 0, message)) abort();
|
||||||
|
|
||||||
parser_free();
|
parser_free();
|
||||||
}
|
}
|
||||||
|
@ -3238,7 +3281,7 @@ test_message_count_body (const struct message *message)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!message_eq(0, message)) abort();
|
if(!message_eq(0, 0, message)) abort();
|
||||||
|
|
||||||
parser_free();
|
parser_free();
|
||||||
}
|
}
|
||||||
|
@ -3589,9 +3632,9 @@ test:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message_eq(0, r1)) abort();
|
if (!message_eq(0, 0, r1)) abort();
|
||||||
if (message_count > 1 && !message_eq(1, r2)) abort();
|
if (message_count > 1 && !message_eq(1, 0, r2)) abort();
|
||||||
if (message_count > 2 && !message_eq(2, r3)) abort();
|
if (message_count > 2 && !message_eq(2, 0, r3)) abort();
|
||||||
|
|
||||||
parser_free();
|
parser_free();
|
||||||
}
|
}
|
||||||
|
@ -3687,17 +3730,17 @@ test:
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message_eq(0, r1)) {
|
if (!message_eq(0, 0, r1)) {
|
||||||
fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n");
|
fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message_count > 1 && !message_eq(1, r2)) {
|
if (message_count > 1 && !message_eq(1, 0, r2)) {
|
||||||
fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n");
|
fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message_count > 2 && !message_eq(2, r3)) {
|
if (message_count > 2 && !message_eq(2, 0, r3)) {
|
||||||
fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n");
|
fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -3796,7 +3839,29 @@ test:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!message_eq(0, msg)) abort();
|
if(!message_eq(0, 0, msg)) abort();
|
||||||
|
|
||||||
|
parser_free();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify that body and next message won't be parsed in responses to CONNECT */
|
||||||
|
void
|
||||||
|
test_message_connect (const struct message *msg)
|
||||||
|
{
|
||||||
|
char *buf = (char*) msg->raw;
|
||||||
|
size_t buflen = strlen(msg->raw);
|
||||||
|
size_t nread;
|
||||||
|
|
||||||
|
parser_init(msg->type);
|
||||||
|
|
||||||
|
nread = parse_connect(buf, buflen);
|
||||||
|
|
||||||
|
if (num_messages != 1) {
|
||||||
|
printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!message_eq(0, 1, msg)) abort();
|
||||||
|
|
||||||
parser_free();
|
parser_free();
|
||||||
}
|
}
|
||||||
|
@ -3867,6 +3932,10 @@ main (void)
|
||||||
test_message_pause(&responses[i]);
|
test_message_pause(&responses[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < response_count; i++) {
|
||||||
|
test_message_connect(&responses[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < response_count; i++) {
|
for (i = 0; i < response_count; i++) {
|
||||||
if (!responses[i].should_keep_alive) continue;
|
if (!responses[i].should_keep_alive) continue;
|
||||||
for (j = 0; j < response_count; j++) {
|
for (j = 0; j < response_count; j++) {
|
||||||
|
|
Loading…
Reference in New Issue