123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- /*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */
- package main
- import (
- "net/http"
- "path"
- "regexp"
- "strings"
- )
- type GoProxyRequestOp int
- const (
- GoProxyRequestNone GoProxyRequestOp = iota
- GoProxyRequestList
- GoProxyRequestInfo
- GoProxyRequestMod
- GoProxyRequestZip
- GoProxyRequestLatest
- )
- type GoProxyRequest struct {
- URI,
- Module, // The Go module name
- ImportPath, // Module without major version
- Host, // The part of the module name resolved in DNS
- RepoPath, // The URI path of the git repo
- Repo, // Git repository name; last component of RepoPath
- Version, // "Canonical" version (e.g. v2.1, v1.0.3, etc.)
- VersionMajor, // v1, v2, etc.
- Extension string // .info, .mod, .zip
- Op GoProxyRequestOp
- }
- var Major = regexp.MustCompile(`^v[0-9]+$`)
- var Version = regexp.MustCompile(`^v[0-9]+((\.[0-9]+)(\.[0-9]+)?)?$`)
- func parseGoProxyPath(
- req *http.Request,
- gpr *GoProxyRequest,
- ) {
- // This should be
- // /go/<module>[/{ @v/{ list | $version.{info|mod|zip} } | @latest }]
- clean := path.Clean(req.URL.Path)
- gpr.URI = path.Join(req.Host, clean)
- gpr.Host = req.Host
- gpr.Module = req.Host
- gpr.ImportPath = req.Host
- gpr.RepoPath = req.Host
- vector := strings.Split(clean, "/")
- i := 0
- i++ // empty subpath
- if i < len(vector) && vector[i] == "go" {
- gpr.Module = path.Join(gpr.Module, vector[i])
- i++
- }
- if i < len(vector) {
- gpr.Repo = vector[i]
- gpr.Module = path.Join(gpr.Module, gpr.Repo)
- gpr.ImportPath = gpr.Module
- gpr.RepoPath = path.Join(gpr.RepoPath, gpr.Repo)
- i++
- }
- if i < len(vector) && Major.MatchString(vector[i]) {
- gpr.VersionMajor = vector[i]
- gpr.Module = path.Join(gpr.Module, gpr.VersionMajor)
- i++
- }
- if i < len(vector) && vector[i] == "@latest" {
- gpr.Op = GoProxyRequestLatest
- return
- }
- if i+1 >= len(vector) || vector[i] != "@v" {
- return
- }
- // @v
- i++
- if vector[i] == "list" {
- gpr.Op = GoProxyRequestList
- return
- }
- ext := path.Ext(vector[i])
- tmp := strings.TrimSuffix(vector[i], ext)
- if !Version.MatchString(tmp) {
- return
- }
- // @version
- gpr.Version = tmp
- switch ext {
- case ".info":
- gpr.Op = GoProxyRequestInfo
- gpr.Extension = ext
- case ".mod":
- gpr.Op = GoProxyRequestMod
- gpr.Extension = ext
- case ".zip":
- gpr.Op = GoProxyRequestZip
- gpr.Extension = ext
- }
- }
|