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 <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Agniva De Sarker
2021-03-15 23:02:24 +05:30
коммит произвёл GitHub
родитель 157f9b5cae
Коммит 4c5ea07aff

Просмотреть файл

@@ -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)