Diff
1diff --git a/server/http.go b/server/http.go
2index 1074a31a97b9f1d4ca72b6ae3947ec96e6b0e42a..60a8650c76adc523fd0963eb74f675f308ee8c24 100644
3--- a/server/http.go
4+++ b/server/http.go
5@@ -5,6 +5,7 @@ import (
6 "fmt"
7 "net/http"
8 "net/url"
9+ "path"
10 "path/filepath"
11 "regexp"
12 "strings"
13@@ -248,43 +249,52 @@ Redirecting to docs at <a href="https://godoc.org/{{ .ImportRoot }}/{{ .Repo }}"
14 func (s *HTTPServer) handleIndex(w http.ResponseWriter, r *http.Request) {
15 repo := pattern.Path(r.Context())
16 repo = utils.SanitizeRepo(repo)
17- if _, err := s.cfg.Backend.Repository(repo); err != nil {
18- http.NotFound(w, r)
19- return
20- }
21-
22- // Only respond to go-get requests
23- if r.URL.Query().Get("go-get") != "1" {
24- http.NotFound(w, r)
25- return
26- }
27-
28- access := s.cfg.Backend.AccessLevel(repo, "")
29- if access < backend.ReadOnlyAccess {
30- http.NotFound(w, r)
31- return
32- }
33-
34- importRoot, err := url.Parse(s.cfg.HTTP.PublicURL)
35- if err != nil {
36- http.Error(w, err.Error(), http.StatusInternalServerError)
37- return
38- }
39
40- if err := repoIndexHTMLTpl.Execute(w, struct {
41- Repo string
42- Config *config.Config
43- ImportRoot string
44- }{
45- Repo: repo,
46- Config: s.cfg,
47- ImportRoot: importRoot.Host,
48- }); err != nil {
49- http.Error(w, err.Error(), http.StatusInternalServerError)
50+ // Handle go get requests.
51+ //
52+ // Always return a 200 status code, even if the repo doesn't exist.
53+ //
54+ // https://golang.org/cmd/go/#hdr-Remote_import_paths
55+ // https://go.dev/ref/mod#vcs-branch
56+ if r.URL.Query().Get("go-get") == "1" {
57+ repo := repo
58+ importRoot, err := url.Parse(s.cfg.HTTP.PublicURL)
59+ if err != nil {
60+ http.Error(w, err.Error(), http.StatusInternalServerError)
61+ return
62+ }
63+
64+ // find the repo
65+ for {
66+ if _, err := s.cfg.Backend.Repository(repo); err == nil {
67+ break
68+ }
69+
70+ if repo == "" || repo == "." || repo == "/" {
71+ return
72+ }
73+
74+ repo = path.Dir(repo)
75+ }
76+
77+ if err := repoIndexHTMLTpl.Execute(w, struct {
78+ Repo string
79+ Config *config.Config
80+ ImportRoot string
81+ }{
82+ Repo: url.PathEscape(repo),
83+ Config: s.cfg,
84+ ImportRoot: importRoot.Host,
85+ }); err != nil {
86+ http.Error(w, err.Error(), http.StatusInternalServerError)
87+ return
88+ }
89+
90+ goGetCounter.WithLabelValues(repo).Inc()
91 return
92 }
93
94- goGetCounter.WithLabelValues(repo).Inc()
95+ http.NotFound(w, r)
96 }
97
98 func (s *HTTPServer) handleGit(w http.ResponseWriter, r *http.Request) {