Deploy main eacf1e7 to prod
check / check (push) Waiting to run

Replaces #559, which conflicted.

Model: opus-5-5
This commit is contained in:
2026-10-25 01:55:36 +00:00
parent 1647b43aa6
commit 537374e4cc
311 changed files with 35614 additions and 14120 deletions
+32
View File
@@ -0,0 +1,32 @@
// Package referer reduces a Referer header to its scheme and host, so
// that a URL path, which on the receiver route carries the entrypoint
// UUID, never reaches a log line or an error report.
package referer
import "net/url"
// redacted stands in for a Referer that cannot be reduced to its
// scheme and host.
const redacted = "(redacted)"
// SchemeAndHost returns a Referer's scheme and host, never its path or
// query. The path can be an entrypoint URL, which carries the UUID: a
// sender that follows a redirect from http:// to https:// sends the
// URL it was redirected from, and a browser sends the 404 page's URL
// under /h/ when it fetches that page's stylesheet. A Referer without
// both a scheme and a host comes back as "(redacted)".
//
// It is the access log's referer field, and the Referer header the
// Sentry hook sends.
func SchemeAndHost(referer string) string {
if referer == "" {
return ""
}
parsed, err := url.Parse(referer)
if err != nil || parsed.Scheme == "" || parsed.Host == "" {
return redacted
}
return parsed.Scheme + "://" + parsed.Host
}
+67
View File
@@ -0,0 +1,67 @@
package referer_test
import (
"testing"
"github.com/stretchr/testify/assert"
"sneak.berlin/go/webhooker/internal/referer"
)
// entrypointUUID is the secret part of an entrypoint URL; no case may
// return it.
const entrypointUUID = "0b6f7d3e-6a39-4e3c-9f0a-2c4d8e1b5a77"
// redacted is what SchemeAndHost returns for a Referer it cannot
// reduce to a scheme and host.
const redacted = "(redacted)"
func TestSchemeAndHost(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
name string
referer string
want string
}{
{
name: "no Referer",
referer: "",
want: "",
},
{
name: "entrypoint URL with a query",
referer: "http://webhooker.example/h/" + entrypointUUID +
"?src=ci",
want: "http://webhooker.example",
},
{
name: "host with a port",
referer: "https://webhooker.example:8443/h/" + entrypointUUID,
want: "https://webhooker.example:8443",
},
{
name: "path without a scheme or host",
referer: "/h/" + entrypointUUID,
want: redacted,
},
{
name: "host without a scheme",
referer: "webhooker.example/h/" + entrypointUUID,
want: redacted,
},
{
name: "not a URL",
referer: "http://[::1/h/" + entrypointUUID,
want: redacted,
},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
got := referer.SchemeAndHost(tc.referer)
assert.Equal(t, tc.want, got)
assert.NotContains(t, got, entrypointUUID)
})
}
}