summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2025-04-14 13:12:09 +0000
committerLibravatar GitHub <noreply@github.com>2025-04-14 15:12:09 +0200
commitf5ce219844e0c6e80b1f1dfbbce1f96a6251448d (patch)
treece2e513d592c4d4838be9f81901413e048e93833
parentensure 'none' gets included in serializable visibilities (#4007) (diff)
downloadgotosocial-f5ce219844e0c6e80b1f1dfbbce1f96a6251448d.tar.xz
[bugfix] websocket header token not always returned (#4009)
* always include headerToken response if provided, because Chrome *sigh* * wording * Update internal/api/client/streaming/stream.go Co-authored-by: Ilia Pozdnyakov <iliazeus@proton.me> --------- Co-authored-by: Ilia Pozdnyakov <iliazeus@proton.me>
-rw-r--r--internal/api/client/streaming/stream.go45
1 files changed, 22 insertions, 23 deletions
diff --git a/internal/api/client/streaming/stream.go b/internal/api/client/streaming/stream.go
index e6d1b80f7..8fafed7c2 100644
--- a/internal/api/client/streaming/stream.go
+++ b/internal/api/client/streaming/stream.go
@@ -18,6 +18,7 @@
package streaming
import (
+ "cmp"
"context"
"net/http"
"slices"
@@ -153,25 +154,22 @@ var pingMsg = []byte("ping!")
// description: bad request
func (m *Module) StreamGETHandler(c *gin.Context) {
var (
- token string
- tokenInHeader bool
- account *gtsmodel.Account
- errWithCode gtserror.WithCode
+ account *gtsmodel.Account
+ errWithCode gtserror.WithCode
)
- if t := c.Query(AccessTokenQueryKey); t != "" {
- // Token was provided as
- // query param, no problem.
- token = t
- } else if t := c.GetHeader(AccessTokenHeader); t != "" {
- // Token was provided in "Sec-Websocket-Protocol" header.
- //
- // This is hacky and not technically correct but some
- // clients do it since Mastodon allows it, so we must
- // also allow it to avoid breaking expectations.
- token = t
- tokenInHeader = true
- }
+ // Check both query parameter AND header "Sec-Websocket-Protocol"
+ // value for a token. The latter is hacky and not technically
+ // correct, but some client do it since Mastodon allows it, so
+ // we must allow it for compatibility.
+ //
+ // Chrome also *always* expects the "Sec-Websocket-Protocol"
+ // response value to match input, so it must always be checked.
+ queryToken := c.Query(AccessTokenQueryKey)
+ headerToken := c.GetHeader(AccessTokenHeader)
+
+ // Prefer query token else use header token.
+ token := cmp.Or(queryToken, headerToken)
if token != "" {
@@ -229,8 +227,7 @@ func (m *Module) StreamGETHandler(c *gin.Context) {
return
}
- l := log.
- WithContext(c.Request.Context()).
+ l := log.WithContext(c.Request.Context()).
WithField("streamID", id.NewULID()).
WithField("username", account.Username)
@@ -241,12 +238,14 @@ func (m *Module) StreamGETHandler(c *gin.Context) {
// If the upgrade fails, then Upgrade replies to the client
// with an HTTP error response.
var responseHeader http.Header
- if tokenInHeader {
- // Return the token in the response,
- // else Chrome fails to connect.
+ if headerToken != "" {
+
+ // Chrome always requires the input header
+ // token to be provided in response, even
+ // if it also provided via query... *shrugs*
//
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism#sec-websocket-protocol
- responseHeader = http.Header{AccessTokenHeader: {token}}
+ responseHeader = http.Header{AccessTokenHeader: {headerToken}}
}
wsConn, err := m.wsUpgrade.Upgrade(c.Writer, c.Request, responseHeader)