Hi,

By investigating a keep-alive issue with CloudFlare, we[1] found that when 
using the 'set-cookie' option in a redirect (302) HAproxy is adding an extra 
`\r\n`.

Triggering rule :

`http-request redirect location / set-cookie Cookie=value if [...]`

Expected result :

```
HTTP/1.1 302 Found
Cache-Control: no-cache
Content-length: 0
Location: /
Set-Cookie: Cookie=value; path=/;
Connection: close
```

Actual result :

```
HTTP/1.1 302 Found
Cache-Control: no-cache
Content-length: 0
Location: /
Set-Cookie: Cookie=value; path=/;

Connection: close
```

This extra `\r\n` seems to be harmless with another HAproxy instance in front 
of it (sanitizing) or when using a browser. But we confirm that the CloudFlare 
NGINX implementation is not able to handle this. It seems that both 
'Content-length: 0' and extra carriage return broke RFC (to be confirmed).

When looking into the code, this carriage-return was already present in 1.3.X 
versions but just before closing the connection which was ok I think. Then, 
with 1.4.X the keep-alive feature was added and this piece of code remains 
unchanged.

I've quickly done a 'patch' (see attachment) for Debian / HAproxy 1.6.10 
package, you might want to have a look.

That said, HAproxy is a fantastic project : keep up the good work guys !

-
[1] all credit for the bug finding goes to CloudFlare Support Team

--
Matthieu Guégan
System Administrator
+41 21 544 28 00

Virtua S.A., Gottaz 36, 1110 Morges

LINKEDIN // https://www.linkedin.com/in/mguegan
PGP/GPG // 0xCAD6A672
Index: haproxy-1.6.10/src/proto_http.c
===================================================================
--- haproxy-1.6.10.orig/src/proto_http.c        2016-11-20 21:42:20.000000000 +0000
+++ haproxy-1.6.10/src/proto_http.c     2016-12-05 08:56:56.503178620 +0000
@@ -4236,8 +4236,6 @@
                trash.len += 14;
                memcpy(trash.str + trash.len, rule->cookie_str, rule->cookie_len);
                trash.len += rule->cookie_len;
-               memcpy(trash.str + trash.len, "\r\n", 2);
-               trash.len += 2;
        }

        /* add end of headers and the keep-alive/close status.

Reply via email to