commit 7f786eb527a18836b3937b1b1c7a47f53edc92c1
parent 5224f4454e596343c5dda48172e958451f6dc003
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Sun, 16 Aug 2026 14:27:43 +0200
MHD_response_from_fd(): implemented support for automatic file size
Diffstat:
3 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h
@@ -6558,14 +6558,18 @@ MHD_response_from_iovec (
*
* @param sc status code to return
* @param fd file descriptor referring to a file on disk with the
- * data; will be closed when response is destroyed;
- * fd should be in 'blocking' mode
- * @param offset offset to start reading from in the file;
- * reading file beyond 2 GiB may be not supported by OS or
- * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
- * @param size size of the data portion of the response;
- * sizes larger than 2 GiB may be not supported by OS or
- * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
+ * data; will be closed when response is destroyed;
+ * fd should be in 'blocking' mode
+ * @param offset offset to start reading from in the file,
+ * must not be #MHD_SIZE_UNKNOWN;
+ * reading file beyond 2 GiB may be not supported by OS or
+ * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
+ * @param size size of the data portion of the response,
+ * #MHD_SIZE_UNKNOWN to send the file to its end; with the
+ * unknown size and @p offset beyond the end of the file the
+ * body is empty;
+ * sizes larger than 2 GiB may be not supported by OS or
+ * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
* @return new response object on success,
* NULL on failure (i.e. invalid arguments, out of memory),
* @p fd is closed automatically in case of failure
diff --git a/src/include/microhttpd2_main.h.in b/src/include/microhttpd2_main.h.in
@@ -1640,14 +1640,18 @@ MHD_response_from_iovec (
*
* @param sc status code to return
* @param fd file descriptor referring to a file on disk with the
- * data; will be closed when response is destroyed;
- * fd should be in 'blocking' mode
- * @param offset offset to start reading from in the file;
- * reading file beyond 2 GiB may be not supported by OS or
- * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
- * @param size size of the data portion of the response;
- * sizes larger than 2 GiB may be not supported by OS or
- * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
+ * data; will be closed when response is destroyed;
+ * fd should be in 'blocking' mode
+ * @param offset offset to start reading from in the file,
+ * must not be #MHD_SIZE_UNKNOWN;
+ * reading file beyond 2 GiB may be not supported by OS or
+ * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
+ * @param size size of the data portion of the response,
+ * #MHD_SIZE_UNKNOWN to send the file to its end; with the
+ * unknown size and @p offset beyond the end of the file the
+ * body is empty;
+ * sizes larger than 2 GiB may be not supported by OS or
+ * MHD build; see #MHD_LIB_INFO_FIXED_HAS_LARGE_FILE
* @return new response object on success,
* NULL on failure (i.e. invalid arguments, out of memory),
* @p fd is closed automatically in case of failure
diff --git a/src/mhd2/stream_process_reply.c b/src/mhd2/stream_process_reply.c
@@ -1129,6 +1129,8 @@ read_response_file (struct MHD_Connection *restrict c,
"for this platform.");
return false;
case mhd_FILE_READ_EOF:
+ if (MHD_SIZE_UNKNOWN == r->cntn_size)
+ return true;
mhd_STREAM_ABORT (c, \
mhd_CONN_CLOSE_FILE_TOO_SHORT, \
"The file for file-backed response is smaller " \
@@ -1243,6 +1245,13 @@ mhd_stream_prep_unchunked_body (struct MHD_Connection *restrict c)
c->write_buffer + c->write_buffer_append_offset,
&filled))
return true; /* Error, the stream is closed */
+ if (0u == filled)
+ {
+ mhd_assert (MHD_SIZE_UNKNOWN == r->cntn_size);
+ c->stage = mhd_HTTP_STAGE_FULL_REPLY_SENT;
+
+ return true;
+ }
c->rp.rsp_cntn_read_pos += filled;
c->write_buffer_append_offset += filled;
@@ -1411,6 +1420,13 @@ mhd_stream_prep_chunked_body (struct MHD_Connection *restrict c)
c->write_buffer + max_chunk_hdr_len,
&filled))
return true; /* Error, the stream is closed */
+ if (0u == filled)
+ {
+ mhd_assert (MHD_SIZE_UNKNOWN == r->cntn_size);
+ c->stage = mhd_HTTP_STAGE_CHUNKED_BODY_SENT;
+
+ return true;
+ }
}
else
{