Hi Finn Arne,

On Mon, Feb 24, 2014 at 01:44:46PM +0100, Finn Arne Gangstad wrote:
> For clients that are keeping their connection open, 503 replies from
> haproxy seem to be silenced. The connection is just closed without sending
> the 503 reply, if an earlier request has already been served on the same
> connection.
> 
> git bisect tells me this appeared in
> 6b726adb35d998eb55671c0d98ef889cb9fd64ab, MEDIUM: http: do not report
> connection errors for second and further requests
> 
> This kills haproxy in all our production setups since we base pretty much
> all monitoring and small time static file serving on empty haproxy backends
> with more or less clever 503 error files. As far as I can see, none of the
> clients (will) retry the request.

Indeed, I forgot about this usage... I think that we'll really need the
return directive to get rid of this definitely.

Anyway, could you please try with the following patch ? It limits
the test to errors resulting from a reuse of the *same* server-side
connection, which does not happen when you "abuse" the 503 to return
static contents. Normally it should be OK.

I'm waiting for your confirmation before merging it.

Thanks,
Willy

diff --git a/include/types/session.h b/include/types/session.h
index 9b5a5bf..02772a8 100644
--- a/include/types/session.h
+++ b/include/types/session.h
@@ -89,6 +89,7 @@
 #define SN_IGNORE_PRST 0x00080000      /* ignore persistence */
 
 #define SN_COMP_READY   0x00100000     /* the compression is initialized */
+#define SN_SRV_REUSED   0x00200000     /* the server-side connection was 
reused */
 
 /* WARNING: if new fields are added, they must be initialized in 
session_accept()
  * and freed in session_free() !
diff --git a/src/backend.c b/src/backend.c
index e561919..4d0dda1 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1072,6 +1072,7 @@ int connect_server(struct session *s)
        else {
                /* the connection is being reused, just re-attach it */
                si_attach_conn(s->req->cons, srv_conn);
+               s->flags |= SN_SRV_REUSED;
        }
 
        /* flag for logging source ip/port */
diff --git a/src/proto_http.c b/src/proto_http.c
index 1f31dd0..ceae4b9 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -992,7 +992,7 @@ void http_return_srv_error(struct session *s, struct 
stream_interface *si)
                                  http_error_message(s, HTTP_ERR_503));
        else if (err_type & SI_ET_CONN_ERR)
                http_server_error(s, si, SN_ERR_SRVCL, SN_FINST_C,
-                                 503, (s->txn.flags & TX_NOT_FIRST) ? NULL :
+                                 503, (s->flags & SN_SRV_REUSED) ? NULL :
                                  http_error_message(s, HTTP_ERR_503));
        else if (err_type & SI_ET_CONN_RES)
                http_server_error(s, si, SN_ERR_RESOURCE, SN_FINST_C,
@@ -4461,7 +4461,7 @@ void http_end_txn_clean_session(struct session *s)
        s->req->flags &= 
~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT);
        s->rep->flags &= 
~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ATTACHED|CF_READ_ERROR|CF_READ_NOEXP|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_PARTIAL|CF_NEVER_WAIT);
        s->flags &= 
~(SN_DIRECT|SN_ASSIGNED|SN_ADDR_SET|SN_BE_ASSIGNED|SN_FORCE_PRST|SN_IGNORE_PRST);
-       s->flags &= ~(SN_CURR_SESS|SN_REDIRECTABLE);
+       s->flags &= ~(SN_CURR_SESS|SN_REDIRECTABLE|SN_SRV_REUSED);
 
        if (s->flags & SN_COMP_READY)
                s->comp_algo->end(&s->comp_ctx);

Reply via email to