aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/connection.c
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2017-06-05 00:31:03 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2017-06-05 00:32:27 +0300
commitddac6d53713141068625b074da18dc306e0bd6fa (patch)
tree14ccf417ad7b3ddf5f07159c2ad882ad4afc2330 /src/microhttpd/connection.c
parent3777686c912cc6102694e55862302aec9a16812b (diff)
downloadlibmicrohttpd-ddac6d53713141068625b074da18dc306e0bd6fa.tar.gz
libmicrohttpd-ddac6d53713141068625b074da18dc306e0bd6fa.zip
Do not use errno to return errors from send_param_adapter()/send_tls_adapter()
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r--src/microhttpd/connection.c147
1 files changed, 68 insertions, 79 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 45cc6566..27a4efb3 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -169,7 +169,8 @@ recv_param_adapter (struct MHD_Connection *connection,
169 * @param connection the MHD connection structure 169 * @param connection the MHD connection structure
170 * @param other data to write 170 * @param other data to write
171 * @param i number of bytes to write 171 * @param i number of bytes to write
172 * @return actual number of bytes written 172 * @return positive value for number of bytes actually sent or
173 * negative value for error number MHD_ERR_xxx_
173 */ 174 */
174static ssize_t 175static ssize_t
175send_param_adapter (struct MHD_Connection *connection, 176send_param_adapter (struct MHD_Connection *connection,
@@ -177,13 +178,11 @@ send_param_adapter (struct MHD_Connection *connection,
177 size_t i) 178 size_t i)
178{ 179{
179 ssize_t ret; 180 ssize_t ret;
180 int err;
181 181
182 if ( (MHD_INVALID_SOCKET == connection->socket_fd) || 182 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
183 (MHD_CONNECTION_CLOSED == connection->state) ) 183 (MHD_CONNECTION_CLOSED == connection->state) )
184 { 184 {
185 MHD_socket_set_error_ (MHD_SCKT_ENOTCONN_); 185 return MHD_ERR_NOTCONN_;
186 return -1;
187 } 186 }
188 if (i > MHD_SCKT_SEND_MAX_SIZE_) 187 if (i > MHD_SCKT_SEND_MAX_SIZE_)
189 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */ 188 i = MHD_SCKT_SEND_MAX_SIZE_; /* return value limit */
@@ -191,23 +190,27 @@ send_param_adapter (struct MHD_Connection *connection,
191 ret = MHD_send_ (connection->socket_fd, 190 ret = MHD_send_ (connection->socket_fd,
192 other, 191 other,
193 i); 192 i);
194 err = MHD_socket_get_error_();
195#ifdef EPOLL_SUPPORT
196 if (0 > ret) 193 if (0 > ret)
197 { 194 {
198 /* EAGAIN --- no longer write-ready */ 195 const int err = MHD_socket_get_error_();
196
199 if (MHD_SCKT_ERR_IS_EAGAIN_(err)) 197 if (MHD_SCKT_ERR_IS_EAGAIN_(err))
200 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 198 {
199#ifdef EPOLL_SUPPORT
200 /* EAGAIN --- no longer write-ready */
201 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
202#endif /* EPOLL_SUPPORT */
203 return MHD_ERR_AGAIN_;
204 }
205 if (MHD_SCKT_ERR_IS_EINTR_ (err))
206 return MHD_ERR_AGAIN_;
207 /* Treat any other error as hard error. */
208 return MHD_ERR_CONNRESET_;
201 } 209 }
210#ifdef EPOLL_SUPPORT
202 else if (i > (size_t)ret) 211 else if (i > (size_t)ret)
203 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 212 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
204#endif 213#endif /* EPOLL_SUPPORT */
205 /* Handle broken kernel / libc, returning -1 but not setting errno;
206 kill connection as that should be safe; reported on mailinglist here:
207 http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */
208 if ( (0 > ret) &&
209 (0 == err) )
210 MHD_socket_set_error_ (MHD_SCKT_ECONNRESET_);
211 return ret; 214 return ret;
212} 215}
213 216
@@ -223,7 +226,6 @@ static ssize_t
223sendfile_adapter (struct MHD_Connection *connection) 226sendfile_adapter (struct MHD_Connection *connection)
224{ 227{
225 int ret; 228 int ret;
226 int err;
227 const int file_fd = connection->response->fd; 229 const int file_fd = connection->response->fd;
228 uint64_t left; 230 uint64_t left;
229 uint64_t offsetu64; 231 uint64_t offsetu64;
@@ -236,61 +238,60 @@ sendfile_adapter (struct MHD_Connection *connection)
236 238
237 offsetu64 = connection->response_write_position + connection->response->fd_off; 239 offsetu64 = connection->response_write_position + connection->response->fd_off;
238 left = connection->response->total_size - connection->response_write_position; 240 left = connection->response->total_size - connection->response_write_position;
239 ret = 0; 241 if (left > SSIZE_MAX)
242 left = SSIZE_MAX;
240#ifndef HAVE_SENDFILE64 243#ifndef HAVE_SENDFILE64
241 if ((uint64_t)OFF_T_MAX < offsetu64) 244 if ((uint64_t)OFF_T_MAX < offsetu64)
242 MHD_socket_set_error_to_ENOMEM (); 245 { /* Retry to send with standard 'send()'. */
243 else 246 connection->resp_sender = MHD_resp_sender_std;
244 { 247 return MHD_ERR_AGAIN_;
245 offset = (off_t) offsetu64; 248 }
246 ret = sendfile (connection->socket_fd, 249 offset = (off_t) offsetu64;
247 file_fd, 250 ret = sendfile (connection->socket_fd,
248 &offset, 251 file_fd,
249 left); 252 &offset,
250 } 253 left);
251#else /* HAVE_SENDFILE64 */ 254#else /* HAVE_SENDFILE64 */
252 if ((uint64_t)OFF64_T_MAX < offsetu64) 255 if ((uint64_t)OFF64_T_MAX < offsetu64)
253 MHD_socket_set_error_to_ENOMEM (); 256 { /* Retry to send with standard 'send()'. */
254 else 257 connection->resp_sender = MHD_resp_sender_std;
255 { 258 return MHD_ERR_AGAIN_;
256 offset = (off64_t) offsetu64;
257 ret = sendfile64 (connection->socket_fd,
258 file_fd,
259 &offset,
260 left);
261 } 259 }
260 offset = (off64_t) offsetu64;
261 ret = sendfile64 (connection->socket_fd,
262 file_fd,
263 &offset,
264 left);
262#endif /* HAVE_SENDFILE64 */ 265#endif /* HAVE_SENDFILE64 */
263 if (0 < ret) 266 if (0 > ret)
264 { 267 {
265 /* write successful */ 268 const int err = MHD_socket_get_error_();
269 if (MHD_SCKT_ERR_IS_EAGAIN_(err))
270 {
266#ifdef EPOLL_SUPPORT 271#ifdef EPOLL_SUPPORT
267 if (left > (uint64_t)ret) 272 /* EAGAIN --- no longer write-ready */
268 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 273 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
269#endif /* EPOLL_SUPPORT */ 274#endif /* EPOLL_SUPPORT */
270 return ret; 275 return MHD_ERR_AGAIN_;
276 }
277 if (MHD_SCKT_ERR_IS_EINTR_ (err))
278 return MHD_ERR_AGAIN_;
279 if (MHD_SCKT_ERR_IS_(err,
280 MHD_SCKT_EBADF_))
281 return MHD_ERR_BADF_;
282 /* sendfile() failed with EINVAL if mmap()-like operations are not
283 supported for FD or other 'unusual' errors occurred, so we should try
284 to fall back to 'SEND'; see also this thread for info on
285 odd libc/Linux behavior with sendfile:
286 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
287 connection->resp_sender = MHD_resp_sender_std;
288 return MHD_ERR_AGAIN_;
271 } 289 }
272 err = MHD_socket_get_error_();
273#ifdef EPOLL_SUPPORT 290#ifdef EPOLL_SUPPORT
274 if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) ) 291 else if (left > (uint64_t)ret)
275 { 292 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
276 /* EAGAIN --- no longer write-ready */ 293#endif /* EPOLL_SUPPORT */
277 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; 294 return ret;
278 }
279#endif
280 if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
281 MHD_SCKT_ERR_IS_EAGAIN_ (err))
282 return 0;
283 if (MHD_SCKT_ERR_IS_(err,
284 MHD_SCKT_EBADF_))
285 return -1;
286 /* sendfile() failed with EINVAL if mmap()-like operations are not
287 supported for FD or other 'unusual' errors occurred, so we should try
288 to fall back to 'SEND'; see also this thread for info on
289 odd libc/Linux behavior with sendfile:
290 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
291 connection->resp_sender = MHD_resp_sender_std;
292 MHD_socket_set_error_ (MHD_SCKT_EAGAIN_);
293 return 0;
294} 295}
295#endif /* __linux__ */ 296#endif /* __linux__ */
296 297
@@ -2786,16 +2787,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2786 connection->continue_message_write_offset); 2787 connection->continue_message_write_offset);
2787 if (ret < 0) 2788 if (ret < 0)
2788 { 2789 {
2789 const int err = MHD_socket_get_error_ (); 2790 if (MHD_ERR_AGAIN_ == ret)
2790
2791 if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
2792 MHD_SCKT_ERR_IS_EAGAIN_ (err))
2793 break; 2791 break;
2794#ifdef HAVE_MESSAGES 2792#ifdef HAVE_MESSAGES
2795 MHD_DLOG (connection->daemon, 2793 MHD_DLOG (connection->daemon,
2796 _("Failed to send data in request for %s: %s\n"), 2794 _("Failed to send data in request for %s.\n"),
2797 connection->url, 2795 connection->url);
2798 MHD_socket_strerr_ (err));
2799#endif 2796#endif
2800 CONNECTION_CLOSE_ERROR (connection, 2797 CONNECTION_CLOSE_ERROR (connection,
2801 NULL); 2798 NULL);
@@ -2824,9 +2821,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2824 connection->write_buffer_send_offset); 2821 connection->write_buffer_send_offset);
2825 if (ret < 0) 2822 if (ret < 0)
2826 { 2823 {
2827 const int err = MHD_socket_get_error_ (); 2824 if (MHD_ERR_AGAIN_ == ret)
2828 if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
2829 MHD_SCKT_ERR_IS_EAGAIN_ (err))
2830 break; 2825 break;
2831 CONNECTION_CLOSE_ERROR (connection, 2826 CONNECTION_CLOSE_ERROR (connection,
2832 _("Connection was closed while sending response headers.\n")); 2827 _("Connection was closed while sending response headers.\n"));
@@ -2889,9 +2884,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2889 MHD_mutex_unlock_chk_ (&response->mutex); 2884 MHD_mutex_unlock_chk_ (&response->mutex);
2890 if (ret < 0) 2885 if (ret < 0)
2891 { 2886 {
2892 err = MHD_socket_get_error_ (); 2887 if (MHD_ERR_AGAIN_ == ret)
2893 if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
2894 MHD_SCKT_ERR_IS_EAGAIN_ (err))
2895 return MHD_YES; 2888 return MHD_YES;
2896#ifdef HAVE_MESSAGES 2889#ifdef HAVE_MESSAGES
2897 MHD_DLOG (connection->daemon, 2890 MHD_DLOG (connection->daemon,
@@ -2921,9 +2914,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2921 connection->write_buffer_send_offset); 2914 connection->write_buffer_send_offset);
2922 if (ret < 0) 2915 if (ret < 0)
2923 { 2916 {
2924 const int err = MHD_socket_get_error_ (); 2917 if (MHD_ERR_AGAIN_ == ret)
2925 if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
2926 MHD_SCKT_ERR_IS_EAGAIN_ (err))
2927 break; 2918 break;
2928 CONNECTION_CLOSE_ERROR (connection, 2919 CONNECTION_CLOSE_ERROR (connection,
2929 _("Connection was closed while sending response body.\n")); 2920 _("Connection was closed while sending response body.\n"));
@@ -2951,9 +2942,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
2951 connection->write_buffer_send_offset); 2942 connection->write_buffer_send_offset);
2952 if (ret < 0) 2943 if (ret < 0)
2953 { 2944 {
2954 const int err = MHD_socket_get_error_ (); 2945 if (MHD_ERR_AGAIN_ == ret)
2955 if (MHD_SCKT_ERR_IS_EINTR_ (err) ||
2956 MHD_SCKT_ERR_IS_EAGAIN_ (err))
2957 break; 2946 break;
2958 CONNECTION_CLOSE_ERROR (connection, 2947 CONNECTION_CLOSE_ERROR (connection,
2959 _("Connection was closed while sending response body.\n")); 2948 _("Connection was closed while sending response body.\n"));