aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2020-12-16 15:21:12 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2020-12-16 15:21:12 +0300
commitd1d9637605c27493bf3efc9ca772aa63c650cd96 (patch)
tree702d475c02b163407bdc80d13d3bdd25503a9100
parent35c2a1eb819c8f44352c4e5a2ad476f084c0f88d (diff)
downloadlibmicrohttpd-d1d9637605c27493bf3efc9ca772aa63c650cd96.tar.gz
libmicrohttpd-d1d9637605c27493bf3efc9ca772aa63c650cd96.zip
mhd_send.c: added support for vector-send on W32
-rw-r--r--src/microhttpd/mhd_send.c81
1 files changed, 63 insertions, 18 deletions
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index fbb65023..a7125708 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -781,6 +781,10 @@ MHD_send_data_ (struct MHD_Connection *connection,
781} 781}
782 782
783 783
784#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) || defined(_WIN32)
785#define _MHD_USE_SEND_VEC 1
786#endif /* HAVE_SENDMSG || HAVE_WRITEV || _WIN32*/
787
784ssize_t 788ssize_t
785MHD_send_hdr_and_body_ (struct MHD_Connection *connection, 789MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
786 const char *header, 790 const char *header,
@@ -794,17 +798,30 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
794 bool push_hdr; 798 bool push_hdr;
795 bool push_body; 799 bool push_body;
796 MHD_socket s = connection->socket_fd; 800 MHD_socket s = connection->socket_fd;
801#ifndef _WIN32
802#define _MHD_SEND_VEC_MAX MHD_SCKT_SEND_MAX_SIZE_
803#else /* ! _WIN32 */
804#define _MHD_SEND_VEC_MAX UINT32_MAX
805#endif /* ! _WIN32 */
806#ifdef _MHD_USE_SEND_VEC
797#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) 807#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
798 struct iovec vector[2]; 808 struct iovec vector[2];
799#ifdef HAVE_SENDMSG 809#ifdef HAVE_SENDMSG
800 struct msghdr msg; 810 struct msghdr msg;
801#endif /* HAVE_SENDMSG */ 811#endif /* HAVE_SENDMSG */
812#endif /* HAVE_SENDMSG || HAVE_WRITEV */
813#ifdef _WIN32
814 WSABUF vector[2];
815 uint32_t vec_sent;
816 int err;
817#endif /* _WIN32 */
802#ifdef HTTPS_SUPPORT 818#ifdef HTTPS_SUPPORT
803 const bool no_vec = (connection->daemon->options & MHD_USE_TLS); 819 const bool no_vec = (connection->daemon->options & MHD_USE_TLS);
804#else /* ! HTTPS_SUPPORT */ 820#else /* ! HTTPS_SUPPORT */
805 const bool no_vec = false; 821 const bool no_vec = false;
806#endif /* ! HTTPS_SUPPORT */ 822#endif /* ! HTTPS_SUPPORT */
807#endif /* HAVE_SENDMSG || HAVE_WRITEV */ 823#endif /* _MHD_USE_SEND_VEC */
824
808 mhd_assert ( (NULL != body) || (0 == body_size) ); 825 mhd_assert ( (NULL != body) || (0 == body_size) );
809 826
810 if ( (MHD_INVALID_SOCKET == s) || 827 if ( (MHD_INVALID_SOCKET == s) ||
@@ -840,13 +857,14 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
840 push_hdr = true; /* The header alone is equal to the whole response. */ 857 push_hdr = true; /* The header alone is equal to the whole response. */
841 858
842 if ( 859 if (
843#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) 860#ifdef _MHD_USE_SEND_VEC
844 (no_vec) || 861 (no_vec) ||
845 (0 == body_size) || 862 (0 == body_size) ||
846 ((size_t) SSIZE_MAX <= header_size) 863 ((size_t) SSIZE_MAX < header_size) ||
847#else /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ 864 ((size_t) _MHD_SEND_VEC_MAX < header_size)
865#else /* ! _MHD_USE_SEND_VEC */
848 true 866 true
849#endif /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ 867#endif /* ! _MHD_USE_SEND_VEC */
850 ) 868 )
851 { 869 {
852 ret = MHD_send_data_ (connection, 870 ret = MHD_send_data_ (connection,
@@ -884,7 +902,7 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
884 } 902 }
885 return ret; 903 return ret;
886 } 904 }
887#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) 905#ifdef _MHD_USE_SEND_VEC
888 906
889 if ( ((size_t) SSIZE_MAX <= body_size) || 907 if ( ((size_t) SSIZE_MAX <= body_size) ||
890 ((size_t) SSIZE_MAX < (header_size + body_size)) ) 908 ((size_t) SSIZE_MAX < (header_size + body_size)) )
@@ -894,32 +912,59 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
894 complete_response = false; 912 complete_response = false;
895 push_body = complete_response; 913 push_body = complete_response;
896 } 914 }
915#if (SSIZE_MAX != _MHD_SEND_VEC_MAX) || (_MHD_SEND_VEC_MAX + 0 == 0)
916 if (((size_t) _MHD_SEND_VEC_MAX <= body_size) ||
917 ((size_t) _MHD_SEND_VEC_MAX < (header_size + body_size)))
918 {
919 /* Send value limit */
920 body_size = _MHD_SEND_VEC_MAX - header_size;
921 complete_response = false;
922 push_body = complete_response;
923 }
924#endif /* SSIZE_MAX != _MHD_SEND_VEC_MAX */
897 925
898 pre_send_setopt (connection, 926 pre_send_setopt (connection,
899#if HAVE_SENDMSG 927#ifdef HAVE_SENDMSG
900 true, 928 true,
901#elif HAVE_WRITEV 929#else /* ! HAVE_SENDMSG */
902 false, 930 false,
903#endif /* HAVE_WRITEV */ 931#endif /* ! HAVE_SENDMSG */
904 push_hdr || push_body); 932 push_hdr || push_body);
905 933#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
906 vector[0].iov_base = (void *) header; 934 vector[0].iov_base = (void *) header;
907 vector[0].iov_len = header_size; 935 vector[0].iov_len = header_size;
908 vector[1].iov_base = (void *) body; 936 vector[1].iov_base = (void *) body;
909 vector[1].iov_len = body_size; 937 vector[1].iov_len = body_size;
910 938
911#if HAVE_SENDMSG 939#if define (HAVE_SENDMSG)
912 memset (&msg, 0, sizeof(msg)); 940 memset (&msg, 0, sizeof(msg));
913 msg.msg_iov = vector; 941 msg.msg_iov = vector;
914 msg.msg_iovlen = 2; 942 msg.msg_iovlen = 2;
915 943
916 ret = sendmsg (s, &msg, MSG_NOSIGNAL_OR_ZERO); 944 ret = sendmsg (s, &msg, MSG_NOSIGNAL_OR_ZERO);
917#elif HAVE_WRITEV 945#elif defined (HAVE_WRITEV)
918 ret = writev (s, vector, 2); 946 ret = writev (s, vector, 2);
919#endif 947#endif /* HAVE_WRITEV */
948#endif /* HAVE_SENDMSG || HAVE_WRITEV */
949#ifdef _WIN32
950 vector[0].buf = (char *) header;
951 vector[0].len = (unsigned long) header_size;
952 vector[1].buf = (char *) body;
953 vector[1].len = (unsigned long) body_size;
954
955 err = WSASend (s, vector, 2, &vec_sent, 0, NULL, NULL);
956
957 if (0 == err)
958 ret = (ssize_t) vec_sent;
959 else
960 ret = -1;
961#endif /* _WIN32 */
962
920 if (0 > ret) 963 if (0 > ret)
921 { 964 {
965#ifndef _WIN32
922 const int err = MHD_socket_get_error_ (); 966 const int err = MHD_socket_get_error_ ();
967#endif /* _WIN32 */
923 968
924 if (MHD_SCKT_ERR_IS_EAGAIN_ (err)) 969 if (MHD_SCKT_ERR_IS_EAGAIN_ (err))
925 { 970 {
@@ -955,11 +1000,11 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
955 * sendfile() will be used so assume that next final send() will be 1000 * sendfile() will be used so assume that next final send() will be
956 * the same, like for this response. */ 1001 * the same, like for this response. */
957 post_send_setopt (connection, 1002 post_send_setopt (connection,
958#if HAVE_SENDMSG 1003#ifdef HAVE_SENDMSG
959 true, 1004 true,
960#elif HAVE_WRITEV 1005#else /* ! HAVE_SENDMSG */
961 false, 1006 false,
962#endif /* HAVE_WRITEV */ 1007#endif /* ! HAVE_SENDMSG */
963 true); 1008 true);
964 } 1009 }
965 else if ( (push_hdr) && 1010 else if ( (push_hdr) &&
@@ -978,10 +1023,10 @@ MHD_send_hdr_and_body_ (struct MHD_Connection *connection,
978 } 1023 }
979 1024
980 return ret; 1025 return ret;
981#else /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ 1026#else /* ! _MHD_USE_SEND_VEC */
982 mhd_assert (false); 1027 mhd_assert (false);
983 return MHD_ERR_CONNRESET_; /* Unreachable. Mute warnings. */ 1028 return MHD_ERR_CONNRESET_; /* Unreachable. Mute warnings. */
984#endif /* ! (HAVE_SENDMSG || HAVE_WRITEV) */ 1029#endif /* ! _MHD_USE_SEND_VEC */
985} 1030}
986 1031
987 1032