github.com/sirkon/goproxy@v1.4.8/plugin/apriori/plugin.go (about) 1 package apriori 2 3 import ( 4 "encoding/json" 5 "io/ioutil" 6 "net/http" 7 8 "github.com/sirkon/goproxy/internal/errors" 9 10 "github.com/sirkon/goproxy" 11 ) 12 13 // ModuleInfo information needed for go modules proxy protocol 14 type ModuleInfo struct { 15 RevInfo goproxy.RevInfo 16 GoModPath string 17 ArchivePath string 18 } 19 20 // Mapping maps path → (version → module info) 21 type Mapping map[string]map[string]ModuleInfo 22 23 // NewPlugin "apriori" - "cache" is boring: some file may contains information 24 // <mod path> → <version> → (<rev info>, <go.mod path>, <zip archive path>) and what it hidden there is enough for a 25 // functional go proxy serving exactly these modules at exactly these versions 26 func NewPlugin(path string) (goproxy.Plugin, error) { 27 var res plugin 28 data, err := ioutil.ReadFile(path) 29 if err != nil { 30 return nil, errors.Wrap(err, "getting apriori file") 31 } 32 if err := json.Unmarshal(data, &res.mapping); err != nil { 33 return nil, errors.Wrapf(err, "parsing apriori file %s", path) 34 } 35 return &res, nil 36 } 37 38 type plugin struct { 39 mapping Mapping 40 } 41 42 func (p *plugin) Module(req *http.Request, prefix string) (goproxy.Module, error) { 43 mod, _, err := goproxy.GetModInfo(req, prefix) 44 if err != nil { 45 return nil, err 46 } 47 modInfo, ok := p.mapping[mod] 48 if !ok { 49 return nil, errors.Newf("no module %s found in cache", mod) 50 } 51 return &aprioriModule{path: mod, mod: modInfo}, nil 52 } 53 54 func (p *plugin) Leave(source goproxy.Module) error { 55 return nil 56 } 57 58 func (p *plugin) Close() error { 59 return nil 60 } 61 62 func (p *plugin) String() string { 63 return "cache" 64 }