goproxy/pkg/proxy/proxy.go

113 lines
2.9 KiB
Go
Raw Normal View History

2018-12-24 07:51:40 +00:00
package proxy
import (
"fmt"
"log"
"net/http"
"os"
"path"
"path/filepath"
"strings"
2018-12-25 09:47:06 +00:00
"github.com/goproxyio/goproxy/pkg/modfetch"
"github.com/goproxyio/goproxy/pkg/modfetch/codehost"
"github.com/goproxyio/goproxy/pkg/module"
2018-12-24 07:51:40 +00:00
)
var cacheDir string
var innerHandle http.Handler
func NewProxy(cache string) http.Handler {
2018-12-25 11:53:45 +00:00
modfetch.PkgMod = filepath.Join(cache, "pkg", "mod")
codehost.WorkRoot = filepath.Join(modfetch.PkgMod, "cache", "vcs")
2018-12-24 07:51:40 +00:00
2018-12-25 11:53:45 +00:00
cacheDir = filepath.Join(modfetch.PkgMod, "cache", "download")
2018-12-24 07:51:40 +00:00
innerHandle = http.FileServer(http.Dir(cacheDir))
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("goproxy: %s download %s\n", r.RemoteAddr, r.URL.Path)
if _, err := os.Stat(filepath.Join(cacheDir, r.URL.Path)); err != nil {
suffix := path.Ext(r.URL.Path)
if suffix == ".info" || suffix == ".mod" || suffix == ".zip" {
mod := strings.Split(r.URL.Path, "/@v/")
if len(mod) != 2 {
ReturnBadRequest(w, fmt.Errorf("bad module path:%s", r.URL.Path))
return
}
version := strings.TrimSuffix(mod[1], suffix)
version, err = module.DecodeVersion(version)
if err != nil {
ReturnServerError(w, err)
return
}
modPath := strings.TrimPrefix(mod[0], "/")
modPath, err := module.DecodePath(modPath)
if err != nil {
ReturnServerError(w, err)
return
}
// ignore the error, incorrect tag may be given
// forward to inner.ServeHTTP
if err := downloadMod(modPath, version); err != nil {
errLogger.Printf("download get err %s", err)
}
}
// fetch latest version
if strings.HasSuffix(r.URL.Path, "/@latest") {
modPath := strings.TrimSuffix(r.URL.Path, "/@latest")
modPath = strings.TrimPrefix(modPath, "/")
modPath, err := module.DecodePath(modPath)
if err != nil {
ReturnServerError(w, err)
return
}
2018-12-25 09:47:06 +00:00
repo, err := modfetch.Lookup(modPath)
if err != nil {
errLogger.Printf("lookup failed: %v", err)
ReturnServerError(w, err)
return
}
rev, err := repo.Stat("latest")
if err != nil {
errLogger.Printf("latest failed: %v", err)
2018-12-25 11:53:45 +00:00
return
2018-12-25 09:47:06 +00:00
}
if err := downloadMod(modPath, rev.Version); err != nil {
2018-12-24 07:51:40 +00:00
errLogger.Printf("download get err %s", err)
}
2018-12-25 11:53:45 +00:00
2018-12-24 07:51:40 +00:00
}
if strings.HasSuffix(r.URL.Path, "/@v/list") {
// TODO
_, _ = w.Write([]byte(""))
return
}
}
innerHandle.ServeHTTP(w, r)
})
}
func downloadMod(modPath, version string) error {
if _, err := modfetch.InfoFile(modPath, version); err != nil {
return err
}
if _, err := modfetch.GoModFile(modPath, version); err != nil {
return err
}
if _, err := modfetch.GoModSum(modPath, version); err != nil {
return err
}
mod := module.Version{Path: modPath, Version: version}
if _, err := modfetch.DownloadZip(mod); err != nil {
return err
}
if a, err := modfetch.Download(mod); err != nil {
return err
} else {
log.Printf("goproxy: download %s@%s to dir %s\n", modPath, version, a)
}
return nil
}