package middleware import ( "fmt" "html" "net/http" "strings" ) // GoImport serves the `` tag required by `go install` / // `go get` to resolve the vanity path `atcr.io/...` to the source repository. // // Go tooling requests `https://atcr.io/?go-get=1` and expects an HTML // document with a meta tag of the form: // // // // The meta tag must be present on every subpath under the module root, so this // runs as middleware at the top of the chain and short-circuits any request // carrying `?go-get=1`. // // For non-go-get requests on paths that look like Go module subpaths // (/cmd/, /pkg/, /internal/, /scanner/), the middleware redirects to the // corresponding source-tree URL in the git host so a browser visit doesn't // 404. The redirect template mirrors the `go-source` meta tag's // `{repoURL}/tree/main{/dir}` form. func GoImport(modulePath, repoURL string) func(http.Handler) http.Handler { body := fmt.Sprintf( `go get %s`, html.EscapeString(modulePath), html.EscapeString(repoURL), html.EscapeString(modulePath), html.EscapeString(repoURL), html.EscapeString(repoURL), html.EscapeString(repoURL), html.EscapeString(modulePath), ) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("go-get") == "1" { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Cache-Control", "public, max-age=300") _, _ = w.Write([]byte(body)) return } // Browser visits to recognizable Go subpaths get redirected to // the repo source tree instead of falling through to the // appview router (which 404s for these paths). if isGoModuleSubpath(r.URL.Path) { target := repoURL + "/tree/main" + r.URL.Path http.Redirect(w, r, target, http.StatusFound) return } next.ServeHTTP(w, r) }) } } // isGoModuleSubpath reports whether p looks like a Go module source path // (under cmd/, pkg/, internal/, or scanner/). The check is intentionally // narrow so the redirect doesn't hijack other appview routes. func isGoModuleSubpath(p string) bool { switch { case strings.HasPrefix(p, "/cmd/"), strings.HasPrefix(p, "/pkg/"), strings.HasPrefix(p, "/internal/"): return true } return false }