Skip to content

Commit df664e5

Browse files
committed
fix: fall back when APKINDEX HEAD is unsupported
Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
1 parent ebd9255 commit df664e5

2 files changed

Lines changed: 39 additions & 10 deletions

File tree

pkg/apk/apk/index.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,6 @@ func (i *indexCache) get(ctx context.Context, repoName, repoURL string, keys map
131131
return nil, fmt.Errorf("unable to add auth to request: %w", err)
132132
}
133133

134-
resp, err := client.Do(head)
135-
if err != nil {
136-
return nil, err
137-
}
138-
defer resp.Body.Close()
139-
140-
if resp.StatusCode != http.StatusOK {
141-
return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode)
142-
}
143-
144134
fetchAndParse := func(etag string) (NamedIndex, error) {
145135
b, err := fetchRepositoryIndex(ctx, u, etag, opts)
146136
if err != nil {
@@ -153,6 +143,19 @@ func (i *indexCache) get(ctx context.Context, repoName, repoURL string, keys map
153143
return NewNamedRepositoryWithIndex(repoName, repoRef.WithIndex(idx)), nil
154144
}
155145

146+
resp, err := client.Do(head)
147+
if err != nil {
148+
return nil, err
149+
}
150+
defer resp.Body.Close()
151+
152+
if resp.StatusCode != http.StatusOK {
153+
if resp.StatusCode == http.StatusMethodNotAllowed || resp.StatusCode == http.StatusNotImplemented {
154+
return fetchAndParse("")
155+
}
156+
return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode)
157+
}
158+
156159
etag, ok := etagFromResponse(resp)
157160
if !ok {
158161
// If there's no etag, we can't cache it, so just return the result.

pkg/apk/apk/repo_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"context"
1919
"encoding/base32"
2020
"fmt"
21+
"io"
2122
"io/fs"
2223
"maps"
2324
"net/http"
@@ -91,6 +92,21 @@ guyM+Ks3c29KlRf3iX35Gt0CAwEAAQ==
9192
testArch = "aarch64"
9293
)
9394

95+
type headMethodNotAllowedTransport struct {
96+
wrapped http.RoundTripper
97+
}
98+
99+
func (t *headMethodNotAllowedTransport) RoundTrip(request *http.Request) (*http.Response, error) {
100+
if request.Method == http.MethodHead {
101+
return &http.Response{
102+
StatusCode: http.StatusMethodNotAllowed,
103+
Body: io.NopCloser(strings.NewReader("method not allowed")),
104+
}, nil
105+
}
106+
107+
return t.wrapped.RoundTrip(request)
108+
}
109+
94110
func TestGetRepositoryIndexes(t *testing.T) {
95111
prepLayout := func(t *testing.T, tr http.RoundTripper, cache string, repos []string) *APK {
96112
src := apkfs.NewMemFS()
@@ -184,6 +200,16 @@ func TestGetRepositoryIndexes(t *testing.T) {
184200
require.NoError(t, err, "unable to read previous index file")
185201
require.Equal(t, index1, index2, "index files do not match")
186202
})
203+
t.Run("head method not allowed falls back to get", func(t *testing.T) {
204+
tmpDir := t.TempDir()
205+
a := prepLayout(t, &headMethodNotAllowedTransport{
206+
wrapped: &testLocalTransport{root: testPrimaryPkgDir, basenameOnly: true},
207+
}, tmpDir, nil)
208+
209+
indexes, err := a.GetRepositoryIndexes(context.Background(), false)
210+
require.NoErrorf(t, err, "unable to get indexes")
211+
require.Greater(t, len(indexes), 0, "no indexes found")
212+
})
187213
t.Run("repo url with http basic auth", func(t *testing.T) {
188214
tmpDir := t.TempDir()
189215
a := prepLayout(t, &testLocalTransport{

0 commit comments

Comments
 (0)