diff options
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r-- | src/microhttpd/connection.c | 468 |
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 | */ | ||
288 | static ssize_t | ||
289 | sendfile_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 | |||
501 | socket_start_extra_buffering (struct MHD_Connection *connection) | 320 | socket_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 | ||
553 | socket_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 | ||
640 | socket_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; |