libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit f9a0f497d8537fecc71613fb590119b2c8dccf07
parent e17a630b17bbd6c78fca30618a6958647749f190
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Mon, 17 Aug 2026 16:08:17 +0200

HTTP/2: implemented file-based replies with unknown size

Diffstat:
Msrc/mhd2/h2/h2_reply_funcs.c | 54++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/src/mhd2/h2/h2_reply_funcs.c b/src/mhd2/h2/h2_reply_funcs.c @@ -403,13 +403,14 @@ content_read_iovec (struct MHD_Response *restrict r, static MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (4, 3) -MHD_FN_PAR_OUT_ (5) bool +MHD_FN_PAR_OUT_ (5) enum mhd_FileReadResult content_read_file (struct MHD_Response *restrict r, uint_fast64_t offset, size_t buff_size, uint8_t *restrict buff, size_t *restrict written) { + enum mhd_FileReadResult res; uint_fast64_t file_off; mhd_assert (mhd_RESPONSE_CONTENT_DATA_FILE == r->cntn_dtype); @@ -418,14 +419,18 @@ content_read_file (struct MHD_Response *restrict r, file_off = offset + r->cntn.file.offset; if (file_off < offset) - return false; /* Offset too large */ - - return (mhd_FILE_READ_OK == - mhd_read_file (r->cntn.file.fd, - file_off, - buff_size, - (char *)buff, - written)); + return mhd_FILE_READ_OFFSET_TOO_LARGE; /* Offset too large */ + + res = mhd_read_file (r->cntn.file.fd, + file_off, + buff_size, + (char *)buff, + written); + if ((mhd_FILE_READ_EOF == res) + && (r->cntn_size != MHD_SIZE_UNKNOWN)) + res = mhd_FILE_READ_ERROR; /* Unexpected EOF */ + + return res; } @@ -522,12 +527,27 @@ stream_content_send (struct mhd_H2Stream *s) payload_used = 0u; break; case mhd_RESPONSE_CONTENT_DATA_FILE: - if (!content_read_file (r, - s->rpl.cntn_read_pos, - (size_t)payload_size_limit, - pld_buff, - &payload_used)) + switch (content_read_file (r, + s->rpl.cntn_read_pos, + (size_t)payload_size_limit, + pld_buff, + &payload_used)) + { + case mhd_FILE_READ_OK: + break; + case mhd_FILE_READ_ERROR: + case mhd_FILE_READ_OFFSET_TOO_LARGE: + payload_used = 0u; // TODO: handle it better + break; + case mhd_FILE_READ_EOF: payload_used = 0u; + dat->end_stream = true; + break; + default: + mhd_UNREACHABLE (); + payload_used = 0u; + break; + } break; case mhd_RESPONSE_CONTENT_DATA_CALLBACK: s->rpl.stage = mhd_H2_RPL_STAGE_BROKEN; @@ -539,9 +559,11 @@ stream_content_send (struct mhd_H2Stream *s) break; } - dat->end_stream = (payload_used + s->rpl.cntn_read_pos == r->cntn_size); + dat->end_stream = dat->end_stream + || (payload_used + s->rpl.cntn_read_pos == r->cntn_size); - if (0u != payload_used) + if ((0u != payload_used) + || (dat->end_stream)) { const size_t full_fr_size = mhd_h2_frame_set_payload_size (&h2frame, payload_used);