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

Introduce raw data callbacks #285

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 50 additions & 0 deletions http_parser.c
Expand Up @@ -56,11 +56,37 @@ do { \
parser->http_errno = (e); \
} while(0)

#define CALLBACK_RAW_ON_RETURN(V) \
do { \

This comment was marked as off-topic.

if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { \
if ((p >= raw_mark) && \
(raw_mark < data + len) && \
((ptrdiff_t)(V) == (ptrdiff_t)(len))) \
{ \
if (p_state <= s_header_almost_done) { \
if (settings->on_header_raw) { \
settings->on_header_raw(parser, \
raw_mark, \
len - (raw_mark - data)); \
} \
} else { \
if (settings->on_body_raw) { \

This comment was marked as off-topic.

settings->on_body_raw(parser, \
raw_mark, \
len - (raw_mark - data)); \
} \
} \
} \
} \
} \
while (0);

#define CURRENT_STATE() p_state
#define UPDATE_STATE(V) p_state = (enum state) (V);
#define RETURN(V) \
do { \
parser->state = CURRENT_STATE(); \
CALLBACK_RAW_ON_RETURN(V); \
return (V); \
} while (0);
#define REEXECUTE() \
Expand All @@ -81,6 +107,17 @@ do { \
do { \
assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
\
if (e_on_##FOR == e_on_message_complete) { \
if ((HTTP_PARSER_ERRNO(parser) == HPE_OK) && \
(settings->on_body_raw) && \
(p >= raw_mark) && \

This comment was marked as off-topic.

(raw_mark < data + len)) \
{ \

This comment was marked as off-topic.

settings->on_body_raw(parser, raw_mark, p - raw_mark + 1); \
raw_mark = p + 1; \
} \
} \
\
if (LIKELY(settings->on_##FOR)) { \
parser->state = CURRENT_STATE(); \
if (UNLIKELY(0 != settings->on_##FOR(parser))) { \
Expand Down Expand Up @@ -639,6 +676,7 @@ size_t http_parser_execute (http_parser *parser,
char c, ch;
int8_t unhex_val;
const char *p = data;
const char *raw_mark = data;
const char *header_field_mark = 0;
const char *header_value_mark = 0;
const char *url_mark = 0;
Expand Down Expand Up @@ -1847,6 +1885,18 @@ size_t http_parser_execute (http_parser *parser,
(F_UPGRADE | F_CONNECTION_UPGRADE) ||
parser->method == HTTP_CONNECT);

/* Here we call final headers_raw. It's based on different variables,
* so we can't use CALLBACK_DATA.
*/
if ((HTTP_PARSER_ERRNO(parser) == HPE_OK) &&
(settings->on_header_raw) &&
(p >= raw_mark) &&
(raw_mark < data + len))
{

This comment was marked as off-topic.

settings->on_header_raw(parser, raw_mark, p - raw_mark + 1);
raw_mark = p + 1;
}

/* Here we call the headers_complete callback. This is somewhat
* different than other callbacks because if the user returns 1, we
* will interpret that as saying that this message has no body. This
Expand Down
16 changes: 16 additions & 0 deletions http_parser.h
Expand Up @@ -244,15 +244,31 @@ struct http_parser {
void *data; /* A pointer to get hook to the "connection" or "socket" object */
};

enum {
e_on_message_begin,
e_on_url,
e_on_status,
e_on_header_field,
e_on_header_value,
e_on_header_raw,
e_on_headers_complete,
e_on_body,
e_on_body_raw,
e_on_message_complete,
e_on_chunk_header,
e_on_chunk_complete,
};

struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_url;
http_data_cb on_status;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_data_cb on_header_raw;
http_cb on_headers_complete;
http_data_cb on_body;
http_data_cb on_body_raw;
http_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
Expand Down