]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: don't close when redirect location doesn't start with "/"
authorWilly Tarreau <w@1wt.eu>
Tue, 28 Feb 2017 08:48:11 +0000 (09:48 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 Feb 2017 08:48:11 +0000 (09:48 +0100)
In 1.4-dev5 when we started to implement keep-alive, commit a9679ac
("[MINOR] http: make the conditional redirect support keep-alive")
added a specific check was added to support keep-alive on redirect
rules but only when the location would start with a "/" indicating
the client would come back to the same server.

But nowadays most applications put http:// or https:// in front of
each and every location, and continuing to perform a close there is
counter-efficient, especially when multiple objects are fetched at
once from a same origin which redirects them to the correct origin
(eg: after an http to https forced upgrade).

It's about time to get rid of this old trick as it causes more harm
than good at an era where persistent connections are omnipresent.

Special thanks to Ciprian Dorin Craciun for providing convincing
arguments with a pretty valid use case and proposing this draft
patch which addresses the issue he was facing.

This change although not exactly a bug fix should be backported
to 1.7 to adapt better to existing infrastructure.

src/proto_http.c

index 5ad295676ac23a48bfcfe9583c764fa3e41fd322..2d567c16aeede8de2a410f9f16ef769ede37bc5b 100644 (file)
@@ -4032,7 +4032,6 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
        struct http_msg *req = &txn->req;
        struct http_msg *res = &txn->rsp;
        const char *msg_fmt;
-       const char *location;
        struct chunk *chunk;
        int ret = 0;
 
@@ -4063,8 +4062,6 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
        if (unlikely(!chunk_strcpy(chunk, msg_fmt)))
                goto leave;
 
-       location = chunk->str + chunk->len;
-
        switch(rule->type) {
        case REDIRECT_TYPE_SCHEME: {
                const char *path;
@@ -4228,17 +4225,12 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
                chunk->len += rule->cookie_len;
        }
 
-       /* add end of headers and the keep-alive/close status.
-        * We may choose to set keep-alive if the Location begins
-        * with a slash, because the client will come back to the
-        * same server.
-        */
+       /* add end of headers and the keep-alive/close status. */
        txn->status = rule->code;
        /* let's log the request time */
        s->logs.tv_request = now;
 
-       if (*location == '/' &&
-           (req->flags & HTTP_MSGF_XFER_LEN) &&
+       if ((req->flags & HTTP_MSGF_XFER_LEN) &&
            ((!(req->flags & HTTP_MSGF_TE_CHNK) && !req->body_len) || (req->msg_state == HTTP_MSG_DONE)) &&
            ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL ||
             (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL)) {