package paths import ( "net/http" "path" "strings" "github.com/gomods/athens/pkg/errors" "github.com/gorilla/mux" ) // GetModule gets the module from the path of a ?go-get=1 request. func GetModule(r *http.Request) (string, error) { const op errors.Op = "paths.GetModule" module := mux.Vars(r)["module"] if module == "" { return "", errors.E(op, "missing module parameter") } return DecodePath(module) } // GetVersion gets the version from the path of a ?go-get=1 request. func GetVersion(r *http.Request) (string, error) { const op errors.Op = "paths.GetVersion" version := mux.Vars(r)["version"] if version == "" { return "", errors.E(op, "missing version parameter") } return DecodePath(version) } // AllPathParams holds the module and version in the path of a ?go-get=1 // request. type AllPathParams struct { Module string `json:"module"` Version string `json:"version"` } // GetAllParams fetches the path params from r and returns them. func GetAllParams(r *http.Request) (*AllPathParams, error) { const op errors.Op = "paths.GetAllParams" mod, err := GetModule(r) if err != nil { return nil, errors.E(op, err) } version, err := GetVersion(r) if err != nil { return nil, errors.E(op, err) } return &AllPathParams{Module: mod, Version: version}, nil } // MatchesPattern reports whether the path prefix of target matches // pattern (as defined by path.Match). // // This tries to keep the same behavior as GOPRIVATE/GONOPROXY/GONOSUMDB, // and is adopted from: // https://github.com/golang/go/blob/a11644a26557ea436d456f005f39f4e01902bafe/src/cmd/go/internal/str/path.go#L58 func MatchesPattern(pattern, target string) bool { n := strings.Count(pattern, "/") prefix := target for i := 0; i < len(target); i++ { if target[i] == '/' { if n == 0 { prefix = target[:i] break } n-- } } if n > 0 { return false } matched, _ := path.Match(pattern, prefix) return matched }