fix(deb): normalize apt flat-repo ./ dist prefix in local index
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful

Real apt appends the flat-repo dist "./" verbatim, requesting <repo>/./Packages
(and ./Release, ./InRelease). ServeLocalIndex matched the literal filename and
404d, breaking the documented `deb ... <repo>/ ./` one-liner; curl/browsers
pre-normalize /./ which masked it. Collapse the dot-segment via a small
normalizeIndexPath helper before matching, a no-op for pool/*.deb lookups.
This commit is contained in:
unkin-agent
2026-08-11 22:39:30 +10:00
parent a35f260b74
commit d7e6ec43ff
2 changed files with 58 additions and 1 deletions
+11 -1
View File
@@ -14,6 +14,7 @@ import (
"io"
"log/slog"
"net/http"
"path"
"regexp"
"strconv"
"strings"
@@ -305,7 +306,16 @@ func parseControlFields(control string) map[string]string {
return fields
}
func (p *Provider) ServeLocalIndex(w http.ResponseWriter, r *http.Request, files provider.FileStore, repoName, path string) bool {
// normalizeIndexPath collapses apt's verbatim dist prefix from a flat-repo
// request. For `deb ... <repo>/ ./`, apt appends the "./" dist literally and asks
// for "./Packages" (and "./Release", "./InRelease"); dot-segments must be
// collapsed so the index matcher sees "Packages". A no-op for pool/*.deb paths.
func normalizeIndexPath(p string) string {
return strings.TrimPrefix(path.Clean("/"+p), "/")
}
func (p *Provider) ServeLocalIndex(w http.ResponseWriter, r *http.Request, files provider.FileStore, repoName, reqPath string) bool {
path := normalizeIndexPath(reqPath)
switch path {
case "Packages", "Packages.gz", "Release":
default: