Skip to content

Commit

Permalink
net: lib: http_server: Move stream-specific flags to stream context
Browse files Browse the repository at this point in the history
The information about replied headers or END_OF_STREAM flag are
stream-specific and not general for a client. Hence, need to move them
to the stream context.

Signed-off-by: Robert Lubos <[email protected]>
  • Loading branch information
rlubos committed Jul 5, 2024
1 parent a387828 commit d008b71
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 24 deletions.
16 changes: 9 additions & 7 deletions include/zephyr/net/http/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ struct http2_stream_ctx {
int stream_id; /**< Stream identifier. */
enum http2_stream_state stream_state; /**< Stream state. */
int window_size; /**< Stream-level window size. */

/** Flag indicating that headers were sent in the reply. */
bool headers_sent : 1;

/** Flag indicating that END_STREAM flag was sent. */
bool end_stream_sent : 1;
};

/** @brief HTTP/2 frame representation. */
Expand Down Expand Up @@ -315,6 +321,9 @@ struct http_client_ctx {
/** Currently processed resource detail. */
struct http_resource_detail *current_detail;

/** Currently processed stream. */
struct http2_stream_ctx *current_stream;

/** HTTP/2 header parser context. */
struct http_hpack_header_buf header_field;

Expand Down Expand Up @@ -360,13 +369,6 @@ struct http_client_ctx {
IF_ENABLED(CONFIG_WEBSOCKET, (uint8_t ws_sec_key[HTTP_SERVER_WS_MAX_SEC_KEY_LEN]));
/** @endcond */

/* TODO those two are stream-specific, move them. */
/** Flag indicating that headers were sent in the reply. */
bool headers_sent : 1;

/** Flag indicating that END_STREAM flag was sent. */
bool end_stream_sent : 1;

/** Flag indicating that HTTP2 preface was sent. */
bool preface_sent : 1;

Expand Down
2 changes: 2 additions & 0 deletions subsys/net/lib/http/http_server_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ static void init_client_ctx(struct http_client_ctx *client, int new_socket)
client->streams[i].stream_state = HTTP2_STREAM_IDLE;
client->streams[i].stream_id = 0;
}

client->current_stream = NULL;
}

static int handle_http_preface(struct http_client_ctx *client)
Expand Down
8 changes: 6 additions & 2 deletions subsys/net/lib/http/http_server_http1.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,17 @@ static int dynamic_post_req(struct http_resource_detail_dynamic *dynamic_detail,
return -ENOENT;
}

if (!client->headers_sent) {
if (client->current_stream == NULL) {
return -ENOENT;
}

if (!client->current_stream->headers_sent) {
ret = SEND_RESPONSE(RESPONSE_TEMPLATE_CHUNKED,
dynamic_detail->common.content_type);
if (ret < 0) {
return ret;
}
client->headers_sent = true;
client->current_stream->headers_sent = true;
}

copy_len = MIN(remaining, dynamic_detail->data_buffer_len);
Expand Down
53 changes: 38 additions & 15 deletions subsys/net/lib/http/http_server_http2.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ static struct http2_stream_ctx *allocate_http_stream_context(
client->streams[i].stream_state = HTTP2_STREAM_OPEN;
client->streams[i].window_size =
HTTP_SERVER_INITIAL_WINDOW_SIZE;
client->streams[i].headers_sent = false;
client->streams[i].end_stream_sent = false;
return &client->streams[i];
}
}
Expand Down Expand Up @@ -339,6 +341,10 @@ static int handle_http2_static_resource(
return -ENOTSUP;
}

if (client->current_stream == NULL) {
return -ENOENT;
}

content_200 = static_detail->static_data;
content_len = static_detail->static_data_len;

Expand All @@ -349,7 +355,7 @@ static int handle_http2_static_resource(
goto out;
}

client->headers_sent = true;
client->current_stream->headers_sent = true;

ret = send_data_frame(client, content_200, content_len,
frame->stream_identifier,
Expand All @@ -359,7 +365,7 @@ static int handle_http2_static_resource(
goto out;
}

client->end_stream_sent = true;
client->current_stream->end_stream_sent = true;

out:
return ret;
Expand All @@ -372,14 +378,18 @@ static int dynamic_get_req_v2(struct http_resource_detail_dynamic *dynamic_detai
int ret, remaining, offset = dynamic_detail->common.path_len;
char *ptr;

if (client->current_stream == NULL) {
return -ENOENT;
}

ret = send_headers_frame(client, HTTP_200_OK, frame->stream_identifier,
&dynamic_detail->common, 0);
if (ret < 0) {
LOG_DBG("Cannot write to socket (%d)", ret);
return ret;
}

client->headers_sent = true;
client->current_stream->headers_sent = true;

remaining = strlen(&client->url_buffer[dynamic_detail->common.path_len]);

Expand Down Expand Up @@ -428,7 +438,7 @@ static int dynamic_get_req_v2(struct http_resource_detail_dynamic *dynamic_detai
LOG_DBG("Cannot send last frame (%d)", ret);
}

client->end_stream_sent = true;
client->current_stream->end_stream_sent = true;

dynamic_detail->holder = NULL;

Expand All @@ -450,6 +460,10 @@ static int dynamic_post_req_v2(struct http_resource_detail_dynamic *dynamic_deta
return -ENOENT;
}

if (client->current_stream == NULL) {
return -ENOENT;
}

data_len = MIN(frame->length, client->data_len);
copy_len = MIN(data_len, dynamic_detail->data_buffer_len);

Expand Down Expand Up @@ -481,7 +495,7 @@ static int dynamic_post_req_v2(struct http_resource_detail_dynamic *dynamic_deta
if (send_len > 0) {
uint8_t flags = 0;

if (!client->headers_sent) {
if (!client->current_stream->headers_sent) {
ret = send_headers_frame(
client, HTTP_200_OK, frame->stream_identifier,
&dynamic_detail->common, 0);
Expand All @@ -490,7 +504,7 @@ static int dynamic_post_req_v2(struct http_resource_detail_dynamic *dynamic_deta
return ret;
}

client->headers_sent = true;
client->current_stream->headers_sent = true;
}

/* In case no more data is available, that was the last
Expand All @@ -499,7 +513,7 @@ static int dynamic_post_req_v2(struct http_resource_detail_dynamic *dynamic_deta
if (frame->length == 0 &&
is_header_flag_set(frame->flags, HTTP2_FLAG_END_STREAM)) {
flags = HTTP2_FLAG_END_STREAM;
client->end_stream_sent = true;
client->current_stream->end_stream_sent = true;
}

ret = send_data_frame(client,
Expand All @@ -518,7 +532,7 @@ static int dynamic_post_req_v2(struct http_resource_detail_dynamic *dynamic_deta

if (frame->length == 0 &&
is_header_flag_set(frame->flags, HTTP2_FLAG_END_STREAM)) {
if (!client->headers_sent) {
if (!client->current_stream->headers_sent) {
/* The callback did not report any data to send, therefore send
* headers frame now, including END_STREAM flag.
*/
Expand All @@ -531,8 +545,8 @@ static int dynamic_post_req_v2(struct http_resource_detail_dynamic *dynamic_deta
return ret;
}

client->headers_sent = true;
client->end_stream_sent = true;
client->current_stream->headers_sent = true;
client->current_stream->end_stream_sent = true;
}

dynamic_detail->holder = NULL;
Expand Down Expand Up @@ -659,6 +673,7 @@ static int enter_http_frame_data_state(struct http_client_ctx *client)
stream->window_size -= frame->length;
client->window_size -= frame->length;
client->server_state = HTTP_SERVER_FRAME_DATA_STATE;
client->current_stream = stream;

return 0;
}
Expand All @@ -680,6 +695,8 @@ static int enter_http_frame_headers_state(struct http_client_ctx *client)
}
}

client->current_stream = stream;

if (!is_header_flag_set(frame->flags, HTTP2_FLAG_END_HEADERS)) {
client->expect_continuation = true;
} else {
Expand Down Expand Up @@ -756,6 +773,8 @@ int handle_http_frame_header(struct http_client_ctx *client)
return -EBADMSG;
}

client->current_stream = NULL;

switch (client->current_frame.type) {
case HTTP2_DATA_FRAME:
return enter_http_frame_data_state(client);
Expand Down Expand Up @@ -1121,6 +1140,10 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client)
goto out;
}

if (client->current_stream == NULL) {
return -ENOENT;
}

if (client->current_detail->type == HTTP_RESOURCE_TYPE_DYNAMIC) {
struct http_resource_detail_dynamic *dynamic_detail =
(struct http_resource_detail_dynamic *)client->current_detail;
Expand All @@ -1130,7 +1153,7 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client)
dynamic_detail->data_buffer, 0,
dynamic_detail->user_data);
if (send_len > 0) {
if (!client->headers_sent) {
if (!client->current_stream->headers_sent) {
ret = send_headers_frame(
client, HTTP_200_OK, frame->stream_identifier,
client->current_detail, 0);
Expand All @@ -1139,7 +1162,7 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client)
goto out;
}

client->headers_sent = true;
client->current_stream->headers_sent = true;
}

ret = send_data_frame(client,
Expand All @@ -1151,21 +1174,21 @@ static int handle_http_frame_headers_end_stream(struct http_client_ctx *client)
goto out;
}

client->end_stream_sent = true;
client->current_stream->end_stream_sent = true;
}

dynamic_detail->holder = NULL;
}

if (!client->headers_sent) {
if (!client->current_stream->headers_sent) {
ret = send_headers_frame(
client, HTTP_200_OK, frame->stream_identifier,
client->current_detail, HTTP2_FLAG_END_STREAM);
if (ret < 0) {
LOG_DBG("Cannot write to socket (%d)", ret);
goto out;
}
} else if (!client->end_stream_sent) {
} else if (!client->current_stream->end_stream_sent) {
ret = send_data_frame(client, NULL, 0, frame->stream_identifier,
HTTP2_FLAG_END_STREAM);
if (ret < 0) {
Expand Down

0 comments on commit d008b71

Please sign in to comment.