Skip to content

Commit

Permalink
net: lib: http_server: Wait all HTTP/1 headers before handling request
Browse files Browse the repository at this point in the history
We need to make sure that all the headers have been received before
the HTTP/1 request processing can continue.

Signed-off-by: Jukka Rissanen <[email protected]>
  • Loading branch information
jukkar authored and rlubos committed Apr 17, 2024
1 parent 7f9f511 commit 839d8bb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/zephyr/net/http/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ enum http_server_state {
HTTP_SERVER_DONE_STATE,
};

enum http1_parser_header_state {
HTTP1_INIT_HEADER_STATE,
HTTP1_WAITING_HEADER_STATE,
HTTP1_RECEIVING_HEADER_STATE,
HTTP1_RECEIVED_HEADER_STATE,
};

struct http_stream_ctx {
int stream_id;
enum http_stream_state stream_state;
Expand Down Expand Up @@ -145,6 +152,7 @@ struct http_client_ctx {
unsigned char content_type[CONFIG_HTTP_SERVER_MAX_CONTENT_TYPE_LENGTH];
size_t content_len;
enum http_method method;
enum http1_parser_header_state parser_header_state;
};

struct http_server_ctx {
Expand Down
22 changes: 22 additions & 0 deletions subsys/net/lib/http/http_server_http1.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ static int on_header_field(struct http_parser *parser, const char *at,
struct http_client_ctx,
parser);

ctx->parser_header_state = HTTP1_RECEIVING_HEADER_STATE;

if (length == 7 && strncasecmp(at, "Upgrade", length) == 0) {
LOG_DBG("The \"Upgrade: h2c\" header is present.");
ctx->has_upgrade_header = true;
Expand All @@ -299,11 +301,25 @@ static int on_header_field(struct http_parser *parser, const char *at,
return 0;
}

static int on_headers_complete(struct http_parser *parser)
{
struct http_client_ctx *ctx = CONTAINER_OF(parser,
struct http_client_ctx,
parser);

ctx->parser_header_state = HTTP1_RECEIVED_HEADER_STATE;

return 0;
}

static int on_url(struct http_parser *parser, const char *at, size_t length)
{
struct http_client_ctx *ctx = CONTAINER_OF(parser,
struct http_client_ctx,
parser);

ctx->parser_header_state = HTTP1_WAITING_HEADER_STATE;

strncpy(ctx->url_buffer, at, length);
ctx->url_buffer[length] = '\0';
LOG_DBG("Requested URL: %s", ctx->url_buffer);
Expand All @@ -318,7 +334,9 @@ int enter_http1_request(struct http_client_ctx *client)
http_parser_settings_init(&client->parser_settings);

client->parser_settings.on_header_field = on_header_field;
client->parser_settings.on_headers_complete = on_headers_complete;
client->parser_settings.on_url = on_url;
client->parser_header_state = HTTP1_INIT_HEADER_STATE;

return 0;
}
Expand All @@ -339,6 +357,10 @@ int handle_http1_request(struct http_server_ctx *server, struct http_client_ctx
return -EBADMSG;
}

if (client->parser_header_state != HTTP1_RECEIVED_HEADER_STATE) {
return 0;
}

client->method = client->parser.method;

if (client->has_upgrade_header) {
Expand Down

0 comments on commit 839d8bb

Please sign in to comment.