aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/connection.c
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2017-11-22 14:12:55 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2017-11-22 14:45:50 +0300
commite28049cccb0d25cf5d93436c7db431f4d147ac59 (patch)
treeba98d321ab730656b2d31b88404218fbfbddab1a /src/microhttpd/connection.c
parent79245407f429a1e10f44452b3a3b10e02a104c7d (diff)
downloadlibmicrohttpd-e28049cccb0d25cf5d93436c7db431f4d147ac59.tar.gz
libmicrohttpd-e28049cccb0d25cf5d93436c7db431f4d147ac59.zip
Added support for Darwin-style sendfile()
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r--src/microhttpd/connection.c62
1 files changed, 51 insertions, 11 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 623b40a5..ef61fdb6 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -39,11 +39,11 @@
39#ifdef MHD_LINUX_SOLARIS_SENDFILE 39#ifdef MHD_LINUX_SOLARIS_SENDFILE
40#include <sys/sendfile.h> 40#include <sys/sendfile.h>
41#endif /* MHD_LINUX_SOLARIS_SENDFILE */ 41#endif /* MHD_LINUX_SOLARIS_SENDFILE */
42#ifdef HAVE_FREEBSD_SENDFILE 42#if defined(HAVE_FREEBSD_SENDFILE) || defined(HAVE_DARWIN_SENDFILE)
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/socket.h> 44#include <sys/socket.h>
45#include <sys/uio.h> 45#include <sys/uio.h>
46#endif /* HAVE_FREEBSD_SENDFILE */ 46#endif /* HAVE_FREEBSD_SENDFILE || HAVE_DARWIN_SENDFILE */
47#ifdef HTTPS_SUPPORT 47#ifdef HTTPS_SUPPORT
48#include "connection_https.h" 48#include "connection_https.h"
49#endif /* HTTPS_SUPPORT */ 49#endif /* HTTPS_SUPPORT */
@@ -272,7 +272,7 @@ send_param_adapter (struct MHD_Connection *connection,
272} 272}
273 273
274 274
275#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) 275#if defined(_MHD_HAVE_SENDFILE)
276/** 276/**
277 * Function for sending responses backed by file FD. 277 * Function for sending responses backed by file FD.
278 * 278 *
@@ -302,6 +302,9 @@ sendfile_adapter (struct MHD_Connection *connection)
302 off_t sent_bytes; 302 off_t sent_bytes;
303 int flags = 0; 303 int flags = 0;
304#endif 304#endif
305#ifdef HAVE_DARWIN_SENDFILE
306 off_t len;
307#endif /* HAVE_DARWIN_SENDFILE */
305 const bool used_thr_p_c = (0 != (connection->daemon->options & MHD_USE_THREAD_PER_CONNECTION)); 308 const bool used_thr_p_c = (0 != (connection->daemon->options & MHD_USE_THREAD_PER_CONNECTION));
306 const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_; 309 const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_;
307 size_t send_size = 0; 310 size_t send_size = 0;
@@ -407,10 +410,47 @@ sendfile_adapter (struct MHD_Connection *connection)
407 mhd_assert (0 < sent_bytes); 410 mhd_assert (0 < sent_bytes);
408 mhd_assert (SSIZE_MAX >= sent_bytes); 411 mhd_assert (SSIZE_MAX >= sent_bytes);
409 ret = (ssize_t)sent_bytes; 412 ret = (ssize_t)sent_bytes;
413#elif defined(HAVE_DARWIN_SENDFILE)
414 len = (off_t)send_size; /* chunk always fit */
415 if (0 != sendfile (file_fd,
416 connection->socket_fd,
417 (off_t) offsetu64,
418 &len,
419 NULL,
420 0))
421 {
422 const int err = MHD_socket_get_error_();
423 if (MHD_SCKT_ERR_IS_EAGAIN_(err) ||
424 MHD_SCKT_ERR_IS_EINTR_(err))
425 {
426 mhd_assert (0 <= len);
427 mhd_assert (SSIZE_MAX >= len);
428 mhd_assert (send_size >= (size_t)len);
429 if (0 != len)
430 return (ssize_t)len;
431
432 return MHD_ERR_AGAIN_;
433 }
434 if (ENOTCONN == err ||
435 EPIPE == err)
436 return MHD_ERR_CONNRESET_;
437 if (ENOTSUP == err ||
438 EOPNOTSUPP == err)
439 { /* This file FD is not suitable for sendfile().
440 * Retry with standard send(). */
441 connection->resp_sender = MHD_resp_sender_std;
442 return MHD_ERR_AGAIN_;
443 }
444 return MHD_ERR_BADF_; /* Return hard error. */
445 }
446 mhd_assert (0 <= len);
447 mhd_assert (SSIZE_MAX >= len);
448 mhd_assert (send_size >= (size_t)len);
449 ret = (ssize_t)len;
410#endif /* HAVE_FREEBSD_SENDFILE */ 450#endif /* HAVE_FREEBSD_SENDFILE */
411 return ret; 451 return ret;
412} 452}
413#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ 453#endif /* _MHD_HAVE_SENDFILE */
414 454
415 455
416/** 456/**
@@ -1042,13 +1082,13 @@ try_ready_normal_body (struct MHD_Connection *connection)
1042 (response->data_size + response->data_start > 1082 (response->data_size + response->data_start >
1043 connection->response_write_position) ) 1083 connection->response_write_position) )
1044 return MHD_YES; /* response already ready */ 1084 return MHD_YES; /* response already ready */
1045#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined (HAVE_FREEBSD_SENDFILE) 1085#if defined(_MHD_HAVE_SENDFILE)
1046 if (MHD_resp_sender_sendfile == connection->resp_sender) 1086 if (MHD_resp_sender_sendfile == connection->resp_sender)
1047 { 1087 {
1048 /* will use sendfile, no need to bother response crc */ 1088 /* will use sendfile, no need to bother response crc */
1049 return MHD_YES; 1089 return MHD_YES;
1050 } 1090 }
1051#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ 1091#endif /* _MHD_HAVE_SENDFILE */
1052 1092
1053 ret = response->crc (response->crc_cls, 1093 ret = response->crc (response->crc_cls,
1054 connection->response_write_position, 1094 connection->response_write_position,
@@ -2986,15 +3026,15 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2986 /* mutex was already unlocked by try_ready_normal_body */ 3026 /* mutex was already unlocked by try_ready_normal_body */
2987 return; 3027 return;
2988 } 3028 }
2989#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) 3029#if defined(_MHD_HAVE_SENDFILE)
2990 if (MHD_resp_sender_sendfile == connection->resp_sender) 3030 if (MHD_resp_sender_sendfile == connection->resp_sender)
2991 { 3031 {
2992 ret = sendfile_adapter (connection); 3032 ret = sendfile_adapter (connection);
2993 } 3033 }
2994 else 3034 else
2995#else /* ! (MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE) */ 3035#else /* ! _MHD_HAVE_SENDFILE */
2996 if (1) 3036 if (1)
2997#endif /* ! (MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE) */ 3037#endif /* ! _MHD_HAVE_SENDFILE */
2998 { 3038 {
2999 data_write_offset = connection->response_write_position 3039 data_write_offset = connection->response_write_position
3000 - response->data_start; 3040 - response->data_start;
@@ -3934,13 +3974,13 @@ MHD_queue_response (struct MHD_Connection *connection,
3934 MHD_increment_response_rc (response); 3974 MHD_increment_response_rc (response);
3935 connection->response = response; 3975 connection->response = response;
3936 connection->responseCode = status_code; 3976 connection->responseCode = status_code;
3937#if defined(MHD_LINUX_SOLARIS_SENDFILE) || defined(HAVE_FREEBSD_SENDFILE) 3977#if defined(_MHD_HAVE_SENDFILE)
3938 if ( (response->fd == -1) || 3978 if ( (response->fd == -1) ||
3939 (0 != (connection->daemon->options & MHD_USE_TLS)) ) 3979 (0 != (connection->daemon->options & MHD_USE_TLS)) )
3940 connection->resp_sender = MHD_resp_sender_std; 3980 connection->resp_sender = MHD_resp_sender_std;
3941 else 3981 else
3942 connection->resp_sender = MHD_resp_sender_sendfile; 3982 connection->resp_sender = MHD_resp_sender_sendfile;
3943#endif /* MHD_LINUX_SOLARIS_SENDFILE || HAVE_FREEBSD_SENDFILE */ 3983#endif /* _MHD_HAVE_SENDFILE */
3944 3984
3945 if ( ( (NULL != connection->method) && 3985 if ( ( (NULL != connection->method) &&
3946 (MHD_str_equal_caseless_ (connection->method, 3986 (MHD_str_equal_caseless_ (connection->method,