mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-01-12 03:21:33 +00:00
Apply retries as global, config-level option `downloadRetries` so that it can be applied to any aptly command which downloads objects. Unwrap `errors.Wrap` which is used in downloader. Unwrap `*url.Error` which should be the actual error returned from the HTTP client, catch more cases, be more specific around failures.
96 lines
2.3 KiB
Go
96 lines
2.3 KiB
Go
package http
|
|
|
|
import (
|
|
"compress/bzip2"
|
|
"compress/gzip"
|
|
"context"
|
|
"io"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/aptly-dev/aptly/aptly"
|
|
"github.com/aptly-dev/aptly/utils"
|
|
xz "github.com/smira/go-xz"
|
|
)
|
|
|
|
// List of extensions + corresponding uncompression support
|
|
var compressionMethods = []struct {
|
|
extenstion string
|
|
transformation func(io.Reader) (io.Reader, error)
|
|
}{
|
|
{
|
|
extenstion: ".bz2",
|
|
transformation: func(r io.Reader) (io.Reader, error) { return bzip2.NewReader(r), nil },
|
|
},
|
|
{
|
|
extenstion: ".gz",
|
|
transformation: func(r io.Reader) (io.Reader, error) { return gzip.NewReader(r) },
|
|
},
|
|
{
|
|
extenstion: ".xz",
|
|
transformation: func(r io.Reader) (io.Reader, error) { return xz.NewReader(r) },
|
|
},
|
|
{
|
|
extenstion: "",
|
|
transformation: func(r io.Reader) (io.Reader, error) { return r, nil },
|
|
},
|
|
}
|
|
|
|
// DownloadTryCompression tries to download from URL .bz2, .gz and raw extension until
|
|
// it finds existing file.
|
|
func DownloadTryCompression(ctx context.Context, downloader aptly.Downloader, baseURL *url.URL, path string, expectedChecksums map[string]utils.ChecksumInfo, ignoreMismatch bool) (io.Reader, *os.File, error) {
|
|
var err error
|
|
|
|
for _, method := range compressionMethods {
|
|
var file *os.File
|
|
|
|
tryPath := path + method.extenstion
|
|
foundChecksum := false
|
|
|
|
bestSuffix := ""
|
|
|
|
for suffix := range expectedChecksums {
|
|
if strings.HasSuffix(tryPath, suffix) {
|
|
foundChecksum = true
|
|
if len(suffix) > len(bestSuffix) {
|
|
bestSuffix = suffix
|
|
}
|
|
}
|
|
}
|
|
|
|
tryURL := baseURL.ResolveReference(&url.URL{Path: tryPath})
|
|
|
|
if foundChecksum {
|
|
expected := expectedChecksums[bestSuffix]
|
|
file, err = DownloadTempWithChecksum(ctx, downloader, tryURL.String(), &expected, ignoreMismatch)
|
|
} else {
|
|
if !ignoreMismatch {
|
|
continue
|
|
}
|
|
|
|
file, err = DownloadTemp(ctx, downloader, tryURL.String())
|
|
}
|
|
|
|
if err != nil {
|
|
if err1, ok := err.(*Error); ok && (err1.Code == 404 || err1.Code == 403) {
|
|
continue
|
|
}
|
|
return nil, nil, err
|
|
}
|
|
|
|
var uncompressed io.Reader
|
|
uncompressed, err = method.transformation(file)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return uncompressed, file, err
|
|
}
|
|
|
|
if err == nil {
|
|
return nil, nil, &NoCandidateFoundError{URL: baseURL.ResolveReference(&url.URL{Path: path})}
|
|
}
|
|
return nil, nil, err
|
|
}
|