Log messages are lower-case event names with their details as key/value
attributes ("error" for errors), in place of formatted strings.
Loggable package take a WithLogger option as part of their "New*" call,
defaulting to slog.Default(). Each tags its lines with its `component`.
Some debug loggers print directly rather than using slog when in
terminal logging mode.
46 lines
1.3 KiB
Go
46 lines
1.3 KiB
Go
package websocket
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
ws "github.com/coder/websocket"
|
|
|
|
"git.avsdev.uk/Go/job-search/internal/middleware"
|
|
)
|
|
|
|
// ServeHTTP upgrades an http connection and runs the client until it closes.
|
|
func (h *Hub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
mode := ws.CompressionDisabled
|
|
if h.conf.EnableCompression {
|
|
mode = ws.CompressionContextTakeover
|
|
}
|
|
|
|
// Accept enforces the Origin check: same host, or one of OriginPatterns.
|
|
// That is the defence against cross-site WebSocket hijacking.
|
|
conn, err := ws.Accept(w, r, &ws.AcceptOptions{
|
|
CompressionMode: mode,
|
|
})
|
|
if err != nil {
|
|
h.logger().Debug("upgrade failed", "error", err)
|
|
return // Accept has already written the HTTP error.
|
|
}
|
|
defer conn.CloseNow() //nolint:errcheck // finished with; it may already be closed
|
|
conn.SetReadLimit(int64(h.maxMessageSize()))
|
|
|
|
ip := middleware.ClientIP(r)
|
|
ctx, cancel := context.WithCancel(r.Context())
|
|
c := newClient(h, conn, ip, cancel)
|
|
|
|
if !h.register(c) {
|
|
cancel()
|
|
conn.Close(ws.StatusGoingAway, "server shutting down") //nolint:errcheck,gosec // turned away
|
|
return
|
|
}
|
|
defer h.unregister(c)
|
|
|
|
h.logger().Info("client connected", "client", c.id, "ip", ip)
|
|
c.run(ctx)
|
|
h.logger().Info("client disconnected", "client", c.id, "ip", ip)
|
|
}
|