diff --git a/internal/archive/archive.go b/internal/archive/archive.go index 4e0a2dea..e24a9c24 100644 --- a/internal/archive/archive.go +++ b/internal/archive/archive.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "net/url" "slices" "strings" "time" @@ -134,9 +135,9 @@ func (a *ubuntuArchive) Fetch(pkg string) (io.ReadSeekCloser, *PackageInfo, erro if err != nil { return nil, nil, err } - suffix := section.Get("Filename") - logf("Fetching %s...", suffix) - reader, err := index.fetch("../../"+suffix, section.Get("SHA256"), fetchBulk) + path := section.Get("Filename") + logf("Fetching %s...", path) + reader, err := index.fetch(path, section.Get("SHA256"), fetchBulk) if err != nil { return nil, nil, err } @@ -276,7 +277,7 @@ func openUbuntu(options *Options) (Archive, error) { func (index *ubuntuIndex) fetchRelease() error { logf("Fetching %s %s %s suite details...", index.displayName(), index.version, index.suite) - reader, err := index.fetch("InRelease", "", fetchDefault) + reader, err := index.fetch(index.distPath("InRelease"), "", fetchDefault) if err != nil { return err } @@ -333,7 +334,7 @@ func (index *ubuntuIndex) fetchIndex() error { } logf("Fetching index for %s %s %s %s component...", index.displayName(), index.version, index.suite, index.component) - reader, err := index.fetch(packagesPath+".gz", digest, fetchBulk) + reader, err := index.fetch(index.distPath(packagesPath+".gz"), digest, fetchBulk) if err != nil { return err } @@ -368,7 +369,11 @@ func (index *ubuntuIndex) checkComponents(components []string) error { return nil } -func (index *ubuntuIndex) fetch(suffix, digest string, flags fetchFlags) (io.ReadSeekCloser, error) { +func (index *ubuntuIndex) distPath(suffix string) string { + return "dists/" + index.suite + "/" + suffix +} + +func (index *ubuntuIndex) fetch(path, digest string, flags fetchFlags) (io.ReadSeekCloser, error) { reader, err := index.archive.cache.Open(digest) if err == nil { return reader, nil @@ -376,19 +381,15 @@ func (index *ubuntuIndex) fetch(suffix, digest string, flags fetchFlags) (io.Rea return nil, err } - baseURL, creds := index.archive.baseURL, index.archive.creds - - var url string - if strings.HasPrefix(suffix, "pool/") { - url = baseURL + suffix - } else { - url = baseURL + "dists/" + index.suite + "/" + suffix + cleanURL, err := url.JoinPath(index.archive.baseURL, path) + if err != nil { + return nil, fmt.Errorf("internal error: cannot construct URL: %v", err) } - - req, err := http.NewRequest("GET", url, nil) + req, err := http.NewRequest("GET", cleanURL, nil) if err != nil { return nil, fmt.Errorf("cannot create HTTP request: %v", err) } + creds := index.archive.creds if creds != nil && !creds.Empty() { req.SetBasicAuth(creds.Username, creds.Password) } @@ -415,7 +416,7 @@ func (index *ubuntuIndex) fetch(suffix, digest string, flags fetchFlags) (io.Rea } body := resp.Body - if strings.HasSuffix(suffix, ".gz") { + if strings.HasSuffix(path, ".gz") { reader, err := gzip.NewReader(body) if err != nil { return nil, fmt.Errorf("cannot decompress data: %v", err) diff --git a/internal/archive/archive_test.go b/internal/archive/archive_test.go index 1671e79a..8ca840e5 100644 --- a/internal/archive/archive_test.go +++ b/internal/archive/archive_test.go @@ -72,6 +72,14 @@ func (s *httpSuite) Do(req *http.Request) (*http.Response, error) { return nil, fmt.Errorf("test expected base %q, got %q", s.base, req.URL.String()) } + cleanURL, err := url.JoinPath(req.URL.String()) + if err != nil { + return nil, fmt.Errorf("cannot clean requested URL: %v", err) + } + if cleanURL != req.URL.String() { + return nil, fmt.Errorf("test expected clean URL %q, got %q", cleanURL, req.URL.String()) + } + s.request = req s.requests = append(s.requests, req) body := s.response