diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index b41c214be8c6d..2860ded9bcc7e 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -851,7 +851,11 @@ func (h *Handler) bindDefaultEndpoints() { // GET /webapi/sites/:site/desktops/:desktopName/connect?username=&width=&height= h.GET("/webapi/sites/:site/desktops/:desktopName/connect/ws", h.WithClusterAuthWebSocket(true, h.desktopConnectHandle)) // GET /webapi/sites/:site/desktopplayback/:sid?access_token= - h.GET("/webapi/sites/:site/desktopplayback/:sid", h.WithClusterAuth(h.desktopPlaybackHandle)) + // Deprecated: The desktopplayback/ws variant should be used instead. + // TODO(lxea): DELETE in v16 + h.GET("/webapi/sites/:site/desktopplayback/:sid", h.WithClusterAuthWebSocket(false, h.desktopPlaybackHandle)) + // GET /webapi/sites/:site/desktopplayback/:sid/ws + h.GET("/webapi/sites/:site/desktopplayback/:sid/ws", h.WithClusterAuthWebSocket(true, h.desktopPlaybackHandle)) h.GET("/webapi/sites/:site/desktops/:desktopName/active", h.WithClusterAuth(h.desktopIsActive)) // GET a Connection Diagnostics by its name @@ -3824,32 +3828,20 @@ var authnWsUpgrader = websocket.Upgrader{ // TODO(lxea): remove the 'websocketAuth' bool once the deprecated websocket handlers are removed func (h *Handler) WithClusterAuthWebSocket(websocketAuth bool, fn ClusterWebsocketHandler) httprouter.Handle { return httplib.MakeHandler(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) (any, error) { - if websocketAuth { - sctx, ws, site, err := h.authenticateWSRequestWithCluster(w, r, p) - if err != nil { - return nil, trace.Wrap(err) - } - // WS protocol requires the server send a close message - // which should be done by downstream users - defer ws.Close() + var sctx *SessionContext + var ws *websocket.Conn + var site reversetunnelclient.RemoteSite + var err error - if _, err := fn(w, r, p, sctx, site, ws); err != nil { - h.writeErrToWebSocket(ws, err) - } - return nil, nil + if websocketAuth { + sctx, ws, site, err = h.authenticateWSRequestWithCluster(w, r, p) + } else { + sctx, ws, site, err = h.authenticateWSRequestWithClusterDeprecated(w, r, p) } - sctx, site, err := h.authenticateRequestWithCluster(w, r, p) if err != nil { return nil, trace.Wrap(err) } - ws, err := authnWsUpgrader.Upgrade(w, r, nil) - if err != nil { - const errMsg = "Error upgrading to websocket" - h.log.WithError(err).Error(errMsg) - http.Error(w, errMsg, http.StatusInternalServerError) - return nil, nil - } // WS protocol requires the server send a close message // which should be done by downstream users defer ws.Close() @@ -3879,6 +3871,19 @@ func (h *Handler) authenticateWSRequestWithCluster(w http.ResponseWriter, r *htt return sctx, ws, site, nil } +// TODO(lxea): remove once the deprecated websocket handlers are removed +func (h *Handler) authenticateWSRequestWithClusterDeprecated(w http.ResponseWriter, r *http.Request, p httprouter.Params) (*SessionContext, *websocket.Conn, reversetunnelclient.RemoteSite, error) { + sctx, site, err := h.authenticateRequestWithCluster(w, r, p) + if err != nil { + return nil, nil, nil, trace.Wrap(err) + } + ws, err := authnWsUpgrader.Upgrade(w, r, nil) + if err != nil { + return nil, nil, nil, trace.Wrap(err) + } + return sctx, ws, site, nil +} + // authenticateRequestWithCluster ensures that a request is authenticated // to this proxy, returning the *SessionContext (same as AuthenticateRequest), // and also grabs the remoteSite (which can represent this local cluster or a diff --git a/lib/web/desktop_playback.go b/lib/web/desktop_playback.go index df04c330eed7f..9c50cdcc153c7 100644 --- a/lib/web/desktop_playback.go +++ b/lib/web/desktop_playback.go @@ -38,6 +38,7 @@ func (h *Handler) desktopPlaybackHandle( p httprouter.Params, sctx *SessionContext, site reversetunnelclient.RemoteSite, + ws *websocket.Conn, ) (interface{}, error) { sID := p.ByName("sid") if sID == "" { @@ -49,16 +50,6 @@ func (h *Handler) desktopPlaybackHandle( return nil, trace.Wrap(err) } - upgrader := websocket.Upgrader{ - ReadBufferSize: 4096, - WriteBufferSize: 4096, - } - ws, err := upgrader.Upgrade(w, r, nil) - if err != nil { - return nil, trace.Wrap(err) - } - defer ws.Close() - player, err := player.New(&player.Config{ Clock: h.clock, Log: h.log,