aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-07-26 14:15:50 +0200
committerChristian Grothoff <christian@grothoff.org>2020-07-26 14:15:50 +0200
commit1c4f23db7458d79a04c8e68022ade67cb5ee006b (patch)
treeca30e21e645f50d9a230ae29ef3cf21056a96279
parentbabda9e9c702aee6e03e7537108383e32a7c17d0 (diff)
downloadlibmicrohttpd-1c4f23db7458d79a04c8e68022ade67cb5ee006b.tar.gz
libmicrohttpd-1c4f23db7458d79a04c8e68022ade67cb5ee006b.zip
add ability to serve files from pipe
-rw-r--r--ChangeLog4
-rw-r--r--doc/libmicrohttpd.texi15
-rw-r--r--src/include/microhttpd.h20
-rw-r--r--src/microhttpd/connection.c3
-rw-r--r--src/microhttpd/internal.h5
-rw-r--r--src/microhttpd/response.c61
6 files changed, 105 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index ebbe7994..a2e24c02 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Sun 26 Jul 2020 01:56:54 PM CEST
2 Add MHD_create_response_from_pipe() to allow creating a response based
3 on data read from a pipe. -CG
4
1Fri Jul 10 15:04:51 CEST 2020 5Fri Jul 10 15:04:51 CEST 2020
2 Fixed Postprocessor URL-encoded parsing if '%' fell on boundary. -CG/MD 6 Fixed Postprocessor URL-encoded parsing if '%' fell on boundary. -CG/MD
3 7
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index 150dd048..fd776028 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -2018,6 +2018,21 @@ Return @code{NULL} on error (i.e. invalid arguments, out of memory).
2018@end deftypefun 2018@end deftypefun
2019 2019
2020 2020
2021@deftypefun {struct MHD_Response *} MHD_create_response_from_pipe (uint64_t size, int fd)
2022Create a response object. The response object can be extended with
2023header information and then it can be used ONLY ONCE.
2024
2025@table @var
2026@item fd
2027file descriptor of the read-end of the pipe; will be
2028closed when response is destroyed.
2029The descriptor should be in blocking-IO mode.
2030@end table
2031
2032Return @code{NULL} on error (i.e. out of memory).
2033@end deftypefun
2034
2035
2021@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset (size_t size, int fd, off_t offset) 2036@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset (size_t size, int fd, off_t offset)
2022Create a response object. The response object can be extended with 2037Create a response object. The response object can be extended with
2023header information and then it can be used any number of times. 2038header information and then it can be used any number of times.
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 09983ab7..7aff40f5 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -180,7 +180,7 @@ enum MHD_Result
180#define _MHD_EXTERN extern 180#define _MHD_EXTERN extern
181#elif defined (_WIN32) && defined(MHD_W32DLL) 181#elif defined (_WIN32) && defined(MHD_W32DLL)
182/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */ 182/* Define MHD_W32DLL when using MHD as W32 .DLL to speed up linker a little */
183#define _MHD_EXTERN __declspec (dllimport) 183#define _MHD_EXTERN __declspec(dllimport)
184#else 184#else
185#define _MHD_EXTERN extern 185#define _MHD_EXTERN extern
186#endif 186#endif
@@ -262,10 +262,10 @@ typedef SOCKET MHD_socket;
262#ifndef _MHD_DEPR_FUNC 262#ifndef _MHD_DEPR_FUNC
263#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1400 263#if defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1400
264/* VS 2005 or later */ 264/* VS 2005 or later */
265#define _MHD_DEPR_FUNC(msg) __declspec (deprecated (msg)) 265#define _MHD_DEPR_FUNC(msg) __declspec(deprecated (msg))
266#elif defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1310 266#elif defined(_MSC_FULL_VER) && _MSC_VER + 0 >= 1310
267/* VS .NET 2003 deprecation do not support custom messages */ 267/* VS .NET 2003 deprecation do not support custom messages */
268#define _MHD_DEPR_FUNC(msg) __declspec (deprecated) 268#define _MHD_DEPR_FUNC(msg) __declspec(deprecated)
269#elif (__GNUC__ + 0 >= 5) || (defined (__clang__) && \ 269#elif (__GNUC__ + 0 >= 5) || (defined (__clang__) && \
270 (__clang_major__ + 0 > 2 || (__clang_major__ + 0 == 2 && __clang_minor__ >= \ 270 (__clang_major__ + 0 > 2 || (__clang_major__ + 0 == 2 && __clang_minor__ >= \
271 9))) /* FIXME: earlier versions not tested */ 271 9))) /* FIXME: earlier versions not tested */
@@ -3127,6 +3127,20 @@ MHD_create_response_from_fd (size_t size,
3127 3127
3128/** 3128/**
3129 * Create a response object. The response object can be extended with 3129 * Create a response object. The response object can be extended with
3130 * header information and then be used ONLY ONCE.
3131 *
3132 * @param fd file descriptor referring to a read-end of a pipe with the
3133 * data; will be closed when response is destroyed;
3134 * fd should be in 'blocking' mode
3135 * @return NULL on error (i.e. invalid arguments, out of memory)
3136 * @ingroup response
3137 */
3138_MHD_EXTERN struct MHD_Response *
3139MHD_create_response_from_pipe (int fd);
3140
3141
3142/**
3143 * Create a response object. The response object can be extended with
3130 * header information and then be used any number of times. 3144 * header information and then be used any number of times.
3131 * 3145 *
3132 * @param size size of the data portion of the response; 3146 * @param size size of the data portion of the response;
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 7a17c628..ceae1cf8 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -3957,11 +3957,14 @@ MHD_queue_response (struct MHD_Connection *connection,
3957 connection->responseCode = status_code; 3957 connection->responseCode = status_code;
3958#if defined(_MHD_HAVE_SENDFILE) 3958#if defined(_MHD_HAVE_SENDFILE)
3959 if ( (response->fd == -1) || 3959 if ( (response->fd == -1) ||
3960 (response->is_pipe) ||
3960 (0 != (connection->daemon->options & MHD_USE_TLS)) ) 3961 (0 != (connection->daemon->options & MHD_USE_TLS)) )
3961 connection->resp_sender = MHD_resp_sender_std; 3962 connection->resp_sender = MHD_resp_sender_std;
3962 else 3963 else
3963 connection->resp_sender = MHD_resp_sender_sendfile; 3964 connection->resp_sender = MHD_resp_sender_sendfile;
3964#endif /* _MHD_HAVE_SENDFILE */ 3965#endif /* _MHD_HAVE_SENDFILE */
3966 /* FIXME: if 'is_pipe' is set, TLS is off, and we have *splice*, we could use splice()
3967 to avoid two user-space copies... */
3965 3968
3966 if ( ( (NULL != connection->method) && 3969 if ( ( (NULL != connection->method) &&
3967 (MHD_str_equal_caseless_ (connection->method, 3970 (MHD_str_equal_caseless_ (connection->method,
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 3fdc7e5c..8f0e821a 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -400,6 +400,11 @@ struct MHD_Response
400 */ 400 */
401 enum MHD_ResponseFlags flags; 401 enum MHD_ResponseFlags flags;
402 402
403 /**
404 * If the @e fd is a pipe (no sendfile()).
405 */
406 bool is_pipe;
407
403}; 408};
404 409
405 410
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 25c05163..27b3ee3f 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -527,6 +527,37 @@ file_reader (void *cls,
527 527
528 528
529/** 529/**
530 * Given a pipe descriptor, read data from the pipe
531 * to generate the response.
532 *
533 * @param cls pointer to the response
534 * @param pos offset in the pipe to access (ignored)
535 * @param buf where to write the data
536 * @param max number of bytes to write at most
537 * @return number of bytes written
538 */
539static ssize_t
540pipe_reader (void *cls,
541 uint64_t pos,
542 char *buf,
543 size_t max)
544{
545 struct MHD_Response *response = cls;
546 ssize_t n;
547
548 (void) pos;
549 n = read (response->fd,
550 buf,
551 max);
552 if (0 == n)
553 return MHD_CONTENT_READER_END_OF_STREAM;
554 if (n < 0)
555 return MHD_CONTENT_READER_END_WITH_ERROR;
556 return n;
557}
558
559
560/**
530 * Destroy file reader context. Closes the file 561 * Destroy file reader context. Closes the file
531 * descriptor. 562 * descriptor.
532 * 563 *
@@ -614,6 +645,7 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size,
614 if (NULL == response) 645 if (NULL == response)
615 return NULL; 646 return NULL;
616 response->fd = fd; 647 response->fd = fd;
648 response->is_pipe = false;
617 response->fd_off = offset; 649 response->fd_off = offset;
618 response->crc_cls = response; 650 response->crc_cls = response;
619 return response; 651 return response;
@@ -622,6 +654,35 @@ MHD_create_response_from_fd_at_offset64 (uint64_t size,
622 654
623/** 655/**
624 * Create a response object. The response object can be extended with 656 * Create a response object. The response object can be extended with
657 * header information and then be used ONLY ONCE.
658 *
659 * @param fd file descriptor referring to a read-end of a pipe with the
660 * data; will be closed when response is destroyed;
661 * fd should be in 'blocking' mode
662 * @return NULL on error (i.e. invalid arguments, out of memory)
663 * @ingroup response
664 */
665_MHD_EXTERN struct MHD_Response *
666MHD_create_response_from_pipe (int fd)
667{
668 struct MHD_Response *response;
669
670 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
671 MHD_FILE_READ_BLOCK_SIZE,
672 &pipe_reader,
673 NULL,
674 &free_callback);
675 if (NULL == response)
676 return NULL;
677 response->fd = fd;
678 response->is_pipe = true;
679 response->crc_cls = response;
680 return response;
681}
682
683
684/**
685 * Create a response object. The response object can be extended with
625 * header information and then be used any number of times. 686 * header information and then be used any number of times.
626 * 687 *
627 * @param size size of the data portion of the response 688 * @param size size of the data portion of the response