aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r--src/microhttpd/connection.c468
1 files changed, 78 insertions, 390 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 6f33dbc1..7b630b77 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -53,7 +53,7 @@
53/* For FreeBSD version identification */ 53/* For FreeBSD version identification */
54#include <sys/param.h> 54#include <sys/param.h>
55#endif /* HAVE_SYS_PARAM_H */ 55#endif /* HAVE_SYS_PARAM_H */
56 56#include "mhd_send.h"
57 57
58/** 58/**
59 * Message to transmit when http 1.1 request is received 59 * Message to transmit when http 1.1 request is received
@@ -278,187 +278,6 @@ send_param_adapter (struct MHD_Connection *connection,
278} 278}
279 279
280 280
281#if defined(_MHD_HAVE_SENDFILE)
282/**
283 * Function for sending responses backed by file FD.
284 *
285 * @param connection the MHD connection structure
286 * @return actual number of bytes sent
287 */
288static ssize_t
289sendfile_adapter (struct MHD_Connection *connection)
290{
291 ssize_t ret;
292 const int file_fd = connection->response->fd;
293 uint64_t left;
294 uint64_t offsetu64;
295#ifndef HAVE_SENDFILE64
296 const uint64_t max_off_t = (uint64_t)OFF_T_MAX;
297#else /* HAVE_SENDFILE64 */
298 const uint64_t max_off_t = (uint64_t)OFF64_T_MAX;
299#endif /* HAVE_SENDFILE64 */
300#ifdef MHD_LINUX_SOLARIS_SENDFILE
301#ifndef HAVE_SENDFILE64
302 off_t offset;
303#else /* HAVE_SENDFILE64 */
304 off64_t offset;
305#endif /* HAVE_SENDFILE64 */
306#endif /* MHD_LINUX_SOLARIS_SENDFILE */
307#ifdef HAVE_FREEBSD_SENDFILE
308 off_t sent_bytes;
309 int flags = 0;
310#endif
311#ifdef HAVE_DARWIN_SENDFILE
312 off_t len;
313#endif /* HAVE_DARWIN_SENDFILE */
314 const bool used_thr_p_c = (0 != (connection->daemon->options & MHD_USE_THREAD_PER_CONNECTION));
315 const size_t chunk_size = used_thr_p_c ? MHD_SENFILE_CHUNK_THR_P_C_ : MHD_SENFILE_CHUNK_;
316 size_t send_size = 0;
317 mhd_assert (MHD_resp_sender_sendfile == connection->resp_sender);
318
319 offsetu64 = connection->response_write_position + connection->response->fd_off;
320 left = connection->response->total_size - connection->response_write_position;
321 /* Do not allow system to stick sending on single fast connection:
322 * use 128KiB chunks (2MiB for thread-per-connection). */
323 send_size = (left > chunk_size) ? chunk_size : (size_t) left;
324 if (max_off_t < offsetu64)
325 { /* Retry to send with standard 'send()'. */
326 connection->resp_sender = MHD_resp_sender_std;
327 return MHD_ERR_AGAIN_;
328 }
329#ifdef MHD_LINUX_SOLARIS_SENDFILE
330#ifndef HAVE_SENDFILE64
331 offset = (off_t) offsetu64;
332 ret = sendfile (connection->socket_fd,
333 file_fd,
334 &offset,
335 send_size);
336#else /* HAVE_SENDFILE64 */
337 offset = (off64_t) offsetu64;
338 ret = sendfile64 (connection->socket_fd,
339 file_fd,
340 &offset,
341 send_size);
342#endif /* HAVE_SENDFILE64 */
343 if (0 > ret)
344 {
345 const int err = MHD_socket_get_error_();
346 if (MHD_SCKT_ERR_IS_EAGAIN_(err))
347 {
348#ifdef EPOLL_SUPPORT
349 /* EAGAIN --- no longer write-ready */
350 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
351#endif /* EPOLL_SUPPORT */
352 return MHD_ERR_AGAIN_;
353 }
354 if (MHD_SCKT_ERR_IS_EINTR_ (err))
355 return MHD_ERR_AGAIN_;
356#ifdef HAVE_LINUX_SENDFILE
357 if (MHD_SCKT_ERR_IS_(err,
358 MHD_SCKT_EBADF_))
359 return MHD_ERR_BADF_;
360 /* sendfile() failed with EINVAL if mmap()-like operations are not
361 supported for FD or other 'unusual' errors occurred, so we should try
362 to fall back to 'SEND'; see also this thread for info on
363 odd libc/Linux behavior with sendfile:
364 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
365 connection->resp_sender = MHD_resp_sender_std;
366 return MHD_ERR_AGAIN_;
367#else /* HAVE_SOLARIS_SENDFILE */
368 if ( (EAFNOSUPPORT == err) ||
369 (EINVAL == err) ||
370 (EOPNOTSUPP == err) )
371 { /* Retry with standard file reader. */
372 connection->resp_sender = MHD_resp_sender_std;
373 return MHD_ERR_AGAIN_;
374 }
375 if ( (ENOTCONN == err) ||
376 (EPIPE == err) )
377 {
378 return MHD_ERR_CONNRESET_;
379 }
380 return MHD_ERR_BADF_; /* Fail hard */
381#endif /* HAVE_SOLARIS_SENDFILE */
382 }
383#ifdef EPOLL_SUPPORT
384 else if (send_size > (size_t)ret)
385 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
386#endif /* EPOLL_SUPPORT */
387#elif defined(HAVE_FREEBSD_SENDFILE)
388#ifdef SF_FLAGS
389 flags = used_thr_p_c ?
390 freebsd_sendfile_flags_thd_p_c_ : freebsd_sendfile_flags_;
391#endif /* SF_FLAGS */
392 if (0 != sendfile (file_fd,
393 connection->socket_fd,
394 (off_t) offsetu64,
395 send_size,
396 NULL,
397 &sent_bytes,
398 flags))
399 {
400 const int err = MHD_socket_get_error_();
401 if (MHD_SCKT_ERR_IS_EAGAIN_(err) ||
402 MHD_SCKT_ERR_IS_EINTR_(err) ||
403 EBUSY == err)
404 {
405 mhd_assert (SSIZE_MAX >= sent_bytes);
406 if (0 != sent_bytes)
407 return (ssize_t)sent_bytes;
408
409 return MHD_ERR_AGAIN_;
410 }
411 /* Some unrecoverable error. Possibly file FD is not suitable
412 * for sendfile(). Retry with standard send(). */
413 connection->resp_sender = MHD_resp_sender_std;
414 return MHD_ERR_AGAIN_;
415 }
416 mhd_assert (0 < sent_bytes);
417 mhd_assert (SSIZE_MAX >= sent_bytes);
418 ret = (ssize_t)sent_bytes;
419#elif defined(HAVE_DARWIN_SENDFILE)
420 len = (off_t)send_size; /* chunk always fit */
421 if (0 != sendfile (file_fd,
422 connection->socket_fd,
423 (off_t) offsetu64,
424 &len,
425 NULL,
426 0))
427 {
428 const int err = MHD_socket_get_error_();
429 if (MHD_SCKT_ERR_IS_EAGAIN_(err) ||
430 MHD_SCKT_ERR_IS_EINTR_(err))
431 {
432 mhd_assert (0 <= len);
433 mhd_assert (SSIZE_MAX >= len);
434 mhd_assert (send_size >= (size_t)len);
435 if (0 != len)
436 return (ssize_t)len;
437
438 return MHD_ERR_AGAIN_;
439 }
440 if (ENOTCONN == err ||
441 EPIPE == err)
442 return MHD_ERR_CONNRESET_;
443 if (ENOTSUP == err ||
444 EOPNOTSUPP == err)
445 { /* This file FD is not suitable for sendfile().
446 * Retry with standard send(). */
447 connection->resp_sender = MHD_resp_sender_std;
448 return MHD_ERR_AGAIN_;
449 }
450 return MHD_ERR_BADF_; /* Return hard error. */
451 }
452 mhd_assert (0 <= len);
453 mhd_assert (SSIZE_MAX >= len);
454 mhd_assert (send_size >= (size_t)len);
455 ret = (ssize_t)len;
456#endif /* HAVE_FREEBSD_SENDFILE */
457 return ret;
458}
459#endif /* _MHD_HAVE_SENDFILE */
460
461
462/** 281/**
463 * Check whether is possible to force push socket buffer content as 282 * Check whether is possible to force push socket buffer content as
464 * partial packet. 283 * partial packet.
@@ -501,89 +320,6 @@ _MHD_static_inline bool
501socket_start_extra_buffering (struct MHD_Connection *connection) 320socket_start_extra_buffering (struct MHD_Connection *connection)
502{ 321{
503 mhd_assert(NULL != connection); 322 mhd_assert(NULL != connection);
504#if defined(TCP_NODELAY)
505 if (connection->sk_tcp_nodelay_on)
506 {
507 const MHD_SCKT_OPT_BOOL_ off_val = 0;
508 /* Enable Nagle's algorithm */
509 /* TCP_NODELAY may interfere with TCP_NOPUSH */
510 if (0 == setsockopt (connection->socket_fd,
511 IPPROTO_TCP,
512 TCP_NODELAY,
513 (const void *) &off_val,
514 sizeof (off_val)))
515 {
516 connection->sk_tcp_nodelay_on = false;
517 }
518 }
519#endif /* TCP_NODELAY */
520
521#if defined(MHD_TCP_CORK_NOPUSH)
522 if (!connection->sk_tcp_cork_nopush_on)
523 {
524 const MHD_SCKT_OPT_BOOL_ on_val = 1;
525 /* Buffer data before sending (TCP_CORK) or
526 * Send only full frames (TCP_NOPUSH) */
527 if (0 == setsockopt (connection->socket_fd,
528 IPPROTO_TCP,
529 MHD_TCP_CORK_NOPUSH,
530 (const void *) &on_val,
531 sizeof (on_val)))
532 {
533 connection->sk_tcp_cork_nopush_on = true;
534 }
535 }
536#endif /* MHD_TCP_CORK_NOPUSH */
537
538#if defined(TCP_NODELAY)
539 return connection->sk_tcp_cork_nopush_on && !connection->sk_tcp_nodelay_on;
540#else /* ! TCP_NODELAY */
541 return connection->sk_tcp_cork_nopush_on;
542#endif /* ! TCP_NODELAY */
543}
544
545
546/**
547 * Activate no buffering mode (no delay sending) on connection socket.
548 *
549 * @param connection connection to be processed
550 * @return true on success, false otherwise
551 */
552_MHD_static_inline bool
553socket_start_no_buffering (struct MHD_Connection *connection)
554{
555#if defined(MHD_TCP_CORK_NOPUSH)
556 if (connection->sk_tcp_cork_nopush_on)
557 {
558 const MHD_SCKT_OPT_BOOL_ off_val = 0;
559 /* Disable extra buffering */
560 if (0 == setsockopt (connection->socket_fd,
561 IPPROTO_TCP,
562 MHD_TCP_CORK_NOPUSH,
563 (const void *) &off_val,
564 sizeof (off_val)))
565 {
566 connection->sk_tcp_cork_nopush_on = false;
567 }
568 }
569#endif /* MHD_TCP_CORK_NOPUSH */
570
571#if defined(TCP_NODELAY)
572 if (!connection->sk_tcp_nodelay_on)
573 {
574 const MHD_SCKT_OPT_BOOL_ on_val = 1;
575 /* Enable sending without delay */
576 if (0 == setsockopt (connection->socket_fd,
577 IPPROTO_TCP,
578 TCP_NODELAY,
579 (const void *) &on_val,
580 sizeof (on_val)))
581 {
582 connection->sk_tcp_nodelay_on = true;
583 }
584 }
585#endif /* TCP_NODELAY */
586 return connection->sk_tcp_nodelay_on && !connection->sk_tcp_cork_nopush_on;
587} 323}
588 324
589 325
@@ -601,21 +337,7 @@ socket_start_no_buffering_flush (struct MHD_Connection *connection)
601#if defined(TCP_NOPUSH) && !defined(TCP_CORK) 337#if defined(TCP_NOPUSH) && !defined(TCP_CORK)
602 const int dummy = 0; 338 const int dummy = 0;
603#endif /* !TCP_CORK */ 339#endif /* !TCP_CORK */
604#if defined(TCP_CORK) || (defined(__FreeBSD__) && __FreeBSD__+0 >= 9)
605 const MHD_SCKT_OPT_BOOL_ off_val = 0;
606 /* Switching off TCP_CORK flush buffer even
607 * if TCP_CORK was not enabled */
608 if (0 == setsockopt (connection->socket_fd,
609 IPPROTO_TCP,
610 MHD_TCP_CORK_NOPUSH,
611 (const void *) &off_val,
612 sizeof (off_val)))
613 {
614 connection->sk_tcp_cork_nopush_on = false;
615 }
616#endif /* MHD_TCP_CORK_NOPUSH */
617 340
618 res = socket_start_no_buffering (connection);
619#if defined(__FreeBSD__) && __FreeBSD__+0 >= 9 341#if defined(__FreeBSD__) && __FreeBSD__+0 >= 9
620 /* FreeBSD do not need zero-send for flushing starting from version 9 */ 342 /* FreeBSD do not need zero-send for flushing starting from version 9 */
621#elif defined(TCP_NOPUSH) && !defined(TCP_CORK) 343#elif defined(TCP_NOPUSH) && !defined(TCP_CORK)
@@ -631,51 +353,6 @@ socket_start_no_buffering_flush (struct MHD_Connection *connection)
631 353
632 354
633/** 355/**
634 * Activate normal buffering mode on connection socket.
635 *
636 * @param connection connection to be processed
637 * @return true on success, false otherwise
638 */
639_MHD_static_inline bool
640socket_start_normal_buffering (struct MHD_Connection *connection)
641{
642 mhd_assert(NULL != connection);
643#if defined(MHD_TCP_CORK_NOPUSH)
644 if (connection->sk_tcp_cork_nopush_on)
645 {
646 const MHD_SCKT_OPT_BOOL_ off_val = 0;
647 /* Disable extra buffering */
648 if (0 == setsockopt (connection->socket_fd,
649 IPPROTO_TCP,
650 MHD_TCP_CORK_NOPUSH,
651 (const void *) &off_val,
652 sizeof (off_val)))
653 {
654 connection->sk_tcp_cork_nopush_on = false;
655 }
656 }
657#endif /* MHD_TCP_CORK_NOPUSH */
658
659#if defined(TCP_NODELAY)
660 if (connection->sk_tcp_nodelay_on)
661 {
662 const MHD_SCKT_OPT_BOOL_ off_val = 0;
663 /* Enable Nagle's algorithm */
664 if (0 == setsockopt (connection->socket_fd,
665 IPPROTO_TCP,
666 TCP_NODELAY,
667 (const void *) &off_val,
668 sizeof (off_val)))
669 {
670 connection->sk_tcp_nodelay_on = false;
671 }
672 }
673#endif /* TCP_NODELAY */
674 return !connection->sk_tcp_nodelay_on && !connection->sk_tcp_cork_nopush_on;
675}
676
677
678/**
679 * Get all of the headers from the request. 356 * Get all of the headers from the request.
680 * 357 *
681 * @param connection connection to get values from 358 * @param connection connection to get values from
@@ -3315,11 +2992,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3315 case MHD_CONNECTION_HEADERS_PROCESSED: 2992 case MHD_CONNECTION_HEADERS_PROCESSED:
3316 return; 2993 return;
3317 case MHD_CONNECTION_CONTINUE_SENDING: 2994 case MHD_CONNECTION_CONTINUE_SENDING:
3318 ret = connection->send_cls (connection, 2995 ret = MHD_send_on_connection_ (connection,
3319 &HTTP_100_CONTINUE 2996 &HTTP_100_CONTINUE
3320 [connection->continue_message_write_offset], 2997 [connection->continue_message_write_offset],
3321 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE) - 2998 MHD_STATICSTR_LEN_ (HTTP_100_CONTINUE) -
3322 connection->continue_message_write_offset); 2999 connection->continue_message_write_offset,
3000 MHD_SSO_NO_CORK);
3323 if (ret < 0) 3001 if (ret < 0)
3324 { 3002 {
3325 if (MHD_ERR_AGAIN_ == ret) 3003 if (MHD_ERR_AGAIN_ == ret)
@@ -3349,26 +3027,55 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3349 mhd_assert (0); 3027 mhd_assert (0);
3350 return; 3028 return;
3351 case MHD_CONNECTION_HEADERS_SENDING: 3029 case MHD_CONNECTION_HEADERS_SENDING:
3352 ret = connection->send_cls (connection, 3030 {
3353 &connection->write_buffer 3031 const size_t wb_ready = connection->write_buffer_append_offset -
3354 [connection->write_buffer_send_offset], 3032 connection->write_buffer_send_offset;
3355 connection->write_buffer_append_offset - 3033
3356 connection->write_buffer_send_offset); 3034 /* if the response body is not available, we use MHD_send_on_connection_() */
3357 if (ret < 0) 3035 if (NULL != connection->response->crc)
3358 { 3036 {
3359 if (MHD_ERR_AGAIN_ == ret) 3037 ret = MHD_send_on_connection_ (connection,
3038 &connection->write_buffer
3039 [connection->write_buffer_send_offset],
3040 wb_ready,
3041 MHD_SSO_MAY_CORK);
3042 }
3043 else
3044 {
3045 ret = MHD_send_on_connection2_ (connection,
3046 &connection->write_buffer
3047 [connection->write_buffer_send_offset],
3048 wb_ready,
3049 connection->response->data,
3050 connection->response->data_buffer_size);
3051 }
3052
3053 if (ret < 0)
3054 {
3055 if (MHD_ERR_AGAIN_ == ret)
3056 return;
3057 CONNECTION_CLOSE_ERROR (connection,
3058 _("Connection was closed while sending response headers.\n"));
3360 return; 3059 return;
3361 CONNECTION_CLOSE_ERROR (connection, 3060 }
3362 _("Connection was closed while sending response headers.\n")); 3061 if (ret > wb_ready)
3062 {
3063 mhd_assert (NULL == connection->repsonse->crc);
3064 /* We sent not just header data but also some response data,
3065 update both offsets! */
3066 connection->write_buffer_send_offset += wb_ready;
3067 ret -= wb_ready;
3068 connection->response_write_position += ret;
3069 }
3070 else
3071 connection->write_buffer_send_offset += ret;
3072 MHD_update_last_activity_ (connection);
3073 if (MHD_CONNECTION_HEADERS_SENDING != connection->state)
3363 return; 3074 return;
3364 } 3075 check_write_done (connection,
3365 connection->write_buffer_send_offset += ret; 3076 MHD_CONNECTION_HEADERS_SENT);
3366 MHD_update_last_activity_ (connection);
3367 if (MHD_CONNECTION_HEADERS_SENDING != connection->state)
3368 return; 3077 return;
3369 check_write_done (connection, 3078 }
3370 MHD_CONNECTION_HEADERS_SENT);
3371 return;
3372 case MHD_CONNECTION_HEADERS_SENT: 3079 case MHD_CONNECTION_HEADERS_SENT:
3373 return; 3080 return;
3374 case MHD_CONNECTION_NORMAL_BODY_READY: 3081 case MHD_CONNECTION_NORMAL_BODY_READY:
@@ -3390,7 +3097,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3390#if defined(_MHD_HAVE_SENDFILE) 3097#if defined(_MHD_HAVE_SENDFILE)
3391 if (MHD_resp_sender_sendfile == connection->resp_sender) 3098 if (MHD_resp_sender_sendfile == connection->resp_sender)
3392 { 3099 {
3393 ret = sendfile_adapter (connection); 3100 ret = MHD_send_sendfile_ (connection);
3394 } 3101 }
3395 else 3102 else
3396#else /* ! _MHD_HAVE_SENDFILE */ 3103#else /* ! _MHD_HAVE_SENDFILE */
@@ -3401,11 +3108,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3401 - response->data_start; 3108 - response->data_start;
3402 if (data_write_offset > (uint64_t)SIZE_MAX) 3109 if (data_write_offset > (uint64_t)SIZE_MAX)
3403 MHD_PANIC (_("Data offset exceeds limit")); 3110 MHD_PANIC (_("Data offset exceeds limit"));
3404 ret = connection->send_cls (connection, 3111 ret = MHD_send_on_connection_ (connection,
3405 &response->data 3112 &response->data
3406 [(size_t)data_write_offset], 3113 [(size_t)data_write_offset],
3407 response->data_size - 3114 response->data_size -
3408 (size_t)data_write_offset); 3115 (size_t)data_write_offset,
3116 MHD_SSO_NO_CORK);
3409#if DEBUG_SEND_DATA 3117#if DEBUG_SEND_DATA
3410 if (ret > 0) 3118 if (ret > 0)
3411 fprintf (stderr, 3119 fprintf (stderr,
@@ -3444,11 +3152,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3444 mhd_assert (0); 3152 mhd_assert (0);
3445 return; 3153 return;
3446 case MHD_CONNECTION_CHUNKED_BODY_READY: 3154 case MHD_CONNECTION_CHUNKED_BODY_READY:
3447 ret = connection->send_cls (connection, 3155 ret = MHD_send_on_connection_ (connection,
3448 &connection->write_buffer 3156 &connection->write_buffer
3449 [connection->write_buffer_send_offset], 3157 [connection->write_buffer_send_offset],
3450 connection->write_buffer_append_offset - 3158 connection->write_buffer_append_offset -
3451 connection->write_buffer_send_offset); 3159 connection->write_buffer_send_offset,
3160 MHD_SSO_NO_CORK);
3452 if (ret < 0) 3161 if (ret < 0)
3453 { 3162 {
3454 if (MHD_ERR_AGAIN_ == ret) 3163 if (MHD_ERR_AGAIN_ == ret)
@@ -3472,11 +3181,12 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3472 mhd_assert (0); 3181 mhd_assert (0);
3473 return; 3182 return;
3474 case MHD_CONNECTION_FOOTERS_SENDING: 3183 case MHD_CONNECTION_FOOTERS_SENDING:
3475 ret = connection->send_cls (connection, 3184 ret = MHD_send_on_connection_ (connection,
3476 &connection->write_buffer 3185 &connection->write_buffer
3477 [connection->write_buffer_send_offset], 3186 [connection->write_buffer_send_offset],
3478 connection->write_buffer_append_offset - 3187 connection->write_buffer_append_offset -
3479 connection->write_buffer_send_offset); 3188 connection->write_buffer_send_offset,
3189 MHD_SSO_HDR_CORK);
3480 if (ret < 0) 3190 if (ret < 0)
3481 { 3191 {
3482 if (MHD_ERR_AGAIN_ == ret) 3192 if (MHD_ERR_AGAIN_ == ret)
@@ -3723,11 +3433,6 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3723 if (need_100_continue (connection)) 3433 if (need_100_continue (connection))
3724 { 3434 {
3725 connection->state = MHD_CONNECTION_CONTINUE_SENDING; 3435 connection->state = MHD_CONNECTION_CONTINUE_SENDING;
3726 if (socket_flush_possible (connection))
3727 socket_start_extra_buffering (connection);
3728 else
3729 socket_start_no_buffering (connection);
3730
3731 break; 3436 break;
3732 } 3437 }
3733 if ( (NULL != connection->response) && 3438 if ( (NULL != connection->response) &&
@@ -3752,9 +3457,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3752 { 3457 {
3753 connection->state = MHD_CONNECTION_CONTINUE_SENT; 3458 connection->state = MHD_CONNECTION_CONTINUE_SENT;
3754 if (socket_flush_possible (connection)) 3459 if (socket_flush_possible (connection))
3755 socket_start_no_buffering_flush (connection); 3460 socket_start_no_buffering_flush (connection); /* REMOVE: Dead */
3756 else
3757 socket_start_normal_buffering (connection);
3758 3461
3759 continue; 3462 continue;
3760 } 3463 }
@@ -3855,11 +3558,6 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3855 continue; 3558 continue;
3856 } 3559 }
3857 connection->state = MHD_CONNECTION_HEADERS_SENDING; 3560 connection->state = MHD_CONNECTION_HEADERS_SENDING;
3858 if (socket_flush_possible (connection))
3859 socket_start_extra_buffering (connection);
3860 else
3861 socket_start_no_buffering (connection);
3862
3863 break; 3561 break;
3864 case MHD_CONNECTION_HEADERS_SENDING: 3562 case MHD_CONNECTION_HEADERS_SENDING:
3865 /* no default action */ 3563 /* no default action */
@@ -3867,12 +3565,11 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3867 case MHD_CONNECTION_HEADERS_SENT: 3565 case MHD_CONNECTION_HEADERS_SENT:
3868 /* Some clients may take some actions right after header receive */ 3566 /* Some clients may take some actions right after header receive */
3869 if (socket_flush_possible (connection)) 3567 if (socket_flush_possible (connection))
3870 socket_start_no_buffering_flush (connection); 3568 socket_start_no_buffering_flush (connection); /* REMOVE: Dead */
3871 3569
3872#ifdef UPGRADE_SUPPORT 3570#ifdef UPGRADE_SUPPORT
3873 if (NULL != connection->response->upgrade_handler) 3571 if (NULL != connection->response->upgrade_handler)
3874 { 3572 {
3875 socket_start_normal_buffering (connection);
3876 connection->state = MHD_CONNECTION_UPGRADE; 3573 connection->state = MHD_CONNECTION_UPGRADE;
3877 /* This connection is "upgraded". Pass socket to application. */ 3574 /* This connection is "upgraded". Pass socket to application. */
3878 if (MHD_YES != 3575 if (MHD_YES !=
@@ -3894,10 +3591,6 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3894 continue; 3591 continue;
3895 } 3592 }
3896#endif /* UPGRADE_SUPPORT */ 3593#endif /* UPGRADE_SUPPORT */
3897 if (socket_flush_possible (connection))
3898 socket_start_extra_buffering (connection);
3899 else
3900 socket_start_normal_buffering (connection);
3901 3594
3902 if (connection->have_chunked_upload) 3595 if (connection->have_chunked_upload)
3903 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY; 3596 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
@@ -3929,8 +3622,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3929#endif 3622#endif
3930 connection->state = MHD_CONNECTION_NORMAL_BODY_READY; 3623 connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
3931 /* Buffering for flushable socket was already enabled*/ 3624 /* Buffering for flushable socket was already enabled*/
3932 if (socket_flush_possible (connection)) 3625
3933 socket_start_no_buffering (connection);
3934 break; 3626 break;
3935 } 3627 }
3936 /* mutex was already unlocked by "try_ready_normal_body */ 3628 /* mutex was already unlocked by "try_ready_normal_body */
@@ -3963,8 +3655,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3963#endif 3655#endif
3964 connection->state = MHD_CONNECTION_CHUNKED_BODY_READY; 3656 connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
3965 /* Buffering for flushable socket was already enabled */ 3657 /* Buffering for flushable socket was already enabled */
3966 if (socket_flush_possible (connection)) 3658
3967 socket_start_no_buffering (connection);
3968 continue; 3659 continue;
3969 } 3660 }
3970 /* mutex was already unlocked by try_ready_chunked_body */ 3661 /* mutex was already unlocked by try_ready_chunked_body */
@@ -3998,9 +3689,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3998 continue; 3689 continue;
3999 } 3690 }
4000 if (socket_flush_possible (connection)) 3691 if (socket_flush_possible (connection))
4001 socket_start_no_buffering_flush (connection); 3692 socket_start_no_buffering_flush (connection); /* REMOVE: Dead */
4002 else
4003 socket_start_normal_buffering (connection);
4004 3693
4005 MHD_destroy_response (connection->response); 3694 MHD_destroy_response (connection->response);
4006 connection->response = NULL; 3695 connection->response = NULL;
@@ -4028,8 +3717,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
4028 else 3717 else
4029 { 3718 {
4030 /* can try to keep-alive */ 3719 /* can try to keep-alive */
4031 if (socket_flush_possible (connection)) 3720
4032 socket_start_normal_buffering (connection);
4033 connection->version = NULL; 3721 connection->version = NULL;
4034 connection->state = MHD_CONNECTION_INIT; 3722 connection->state = MHD_CONNECTION_INIT;
4035 connection->last = NULL; 3723 connection->last = NULL;