summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2009-07-14 19:21:50 +0200
committerWilly Tarreau <w@1wt.eu>2009-07-14 20:24:27 +0200
commit77cb0671427453e3bc18ed2232fd7f5da94b6482 (patch)
treecfdbcef87bdb06bf5e1088455cf24b7006e8b9c5 /src
parentb6b8f478e2a54a5c99f7d034fd7bc24925cf5309 (diff)
downloadhaproxy-77cb0671427453e3bc18ed2232fd7f5da94b6482.tar.gz
[BUG] stream_sock: always shutdown(SHUT_WR) before closing
When we close a socket with unread data in the buffer, or when the nolinger option is set, we regularly lose the last fragment, which often contains the error message. This typically occurs when sending too large a request. Only the RST is seen due to the close() (since not all data were read) and the output message never reaches the network. Doing a shutdown() before the close() solves this annoying issue because the data are really pushed before the system sends the RST. (cherry picked from commit 720058cdcbd5285dc4e4a48216b10c9b96000141)
Diffstat (limited to 'src')
-rw-r--r--src/stream_sock.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/stream_sock.c b/src/stream_sock.c
index 82bf8caf6..80d4996a7 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -787,11 +787,16 @@ void stream_sock_shutw(struct stream_interface *si)
switch (si->state) {
case SI_ST_EST:
- if (!(si->ib->flags & BF_SHUTR)) {
- EV_FD_CLR(si->fd, DIR_WR);
- shutdown(si->fd, SHUT_WR);
+ /* we have to shut before closing, otherwise some short messages
+ * may never leave the system, especially when there are remaining
+ * unread data in the socket input buffer, or when nolinger is set.
+ */
+ EV_FD_CLR(si->fd, DIR_WR);
+ shutdown(si->fd, SHUT_WR);
+
+ if (!(si->ib->flags & BF_SHUTR))
return;
- }
+
/* fall through */
case SI_ST_CON:
/* we may have to close a pending connection, and mark the