fix: WS upgrade via metrics middleware (realtime), DM names, tap reactions
CI / Go (build + vet + test) (push) Canceled after 0s
CI / Web (build + lint) (push) Canceled after 0s

This commit is contained in:
vantablackTea
2026-09-28 14:07:59 +03:00
parent e709ae11f8
commit a0b17d25bf
5 changed files with 170 additions and 34 deletions
@@ -3,6 +3,9 @@
package metrics
import (
"bufio"
"errors"
"net"
"net/http"
"strconv"
"strings"
@@ -82,6 +85,23 @@ func (r *recorder) WriteHeader(code int) {
r.ResponseWriter.WriteHeader(code)
}
// Hijack forwards the WebSocket upgrade to the underlying writer. Without
// this, wrapping the mux breaks every WebSocket handshake.
func (r *recorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hj, ok := r.ResponseWriter.(http.Hijacker)
if !ok {
return nil, nil, errors.New("metrics: response writer does not support hijacking")
}
return hj.Hijack()
}
// Flush forwards periodic flush calls for streaming responses.
func (r *recorder) Flush() {
if f, ok := r.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}
// NormalizePath replaces numeric path segments with a placeholder so that
// per-route cardinality stays bounded regardless of resource IDs.
func NormalizePath(p string) string {
@@ -0,0 +1,30 @@
package metrics
import (
"bufio"
"net"
"net/http"
"net/http/httptest"
"testing"
)
type hijackRecorder struct {
*httptest.ResponseRecorder
}
func (h *hijackRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return nil, nil, nil
}
func TestMiddlewarePreservesHijacker(t *testing.T) {
var seen http.ResponseWriter
handler := Middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
seen = w
}))
handler.ServeHTTP(&hijackRecorder{httptest.NewRecorder()}, httptest.NewRequest(http.MethodGet, "/", nil))
if _, ok := seen.(http.Hijacker); !ok {
t.Fatal("middleware stripped http.Hijacker: WebSocket upgrades will fail")
}
}