diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2015-11-25 18:45:22 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2015-11-25 18:45:22 +0000 |
commit | 602a14fb5d0e81e1f59bf8e1012cbb034d978fe4 (patch) | |
tree | bc4eb55a5e4c79ca7f2d96cb8ef6bb97d794fda8 /src/microhttpd | |
parent | bd05eb27037144c3058c30dc20640d4b1ffa68a3 (diff) | |
download | libmicrohttpd-602a14fb5d0e81e1f59bf8e1012cbb034d978fe4.tar.gz libmicrohttpd-602a14fb5d0e81e1f59bf8e1012cbb034d978fe4.zip |
Reduce last packet response delay observable with keep-alive on BSD and Darwin platforms
Diffstat (limited to 'src/microhttpd')
-rw-r--r-- | src/microhttpd/connection.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 3878f13a..9a65cfa3 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -2422,14 +2422,29 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
2422 | } | 2422 | } |
2423 | connection->state = MHD_CONNECTION_HEADERS_SENDING; | 2423 | connection->state = MHD_CONNECTION_HEADERS_SENDING; |
2424 | 2424 | ||
2425 | #if HAVE_DECL_TCP_CORK | 2425 | /* starting send, prefer fill full buffer before sending */ |
2426 | /* starting header send, set TCP cork */ | 2426 | #if defined(TCP_CORK) |
2427 | { | 2427 | { /* Send only full packets */ |
2428 | const _MHD_SOCKOPT_BOOL_TYPE val = 1; | 2428 | const _MHD_SOCKOPT_BOOL_TYPE val = 1; |
2429 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val, | 2429 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val, |
2430 | sizeof (val)); | 2430 | sizeof (val)); |
2431 | } | 2431 | } |
2432 | #endif | 2432 | #elif defined(TCP_NODELAY) || defined(TCP_NOPUSH) |
2433 | #if defined(TCP_NOPUSH) | ||
2434 | { /* Buffer data before sending */ | ||
2435 | const _MHD_SOCKOPT_BOOL_TYPE on_val = 1; | ||
2436 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NOPUSH, (const void*)&on_val, | ||
2437 | sizeof (on_val)); | ||
2438 | } | ||
2439 | #endif /* TCP_NOPUSH */ | ||
2440 | #if defined(TCP_NODELAY) | ||
2441 | { /* Enable Nagle's algorithm, even if it was disabled somehow */ | ||
2442 | const _MHD_SOCKOPT_BOOL_TYPE off_val = 0; | ||
2443 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&off_val, | ||
2444 | sizeof (off_val)); | ||
2445 | } | ||
2446 | #endif /* TCP_NODELAY */ | ||
2447 | #endif /* TCP_NODELAY || TCP_NOPUSH */ | ||
2433 | break; | 2448 | break; |
2434 | case MHD_CONNECTION_HEADERS_SENDING: | 2449 | case MHD_CONNECTION_HEADERS_SENDING: |
2435 | /* no default action */ | 2450 | /* no default action */ |
@@ -2506,14 +2521,35 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
2506 | /* no default action */ | 2521 | /* no default action */ |
2507 | break; | 2522 | break; |
2508 | case MHD_CONNECTION_FOOTERS_SENT: | 2523 | case MHD_CONNECTION_FOOTERS_SENT: |
2509 | #if HAVE_DECL_TCP_CORK | 2524 | /* done sending, send last partial packet immediately if possible */ |
2510 | /* done sending, uncork */ | 2525 | #if defined(TCP_CORK) |
2511 | { | 2526 | { /* Flush buffered data, allow partial packets */ |
2512 | const _MHD_SOCKOPT_BOOL_TYPE val = 0; | 2527 | const _MHD_SOCKOPT_BOOL_TYPE val = 0; |
2513 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val, | 2528 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &val, |
2514 | sizeof (val)); | 2529 | sizeof (val)); |
2515 | } | 2530 | } |
2516 | #endif | 2531 | #elif defined(TCP_NODELAY) || defined(TCP_NOPUSH) |
2532 | #if defined(TCP_NODELAY) | ||
2533 | { /* Disable Nagle's algorithm to push partial packet */ | ||
2534 | const _MHD_SOCKOPT_BOOL_TYPE on_val = 1; | ||
2535 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&on_val, | ||
2536 | sizeof (on_val)); | ||
2537 | } | ||
2538 | #endif /* TCP_NODELAY */ | ||
2539 | #if defined(TCP_NOPUSH) | ||
2540 | { /* Send data without extra buffering, may flush pending data on some platforms */ | ||
2541 | const _MHD_SOCKOPT_BOOL_TYPE off_val = 0; | ||
2542 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NOPUSH, (const void*)&off_val, | ||
2543 | sizeof (off_val)); | ||
2544 | } | ||
2545 | #endif /* TCP_NOPUSH */ | ||
2546 | { /* force flush data with zero send otherwise Darwin and some BSD systems | ||
2547 | will add 5 seconds delay */ | ||
2548 | const int dummy = 0; | ||
2549 | (void)send (connection->socket_fd, (const void*)&dummy, 0, 0); | ||
2550 | } | ||
2551 | #endif /* TCP_NODELAY || TCP_NOPUSH */ | ||
2552 | |||
2517 | end = | 2553 | end = |
2518 | MHD_get_response_header (connection->response, | 2554 | MHD_get_response_header (connection->response, |
2519 | MHD_HTTP_HEADER_CONNECTION); | 2555 | MHD_HTTP_HEADER_CONNECTION); |
@@ -2557,6 +2593,12 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) | |||
2557 | else | 2593 | else |
2558 | { | 2594 | { |
2559 | /* can try to keep-alive */ | 2595 | /* can try to keep-alive */ |
2596 | #if !defined(TCP_CORK) && defined(TCP_NODELAY) | ||
2597 | /* Enable Nagle's algorithm */ | ||
2598 | const _MHD_SOCKOPT_BOOL_TYPE off_val = 0; | ||
2599 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&off_val, | ||
2600 | sizeof (off_val)); | ||
2601 | #endif /* !TCP_CORK && TCP_NODELAY */ | ||
2560 | connection->version = NULL; | 2602 | connection->version = NULL; |
2561 | connection->state = MHD_CONNECTION_INIT; | 2603 | connection->state = MHD_CONNECTION_INIT; |
2562 | /* Reset the read buffer to the starting size, | 2604 | /* Reset the read buffer to the starting size, |