0.2.63 update

This commit is contained in:
ponzischeme89
2026-08-14 11:47:32 +12:00
parent 9a8ecbdceb
commit 06b6490ac9
41 changed files with 921 additions and 179 deletions
+38 -8
View File
@@ -2,6 +2,8 @@ package api
import (
"context"
"crypto/rand"
"encoding/hex"
"log/slog"
"net"
"net/http"
@@ -19,11 +21,12 @@ import (
// still read what an inner layer filled in. A request is served on one goroutine and the
// handler has returned by the time the middleware reads this, so no lock is needed.
type requestIdentity struct {
component string
user string
device string
client string
protocol string
component string
user string
device string
client string
protocol string
correlation string
}
type identityKey struct{}
@@ -31,9 +34,10 @@ type identityKey struct{}
// withRequestIdentity installs an empty identity for this request and returns it.
func withRequestIdentity(r *http.Request) (*http.Request, *requestIdentity) {
identity := &requestIdentity{
component: componentFor(r.URL.Path),
client: clientVersion(r),
protocol: clientProtocol(r),
component: componentFor(r.URL.Path),
client: clientVersion(r),
protocol: clientProtocol(r),
correlation: requestCorrelation(r),
}
return r.WithContext(context.WithValue(r.Context(), identityKey{}, identity)), identity
}
@@ -79,9 +83,35 @@ func (i *requestIdentity) attrs() []any {
if i.client != "" {
attrs = append(attrs, "client", i.client)
}
if i.correlation != "" {
attrs = append(attrs, "correlation", i.correlation)
}
return attrs
}
// requestCorrelation accepts a client-supplied safe identifier or creates one at the
// gateway boundary. The same value is attached to every log line within the exchange and
// returned to the client, making a playback launch traceable through gateway and Emby work.
func requestCorrelation(r *http.Request) string {
if value := strings.TrimSpace(r.Header.Get("X-Memby-Correlation")); len(value) >= 6 && len(value) <= 64 {
for _, rune := range value {
if !(rune >= 'a' && rune <= 'z' || rune >= 'A' && rune <= 'Z' || rune >= '0' && rune <= '9' || rune == '-' || rune == '_') {
return newCorrelation()
}
}
return value
}
return newCorrelation()
}
func newCorrelation() string {
var raw [4]byte
if _, err := rand.Read(raw[:]); err != nil {
return "request-unknown"
}
return "req-" + strings.ToUpper(hex.EncodeToString(raw[:]))
}
// viewerAttrs names the person and the television, and only when they are known: an
// unauthenticated probe has neither, and "user=unknown" on every health check is noise.
func (i *requestIdentity) viewerAttrs() []any {