diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2020-12-16 15:21:12 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2020-12-16 15:21:12 +0300 |
commit | d1d9637605c27493bf3efc9ca772aa63c650cd96 (patch) | |
tree | 702d475c02b163407bdc80d13d3bdd25503a9100 | |
parent | 35c2a1eb819c8f44352c4e5a2ad476f084c0f88d (diff) | |
download | libmicrohttpd-d1d9637605c27493bf3efc9ca772aa63c650cd96.tar.gz libmicrohttpd-d1d9637605c27493bf3efc9ca772aa63c650cd96.zip |
mhd_send.c: added support for vector-send on W32
-rw-r--r-- | src/microhttpd/mhd_send.c | 81 |
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 | |||
784 | ssize_t | 788 | ssize_t |
785 | MHD_send_hdr_and_body_ (struct MHD_Connection *connection, | 789 | MHD_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 | ||