github.com/sirkon/goproxy@v1.4.8/mod_info.go (about) 1 package goproxy 2 3 import ( 4 "net/http" 5 "strings" 6 7 "github.com/sirkon/goproxy/internal/errors" 8 9 "github.com/sirkon/goproxy/internal/module" 10 ) 11 12 const ( 13 slashDogVSlash = "/@v/" 14 constSlashDogLatest = "/@latest" 15 ) 16 17 // modInfoExtraction ... 18 type modInfoExtraction struct { 19 Rest string 20 Module string 21 Suffix string 22 } 23 24 // Extract ... 25 func (p *modInfoExtraction) Extract(line string) (bool, error) { 26 p.Rest = line 27 var pos int 28 29 // Checks if the rest starts with '/' and pass it 30 if len(p.Rest) >= 1 && p.Rest[0] == '/' { 31 p.Rest = p.Rest[1:] 32 } else { 33 return false, errors.Newf("/<url> expected, got %s", line) 34 } 35 36 // Take until "/@v/" as Module(string) 37 pos = strings.Index(p.Rest, slashDogVSlash) 38 if pos >= 0 { 39 p.Module = p.Rest[:pos] 40 p.Rest = p.Rest[pos+len(slashDogVSlash):] 41 } else { 42 return false, errors.Newf("/@v/ was not found in %s", p.Rest) 43 } 44 45 // Take the rest as Suffix(string) 46 p.Suffix = p.Rest 47 p.Rest = p.Rest[len(p.Rest):] 48 return true, nil 49 } 50 51 // latestExtraction ... 52 type latestExtraction struct { 53 Rest string 54 Path string 55 } 56 57 // Extract ... 58 func (p *latestExtraction) Extract(line string) (bool, error) { 59 p.Rest = line 60 var pos int 61 62 // Checks if the rest starts with '/' and pass it 63 if len(p.Rest) >= 1 && p.Rest[0] == '/' { 64 p.Rest = p.Rest[1:] 65 } else { 66 return false, nil 67 } 68 69 // Take until "/@latest" as Path(string) 70 pos = strings.Index(p.Rest, constSlashDogLatest) 71 if pos >= 0 { 72 p.Path = p.Rest[:pos] 73 p.Rest = p.Rest[pos+len(constSlashDogLatest):] 74 } else { 75 return false, nil 76 } 77 78 return true, nil 79 } 80 81 // GetModInfo retrieves mod info from URL 82 func GetModInfo(req *http.Request, prefix string) (path string, suffix string, err error) { 83 method := req.URL.Path 84 if !strings.HasPrefix(method, prefix) { 85 err = errors.Newf("request URL path expected to be a %s*, got %s", prefix, method) 86 } 87 method = method[len(prefix):] 88 89 var ok bool 90 var le latestExtraction 91 var e modInfoExtraction 92 93 if ok, _ = le.Extract(method); ok { 94 path = le.Path 95 suffix = "latest" 96 97 } else if ok, err = e.Extract(method); ok { 98 path = e.Module 99 suffix = e.Suffix 100 } else { 101 err = errors.Wrapf(err, "invalid go proxy request, wrong URL %s", method) 102 return 103 } 104 105 path, err = module.DecodePath(path) 106 if err != nil { 107 return 108 } 109 110 return 111 } 112 113 // PathEncoding returns go module encoded path 114 func PathEncoding(path string) (string, error) { 115 return module.EncodePath(path) 116 }