[MEDIUM] http: add support for "http-no-delay"
There are some very rare server-to-server applications that abuse the HTTP
protocol and expect the payload phase to be highly interactive, with many
interleaved data chunks in both directions within a single request. This is
absolutely not supported by the HTTP specification and will not work across
most proxies or servers. When such applications attempt to do this through
haproxy, it works but they will experience high delays due to the network
optimizations which favor performance by instructing the system to wait for
enough data to be available in order to only send full packets. Typical
delays are around 200 ms per round trip. Note that this only happens with
abnormal uses. Normal uses such as CONNECT requests nor WebSockets are not
affected.
When "option http-no-delay" is present in either the frontend or the backend
used by a connection, all such optimizations will be disabled in order to
make the exchanges as fast as possible. Of course this offers no guarantee on
the functionality, as it may break at any other place. But if it works via
HAProxy, it will work as fast as possible. This option should never be used
by default, and should never be used at all unless such a buggy application
is discovered. The impact of using this option is an increase of bandwidth
usage and CPU usage, which may significantly lower performance in high
latency environments.
This change should be backported to 1.4 since the first report of such a
misuse was in 1.4. Next patch will also be needed.
diff --git a/src/stream_sock.c b/src/stream_sock.c
index 3641b4e..b08134a 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -643,8 +643,9 @@
if (MSG_NOSIGNAL && MSG_MORE) {
unsigned int send_flag = MSG_DONTWAIT | MSG_NOSIGNAL;
- if ((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) ||
- (b->flags & BF_EXPECT_MORE) ||
+ if ((!(b->flags & BF_NEVER_WAIT) &&
+ ((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) ||
+ (b->flags & BF_EXPECT_MORE))) ||
((b->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK)) == BF_SHUTW_NOW && (max == b->send_max)) ||
(max != b->l && max != b->send_max)) {
send_flag |= MSG_MORE;