Skip to content
This repository was archived by the owner on Nov 6, 2022. It is now read-only.

Add two hooks to be executed when a chunk is downloaded. #159

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions contrib/parsertrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ int on_message_complete(http_parser* _) {
return 0;
}

int on_chunk_begin(http_parser* _) {
(void)_;
printf("\n***CHUNK BEGIN***\n\n");
return 0;
}

int on_chunk_complete(http_parser* _) {
(void)_;
printf("\n***CHUNK COMPLETE***\n\n");
return 0;
}

int on_url(http_parser* _, const char* at, size_t length) {
(void)_;
printf("Url: %.*s\n", (int)length, at);
Expand Down Expand Up @@ -136,7 +148,9 @@ int main(int argc, char* argv[]) {
settings.on_header_field = on_header_field;
settings.on_header_value = on_header_value;
settings.on_headers_complete = on_headers_complete;
settings.on_chunk_begin = on_chunk_begin;
settings.on_body = on_body;
settings.on_chunk_complete = on_chunk_complete;
settings.on_message_complete = on_message_complete;

http_parser parser;
Expand Down
2 changes: 2 additions & 0 deletions http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1782,6 +1782,7 @@ size_t http_parser_execute (http_parser *parser,
parser->state = s_header_field_start;
} else {
parser->state = s_chunk_data;
CALLBACK_NOTIFY(chunk_begin);
}
break;
}
Expand Down Expand Up @@ -1822,6 +1823,7 @@ size_t http_parser_execute (http_parser *parser,
STRICT_CHECK(ch != LF);
parser->nread = 0;
parser->state = s_chunk_size_start;
CALLBACK_NOTIFY(chunk_complete);
break;

default:
Expand Down
4 changes: 4 additions & 0 deletions http_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ enum flags
XX(CB_header_field, "the on_header_field callback failed") \
XX(CB_header_value, "the on_header_value callback failed") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \
XX(CB_chunk_begin, "the on_chunk_begin callback failed") \
XX(CB_body, "the on_body callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
XX(CB_message_complete, "the on_message_complete callback failed") \
\
/* Parsing-related errors */ \
Expand Down Expand Up @@ -228,7 +230,9 @@ struct http_parser_settings {
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_cb on_chunk_begin;
http_data_cb on_body;
http_cb on_chunk_complete;
http_cb on_message_complete;
};

Expand Down
72 changes: 72 additions & 0 deletions test.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct message {
const char *userinfo;
uint16_t port;
int num_headers;
int num_chunks;
int num_end_chunks;
enum { NONE=0, FIELD, VALUE } last_header_element;
char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE];
int should_keep_alive;
Expand Down Expand Up @@ -290,6 +292,7 @@ const struct message requests[] =
,.request_path= "/post_chunked_all_your_base"
,.request_url= "/post_chunked_all_your_base"
,.num_headers= 1
,.num_chunks= 1
,.headers=
{ { "Transfer-Encoding" , "chunked" }
}
Expand All @@ -316,6 +319,7 @@ const struct message requests[] =
,.request_path= "/two_chunks_mult_zero_end"
,.request_url= "/two_chunks_mult_zero_end"
,.num_headers= 1
,.num_chunks= 2
,.headers=
{ { "Transfer-Encoding", "chunked" }
}
Expand Down Expand Up @@ -344,6 +348,7 @@ const struct message requests[] =
,.request_path= "/chunked_w_trailing_headers"
,.request_url= "/chunked_w_trailing_headers"
,.num_headers= 3
,.num_chunks= 2
,.headers=
{ { "Transfer-Encoding", "chunked" }
, { "Vary", "*" }
Expand Down Expand Up @@ -372,6 +377,7 @@ const struct message requests[] =
,.request_path= "/chunked_w_bullshit_after_length"
,.request_url= "/chunked_w_bullshit_after_length"
,.num_headers= 1
,.num_chunks= 2
,.headers=
{ { "Transfer-Encoding", "chunked" }
}
Expand Down Expand Up @@ -1044,6 +1050,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.num_headers= 2
,.num_chunks= 2
,.headers=
{ {"Content-Type", "text/plain" }
, {"Transfer-Encoding", "chunked" }
Expand Down Expand Up @@ -1187,6 +1194,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.num_headers= 11
,.num_chunks= 0
,.headers=
{ { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" }
, { "Server", "Apache" }
Expand Down Expand Up @@ -1369,6 +1377,7 @@ const struct message responses[] =
,.http_minor= 1
,.status_code= 200
,.num_headers= 1
,.num_chunks= 0
,.headers=
{ { "Transfer-Encoding", "chunked" }
}
Expand Down Expand Up @@ -1623,6 +1632,22 @@ message_complete_cb (http_parser *p)
return 0;
}

int
chunk_begin_cb (http_parser *p)
{
assert(p == parser);
messages[num_messages].num_chunks++;
return 0;
}

int
chunk_complete_cb (http_parser *p)
{
assert(p == parser);
messages[num_messages].num_end_chunks++;
return 0;
}

/* These dontcall_* callbacks exist so that we can verify that when we're
* paused, no additional callbacks are invoked */
int
Expand Down Expand Up @@ -1683,6 +1708,24 @@ dontcall_message_complete_cb (http_parser *p)
abort();
}

int
dontcall_chunk_begin_cb (http_parser *p)
{
if (p) { } // gcc
fprintf(stderr, "\n\n*** on_chunk_begin() called on paused "
"parser ***\n\n");
abort();
}

int
dontcall_chunk_complete_cb (http_parser *p)
{
if (p) { } // gcc
fprintf(stderr, "\n\n*** on_chunk_complete() called on paused "
"parser ***\n\n");
abort();
}

static http_parser_settings settings_dontcall =
{.on_message_begin = dontcall_message_begin_cb
,.on_header_field = dontcall_header_field_cb
Expand All @@ -1691,6 +1734,8 @@ static http_parser_settings settings_dontcall =
,.on_body = dontcall_body_cb
,.on_headers_complete = dontcall_headers_complete_cb
,.on_message_complete = dontcall_message_complete_cb
,.on_chunk_begin = dontcall_chunk_begin_cb
,.on_chunk_complete = dontcall_chunk_complete_cb
};

/* These pause_* callbacks always pause the parser and just invoke the regular
Expand Down Expand Up @@ -1753,6 +1798,22 @@ pause_message_complete_cb (http_parser *p)
return message_complete_cb(p);
}

int
pause_chunk_begin_cb (http_parser *p)
{
http_parser_pause(p, 1);
*current_pause_parser = settings_dontcall;
return chunk_begin_cb(p);
}

int
pause_chunk_complete_cb (http_parser *p)
{
http_parser_pause(p, 1);
*current_pause_parser = settings_dontcall;
return chunk_complete_cb(p);
}

static http_parser_settings settings_pause =
{.on_message_begin = pause_message_begin_cb
,.on_header_field = pause_header_field_cb
Expand All @@ -1761,6 +1822,8 @@ static http_parser_settings settings_pause =
,.on_body = pause_body_cb
,.on_headers_complete = pause_headers_complete_cb
,.on_message_complete = pause_message_complete_cb
,.on_chunk_begin = pause_chunk_begin_cb
,.on_chunk_complete = pause_chunk_complete_cb
};

static http_parser_settings settings =
Expand All @@ -1771,6 +1834,8 @@ static http_parser_settings settings =
,.on_body = body_cb
,.on_headers_complete = headers_complete_cb
,.on_message_complete = message_complete_cb
,.on_chunk_begin = chunk_begin_cb
,.on_chunk_complete = chunk_complete_cb
};

static http_parser_settings settings_count_body =
Expand All @@ -1781,6 +1846,8 @@ static http_parser_settings settings_count_body =
,.on_body = count_body_cb
,.on_headers_complete = headers_complete_cb
,.on_message_complete = message_complete_cb
,.on_chunk_begin = chunk_begin_cb
,.on_chunk_complete = chunk_complete_cb
};

static http_parser_settings settings_null =
Expand All @@ -1791,6 +1858,8 @@ static http_parser_settings settings_null =
,.on_body = 0
,.on_headers_complete = 0
,.on_message_complete = 0
,.on_chunk_begin = 0
,.on_chunk_complete = 0
};

void
Expand Down Expand Up @@ -1959,6 +2028,8 @@ message_eq (int index, const struct message *expected)
}

MESSAGE_CHECK_NUM_EQ(expected, m, num_headers);
MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks);
if (!check_num_eq(expected, "num_end_chunks", m->num_chunks, m->num_end_chunks)) return 0;

int r;
for (i = 0; i < m->num_headers; i++) {
Expand Down Expand Up @@ -3244,6 +3315,7 @@ main (void)
,.http_minor= 0
,.status_code= 200
,.num_headers= 2
,.num_chunks= 31337
,.headers=
{ { "Transfer-Encoding", "chunked" }
, { "Content-Type", "text/plain" }
Expand Down