internal/frontend: fix github.com/golang/go redirects
Previously, any URL with the prefix /github.com/golang/go redirected to
their corresponding package page (for example, /std or /cmd/go).
However, this also redirected paths like /github.com/golang/gofrontend.
This bug is now fixed and a test is added.
Fixes golang/go#47957
Change-Id: Iabcc2c57ef9f5365d93911a4971addb8bb5a903d
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/344989
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/internal/frontend/details.go b/internal/frontend/details.go
index a534635..342e387 100644
--- a/internal/frontend/details.go
+++ b/internal/frontend/details.go
@@ -17,6 +17,7 @@
"golang.org/x/mod/semver"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/middleware"
+ "golang.org/x/pkgsite/internal/stdlib"
)
// serveDetails handles requests for package/directory/module details pages. It
@@ -33,15 +34,6 @@
s.staticPageHandler("homepage", "Home")(w, r)
return nil
}
- if strings.HasPrefix(r.URL.Path, "/github.com/golang/go") {
- urlPath := strings.TrimPrefix(strings.TrimPrefix(r.URL.Path, "/github.com/golang/go"), "/src")
- if urlPath == "" {
- http.Redirect(w, r, "/std", http.StatusMovedPermanently)
- return
- }
- http.Redirect(w, r, urlPath, http.StatusMovedPermanently)
- return
- }
if strings.HasSuffix(r.URL.Path, "/") {
http.Redirect(w, r, strings.TrimSuffix(r.URL.Path, "/"), http.StatusMovedPermanently)
return
@@ -69,12 +61,30 @@
if !isSupportedVersion(urlInfo.fullPath, urlInfo.requestedVersion) {
return invalidVersionError(urlInfo.fullPath, urlInfo.requestedVersion)
}
+ if urlPath := stdlibRedirectURL(urlInfo.fullPath); urlPath != "" {
+ http.Redirect(w, r, urlPath, http.StatusMovedPermanently)
+ return
+ }
if err := checkExcluded(ctx, ds, urlInfo.fullPath); err != nil {
return err
}
return s.serveUnitPage(ctx, w, r, ds, urlInfo)
}
+func stdlibRedirectURL(fullPath string) string {
+ if !strings.HasPrefix(fullPath, stdlib.GitHubRepo) {
+ return ""
+ }
+ if fullPath == stdlib.GitHubRepo || fullPath == stdlib.GitHubRepo+"/src" {
+ return "/std"
+ }
+ urlPath2 := strings.TrimPrefix(strings.TrimPrefix(fullPath, stdlib.GitHubRepo+"/"), "src/")
+ if fullPath == urlPath2 {
+ return ""
+ }
+ return "/" + urlPath2
+}
+
func invalidVersionError(fullPath, requestedVersion string) error {
return &serverError{
status: http.StatusBadRequest,
diff --git a/internal/frontend/details_test.go b/internal/frontend/details_test.go
new file mode 100644
index 0000000..a84e8a9
--- /dev/null
+++ b/internal/frontend/details_test.go
@@ -0,0 +1,30 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package frontend
+
+import (
+ "testing"
+)
+
+func TestStdlibRedirectURL(t *testing.T) {
+ for _, test := range []struct {
+ path string
+ want string
+ }{
+ {"std", ""},
+ {"cmd/go", ""},
+ {"github.com/golang/go", "/std"},
+ {"github.com/golang/go/src", "/std"},
+ {"github.com/golang/go/src", "/std"},
+ {"github.com/golang/go/cmd/go", "/cmd/go"},
+ {"github.com/golang/go/src/cmd/go", "/cmd/go"},
+ {"github.com/golang/gofrontend", ""},
+ {"github.com/golang/gofrontend/libgo/misc/cgo/frontend/libgo/misc", ""},
+ } {
+ if got := stdlibRedirectURL(test.path); got != test.want {
+ t.Errorf("stdlibRedirectURL(%q) = %q; want = %q", test.path, got, test.want)
+ }
+ }
+}
diff --git a/internal/stdlib/stdlib.go b/internal/stdlib/stdlib.go
index 08fc407..d875773 100644
--- a/internal/stdlib/stdlib.go
+++ b/internal/stdlib/stdlib.go
@@ -184,6 +184,8 @@
const (
GoRepoURL = "https://go.googlesource.com/go"
GoSourceRepoURL = "https://cs.opensource.google/go/go"
+
+ GitHubRepo = "github.com/golang/go"
)
// UseTestData determines whether to really clone the Go repo, or use