From 4c5ea07affa479260a79c58eb04184ff3d085284 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Mon, 15 Mar 2021 23:02:24 +0530 Subject: [PATCH] MM-33836: Detect and upgrade incorrect HTTP version for websocket handshakes (#17142) Our proxy configuration was historically incorrect, due to which a lot of customers have that in their setups. As a result, strictly following the websocket RFC results in a breaking change. For now, we transparently upgrade the version header to 1.1, if we detect 1.0. If a client was sending 1.0, it wouldn't have worked anyways because persistent connections were introduced from 1.1 onwards. https://mattermost.atlassian.net/browse/MM-33836 ```release-note WebSocket handshakes done with HTTP version lower than 1.1 will result in a warning, and the server will transparently upgrade the version to 1.1 to comply with the websocket RFC. This is done to work around incorrect nginx (and other proxy) configs that do not set the proxy_http_version directive to 1.1. This facility will be removed in a future Mattermost version and it is strongly recommended to fix the proxy configuration to correctly use the websocket protocol. ``` Co-authored-by: Mattermod --- api4/websocket.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api4/websocket.go b/api4/websocket.go index 92c87d0ac5..7c12bccf8b 100644 --- a/api4/websocket.go +++ b/api4/websocket.go @@ -11,6 +11,7 @@ import ( "github.com/gobwas/ws" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/shared/mlog" ) func (api *API) InitWebSocket() { @@ -29,6 +30,14 @@ func connectWebSocket(c *Context, w http.ResponseWriter, r *http.Request) { Timeout: 5 * time.Second, } + // Uprgade the HTTP version header to 1.1, if we detect a 1.0 header. + // This is a hack to work around a flaw in our proxy configs which sends the protocol version as 1.0. + // It will be removed in a future version. + if r.ProtoMajor == 1 && r.ProtoMinor == 0 { + r.ProtoMinor = 1 + mlog.Warn("The HTTP version field was detected as 1.0 during WebSocket handshake. This is most probably due to an incorrect proxy configuration. Please upgrade your proxy config to set the header version to a minimum of 1.1.") + } + conn, _, _, err := upgrader.Upgrade(r, w) if err != nil { c.Err = model.NewAppError("connect", "api.web_socket.connect.upgrade.app_error", nil, err.Error(), http.StatusInternalServerError)