From a5f612e082a8bf2dfad05abc1e49cee195033889 Mon Sep 17 00:00:00 2001 From: Jerry Ng Date: Thu, 16 Feb 2023 20:34:36 +0800 Subject: [PATCH 1/2] Fix download mode leak for latest and list handlers --- pkg/download/protocol.go | 15 ++++++++++++++- pkg/download/protocol_test.go | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/pkg/download/protocol.go b/pkg/download/protocol.go index b9d5945ee..f802eccfa 100644 --- a/pkg/download/protocol.go +++ b/pkg/download/protocol.go @@ -89,6 +89,12 @@ func (p *protocol) List(ctx context.Context, mod string) ([]string, error) { var sErr, goErr error var wg sync.WaitGroup + // if download mode is none for the specific mod, just return an error. + downloadMode := p.df.Match(mod) + if downloadMode == mode.None { + return nil, errors.E(op, errors.M(mod), errors.KindNotFound) + } + /* TODO: potential refactor: @@ -183,9 +189,16 @@ func (p *protocol) Latest(ctx context.Context, mod string) (*storage.RevInfo, er const op errors.Op = "protocol.Latest" ctx, span := observ.StartSpan(ctx, op.String()) defer span.End() + + // if download mode is none for the specific mod, just return an error. + downloadMode := p.df.Match(mod) + if downloadMode == mode.None { + return nil, errors.E(op, errors.M(mod), errors.KindNotFound) + } + if p.networkMode == Offline { // Go never pings the /@latest endpoint _first_. It always tries /list and if that - // endpoint returns an empty list then it fallsback to calling /@latest. + // endpoint returns an empty list then it fallbacks to calling /@latest. return nil, errors.E(op, "Athens is in offline mode, use /list endpoint", errors.KindNotFound) } lr, _, err := p.lister.List(ctx, mod) diff --git a/pkg/download/protocol_test.go b/pkg/download/protocol_test.go index 40134a497..c89806e3f 100644 --- a/pkg/download/protocol_test.go +++ b/pkg/download/protocol_test.go @@ -164,6 +164,7 @@ func TestListMode(t *testing.T) { storage: strg, lister: ml, networkMode: tc.networkmode, + df: &mode.DownloadFile{}, } for _, tag := range tc.storageTags { err := strg.Save(ctx, tc.path, tag, []byte("mod"), bytes.NewReader([]byte("zip")), []byte("info")) From 962acf013c4b63dd9f875bc40144f4c7f2ee7287 Mon Sep 17 00:00:00 2001 From: Jerry Ng Date: Thu, 16 Feb 2023 22:11:38 +0800 Subject: [PATCH 2/2] Add test cases for download mode file --- download.example.hcl | 4 +-- pkg/download/protocol_test.go | 55 +++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/download.example.hcl b/download.example.hcl index a2e3275cf..ca7079a7a 100644 --- a/download.example.hcl +++ b/download.example.hcl @@ -1,9 +1,9 @@ downloadURL = "https://proxy.golang.org" -mode = "async_redirect" +mode = "sync" download "github.com/gomods/*" { - mode = "sync" + mode = "async_redirect" } download "golang.org/x/*" { diff --git a/pkg/download/protocol_test.go b/pkg/download/protocol_test.go index c89806e3f..d2b69a287 100644 --- a/pkg/download/protocol_test.go +++ b/pkg/download/protocol_test.go @@ -28,7 +28,8 @@ import ( ) var ( - testConfigPath = filepath.Join("..", "..", "config.dev.toml") + testConfigPath = filepath.Join("..", "..", "config.dev.toml") + testDownloadModeFilePath = filepath.Join("..", "..", "download.example.hcl") ) func getDP(t *testing.T) Protocol { @@ -37,6 +38,12 @@ func getDP(t *testing.T) Protocol { if err != nil { t.Fatalf("Unable to parse config file: %s", err.Error()) } + + df, err := mode.NewFile(mode.Mode("file:"+testDownloadModeFilePath), conf.DownloadURL) + if err != nil { + t.Fatalf("Unable to parse download mode file: %s", err.Error()) + } + goBin := conf.GoBinary fs := afero.NewOsFs() mf, err := module.NewGoGetFetcher(goBin, conf.GoGetDir, conf.GoBinaryEnvVars, fs) @@ -49,10 +56,11 @@ func getDP(t *testing.T) Protocol { } st := stash.New(mf, s, nop.New()) return New(&Opts{ - Storage: s, - Stasher: st, - Lister: module.NewVCSLister(goBin, conf.GoBinaryEnvVars, fs), - NetworkMode: Strict, + Storage: s, + Stasher: st, + Lister: module.NewVCSLister(goBin, conf.GoBinaryEnvVars, fs), + NetworkMode: Strict, + DownloadFile: df, }) } @@ -149,10 +157,33 @@ var listModeTests = []listModeTest{ wantTags: nil, wantErr: true, }, + { + name: "download mode is none for module", + networkmode: Strict, + path: "golang.org/x/crypto", + storageTags: []string{"v0.1.0"}, + upstreamList: []string{"v0.1.0", "v0.2.0", "v0.3.0", "v0.4.0", "v0.5.0", "v0.6.0"}, + wantTags: nil, + wantErr: true, + }, + { + name: "download mode is async_redirect for module", + networkmode: Strict, + path: "github.com/gomods/athens", + storageTags: []string{"v0.1.0"}, + upstreamList: []string{"v0.1.0", "v0.2.0", "v0.3.0"}, + wantTags: []string{"v0.1.0", "v0.2.0", "v0.3.0"}, + wantErr: true, + }, } func TestListMode(t *testing.T) { ctx := context.Background() + df, err := mode.NewFile(mode.Mode("file:"+testDownloadModeFilePath), "") + if err != nil { + t.Fatalf("Unable to parse download mode file: %s", err.Error()) + } + for _, tc := range listModeTests { strg, err := mem.NewStorage() require.NoError(t, err) @@ -164,7 +195,7 @@ func TestListMode(t *testing.T) { storage: strg, lister: ml, networkMode: tc.networkmode, - df: &mode.DownloadFile{}, + df: df, } for _, tag := range tc.storageTags { err := strg.Save(ctx, tc.path, tag, []byte("mod"), bytes.NewReader([]byte("zip")), []byte("info")) @@ -238,6 +269,12 @@ var latestTests = []latestTest{ Time: time.Date(2018, 8, 3, 17, 16, 00, 0, time.UTC), }, }, + { + name: "download mode is none", + path: "golang.org/x/crypto", + info: nil, + err: true, + }, } func TestLatest(t *testing.T) { @@ -331,6 +368,12 @@ var modTests = []modTest{ version: "v1.0.0", err: true, }, + { + name: "download mode is none", + path: "golang.org/x/crypto", + version: "v0.6.0", + err: true, + }, } func rmNewLine(input string) string {