diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2017-11-22 14:12:55 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2017-11-22 14:45:50 +0300 |
commit | e28049cccb0d25cf5d93436c7db431f4d147ac59 (patch) | |
tree | ba98d321ab730656b2d31b88404218fbfbddab1a /src/microhttpd/connection.c | |
parent | 79245407f429a1e10f44452b3a3b10e02a104c7d (diff) | |
download | libmicrohttpd-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.c | 62 |
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, |