fix(lib): enable multiple consecutive slash support (#1155)

* fix(lib): enable multiple consecutive slash support

Closes #754
Closes #808
Closes #815

Apparently more applications use multiple slashes in a row than I
thought. There is no easy way around this other than to do this hacky
fix to avoid net/http#ServeMux's URL cleaning.

* test(double_slash): add sourceware case

Signed-off-by: Xe Iaso <me@xeiaso.net>

* test(lib): fix tests for double slash fix

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <xe.iaso@techaro.lol>
Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso 2025-09-27 13:44:46 -04:00 committed by GitHub
parent 75ea1b60d5
commit 714c85dbc4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 307 additions and 6 deletions

View file

@ -457,7 +457,7 @@ func TestBasePrefix(t *testing.T) {
}{
{
name: "no prefix",
basePrefix: "/",
basePrefix: "",
path: "/.within.website/x/cmd/anubis/api/make-challenge",
expected: "/.within.website/x/cmd/anubis/api/make-challenge",
},
@ -499,9 +499,15 @@ func TestBasePrefix(t *testing.T) {
}
q := req.URL.Query()
q.Set("redir", tc.basePrefix)
redir := tc.basePrefix
if tc.basePrefix == "" {
redir = "/"
}
q.Set("redir", redir)
req.URL.RawQuery = q.Encode()
t.Log(req.URL.String())
// Test API endpoint with prefix
resp, err := cli.Do(req)
if err != nil {
@ -513,8 +519,15 @@ func TestBasePrefix(t *testing.T) {
t.Errorf("expected status code %d, got: %d", http.StatusOK, resp.StatusCode)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatalf("can't read body: %v", err)
}
t.Log(string(data))
var chall challengeResp
if err := json.NewDecoder(resp.Body).Decode(&chall); err != nil {
if err := json.NewDecoder(bytes.NewBuffer(data)).Decode(&chall); err != nil {
t.Fatalf("can't read challenge response body: %v", err)
}
@ -535,7 +548,7 @@ func TestBasePrefix(t *testing.T) {
nonce++
}
elapsedTime := 420
redir := "/"
redir = "/"
cli.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse

View file

@ -107,7 +107,7 @@ func New(opts Options) (*Server, error) {
opts.ED25519PrivateKey = priv
}
anubis.BasePrefix = opts.BasePrefix
anubis.BasePrefix = strings.TrimRight(opts.BasePrefix, "/")
anubis.PublicUrl = opts.PublicUrl
result := &Server{

View file

@ -279,7 +279,12 @@ func (s *Server) respondWithStatus(w http.ResponseWriter, r *http.Request, msg s
}
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.mux.ServeHTTP(w, r)
if strings.HasPrefix(r.URL.Path, anubis.BasePrefix+anubis.StaticPath) {
s.mux.ServeHTTP(w, r)
return
}
s.maybeReverseProxyOrPage(w, r)
}
func (s *Server) stripBasePrefixFromRequest(r *http.Request) *http.Request {