fix: изменение монтирования /ws
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-27 20:35:20 +03:00
parent f381b4cd14
commit ae24bdd0e0
3 changed files with 36 additions and 4 deletions
+13 -1
View File
@@ -3,6 +3,7 @@ package api
import ( import (
"log/slog" "log/slog"
"net/http" "net/http"
"strings"
"messenger/internal/auth" "messenger/internal/auth"
"messenger/internal/platform/config" "messenger/internal/platform/config"
@@ -19,7 +20,8 @@ type apiHandler struct {
} }
// NewHandler builds the /api/v1 route tree with all middleware applied. // NewHandler builds the /api/v1 route tree with all middleware applied.
func NewHandler(st *store.Store, tm *auth.TokenManager, hub *realtime.Hub, log *slog.Logger, cfg *config.Config) http.Handler { // static, when non-nil, serves the built frontend for non-API paths.
func NewHandler(st *store.Store, tm *auth.TokenManager, hub *realtime.Hub, log *slog.Logger, cfg *config.Config, static http.Handler) http.Handler {
h := &apiHandler{ h := &apiHandler{
store: st, store: st,
tokens: tm, tokens: tm,
@@ -54,6 +56,16 @@ func NewHandler(st *store.Store, tm *auth.TokenManager, hub *realtime.Hub, log *
mux.Handle("GET /ws", authHandler) mux.Handle("GET /ws", authHandler)
if static != nil {
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/api/") {
writeError(w, http.StatusNotFound, "not found")
return
}
static.ServeHTTP(w, r)
})
}
return mux return mux
} }
+19
View File
@@ -1,7 +1,10 @@
package server package server
import ( import (
"bufio"
"errors"
"log/slog" "log/slog"
"net"
"net/http" "net/http"
"runtime/debug" "runtime/debug"
"slices" "slices"
@@ -61,3 +64,19 @@ func (r *statusRecorder) WriteHeader(code int) {
r.status = code r.status = code
r.ResponseWriter.WriteHeader(code) r.ResponseWriter.WriteHeader(code)
} }
// Hijack forwards the WebSocket upgrade to the underlying writer.
func (r *statusRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hj, ok := r.ResponseWriter.(http.Hijacker)
if !ok {
return nil, nil, errors.New("response writer does not support hijacking")
}
return hj.Hijack()
}
// Flush forwards periodic flush calls (SSE, streaming).
func (r *statusRecorder) Flush() {
if f, ok := r.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}
+4 -3
View File
@@ -27,12 +27,13 @@ func New(cfg *config.Config, log *slog.Logger, st *store.Store, tm *auth.TokenMa
writeJSON(w, http.StatusOK, map[string]string{"status": "ready"}) writeJSON(w, http.StatusOK, map[string]string{"status": "ready"})
}) })
mux.Handle("/api/v1/", api.NewHandler(st, tm, hub, log, cfg)) var static http.Handler
if cfg.StaticDir != "" { if cfg.StaticDir != "" {
mux.Handle("/", spaHandler{staticDir: cfg.StaticDir, log: log}) static = spaHandler{staticDir: cfg.StaticDir, log: log}
} }
mux.Handle("/", api.NewHandler(st, tm, hub, log, cfg, static))
handler := logRequests(log, recoverPanics(cors(cfg.AllowedOrigins, mux))) handler := logRequests(log, recoverPanics(cors(cfg.AllowedOrigins, mux)))
return &http.Server{ return &http.Server{