diff --git a/include/types/buffers.h b/include/types/buffers.h index fd078fa8c..34189cde0 100644 --- a/include/types/buffers.h +++ b/include/types/buffers.h @@ -112,6 +112,7 @@ #define BF_AUTO_CONNECT 0x800000 /* consumer may attempt to establish a new connection */ #define BF_DONT_READ 0x1000000 /* disable reading for now */ +#define BF_EXPECT_MORE 0x2000000 /* more data expected to be sent very soon (one-shoot) */ /* Use these masks to clear the flags before going back to lower layers */ #define BF_CLEAR_READ (~(BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR|BF_READ_ATTACHED)) diff --git a/src/proto_http.c b/src/proto_http.c index d8dc7113e..5cc0f23e0 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3497,6 +3497,13 @@ int http_request_forward_body(struct session *s, struct buffer *req, int an_bit) if (s->be->options2 & PR_O2_INDEPSTR) s->req->cons->flags |= SI_FL_INDEP_STR; + /* if the request buffer is not empty, it means we're + * about to process another request, so send pending + * data with MSG_MORE to merge TCP packets when possible. + */ + if (s->req->l) + s->rep->flags |= BF_EXPECT_MORE; + /* make ->lr point to the first non-forwarded byte */ s->req->lr = s->req->w + s->req->send_max; if (s->req->lr >= s->req->data + s->req->size) diff --git a/src/stream_sock.c b/src/stream_sock.c index 7e9dd2c2f..4a9434c4f 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -608,16 +608,20 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b) * tests. */ - if (MSG_NOSIGNAL) { + if (MSG_NOSIGNAL && MSG_MORE) { unsigned int send_flag = MSG_DONTWAIT | MSG_NOSIGNAL; - if (MSG_MORE && - ((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) || + if (((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) || ((b->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK)) == BF_SHUTW_NOW && (max == b->send_max)) || (max != b->l && max != b->send_max)) && (fdtab[si->fd].flags & FD_FL_TCP)) { send_flag |= MSG_MORE; } + else if (b->flags & BF_EXPECT_MORE) { + /* it was forced on the buffer, this flag is one-shoot */ + b->flags &= ~BF_EXPECT_MORE; + send_flag |= MSG_MORE; + } ret = send(si->fd, b->w, max, send_flag); } else {