diff --git a/include/zephyr/net/http/server.h b/include/zephyr/net/http/server.h index 3536352a8f285db..253766ac2d152e4 100644 --- a/include/zephyr/net/http/server.h +++ b/include/zephyr/net/http/server.h @@ -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; @@ -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 { diff --git a/subsys/net/lib/http/http_server_http1.c b/subsys/net/lib/http/http_server_http1.c index 612800270253840..a805ff65ea8aa5f 100644 --- a/subsys/net/lib/http/http_server_http1.c +++ b/subsys/net/lib/http/http_server_http1.c @@ -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; @@ -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); @@ -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; } @@ -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) {