Hi Ryan,
> I recently started investigating using HAProxy to ensure that multiple
> WebSocket connections from the same browser (or device) end up
> communicating with the same application server. Forwarding all
> connections from the same origin to the respective application server
> greatly reduces the complexity on the application.
>
> My setup is simple: 1 HAProxy in front, 2 App servers on the back. The
> browser makes several connections via WebSockets (using ws:// or
> wss://). My goal is to have those connections all go to the same app
> server. When a new browser is opened on another PC or device then those
> will go to the other server (round-robin), etc.
>
> HAProxy was easy enough to configure and I decided to use the cookie
> injection persistence method rather than URL parameter, HTTP header
> field, or cookie modification (e.g. JSESSIONID) since it seemed the
> most transparent and straightforward. However, I noticed it wasn't
> forwarding the subsequent WebSocket connections to the same application
> server. I started to sniff the packets to see what the HTTP response
> from HAProxy looked like and found that the cookie wasn't present. I
> did notice, however, that the cookie was present with non-WebSocket
> HTTP responses. This led me to the source code proto_http.c to see if
> there was any code that treated WebSocket handshakes differently.
> Nothing really stood out. However, I did notice that around line 6305
> there is a check for status codes less than 200. In the event that the
> status code is less than 200 it skips the header mangling. Note that
> WebSocket HTTP responses are usually '101 Switching Protocols'. This
> means that the initial response from the application server will not
> have the cookie injected into the response via HAProxy. If I comment
> out the goto, things work as I would expect.
>
> My question is, is this line really necessary? I understand that the
> HTTP RFC indicates that for 1xx responses that the following header
> fields are optional, but does that mean that the injection should not
> be done? What if I were to update the code so that it was a little more
> stateful and WebSocket aware so that in the event that the
> request/response was WebSockets it would perform the header mangling?
Yes, I wonder if we need this condition at all.
Since commit 628c40cd961d ("MEDIUM: http: move skipping of 100-continue
earlier") a "100 continue" response doesn't even make it to that condition.
Webdav has a "102 Processing" response, but I doubt it would do harm it
if we would add response headers or cookies there.
Of course, to keep the change minimal we could just make an exception
for 101.
Note that the same issue applies to the add-response headers feature,
with the same condition just some 20 lines above this one.
For example, if we would like to enable HSTS but only use HTTP to
upgrade to WS, haproxy would never be able to send the hsts header.
Willy, whats your opinion on this, is there a reason to keep the
condition and make an exception for status 101, or should we remove
the check entirely?
Regards,
Lukas