gddo-server: add utm_source to pkg.go.dev redirect URLs
This will reliably indicate to pkg.go.dev that a request is due
to the automatic redirect logic.
Additional logic is added for more accurate mapping of
godoc.org -> pkg.go.dev URLs.
Updates golang/go#37099
Change-Id: Iba380a3b5951d50576c17711990d0ba87857b926
Reviewed-on: https://go-review.googlesource.com/c/gddo/+/224659
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/gddo-server/main.go b/gddo-server/main.go
index 795df07..5154bf4 100644
--- a/gddo-server/main.go
+++ b/gddo-server/main.go
@@ -1095,16 +1095,9 @@
return req.FormValue("utm_source") == "backtogodoc"
}
-var gddoToPkgGoDevRequest = map[string]string{
- "/-/about": "/about",
- "/-/go": "/std",
-}
-
// pkgGoDevRedirectHandler redirects requests from godoc.org to pkg.go.dev,
// based on whether a cookie is set for pkggodev-redirect. The cookie
-// can be turned on/off using a query param. It determines which path to
-// direct to by checking if a path is mapped in gddoToPkgGoDevRequest, and
-// if not redirecting to the same path that was used for the godoc.org request.
+// can be turned on/off using a query param.
func pkgGoDevRedirectHandler(f func(http.ResponseWriter, *http.Request) error) func(http.ResponseWriter, *http.Request) error {
return func(w http.ResponseWriter, r *http.Request) error {
if userReturningFromPkgGoDev(r) {
@@ -1138,17 +1131,45 @@
return f(w, r)
}
- path, ok := gddoToPkgGoDevRequest[r.URL.Path]
- if !ok {
- path = r.URL.Path
- }
-
- nextUrl := url.URL{Scheme: "https", Host: pkgGoDevHost, Path: path}
- http.Redirect(w, r, nextUrl.String(), http.StatusFound)
+ http.Redirect(w, r, pkgGoDevURL(r.URL).String(), http.StatusFound)
return nil
}
}
+func pkgGoDevURL(godocURL *url.URL) *url.URL {
+ u := &url.URL{Scheme: "https", Host: pkgGoDevHost}
+ q := url.Values{"utm_source": []string{"godoc"}}
+
+ switch godocURL.Path {
+ case "/-/go":
+ u.Path = "/std"
+ q.Add("tab", "packages")
+ case "/-/about":
+ u.Path = "/about"
+ case "/":
+ if qparam := godocURL.Query().Get("q"); qparam != "" {
+ u.Path = "/search"
+ q.Set("q", qparam)
+ } else {
+ u.Path = "/"
+ }
+ default:
+ {
+ u.Path = godocURL.Path
+ if _, ok := godocURL.Query()["imports"]; ok {
+ q.Set("tab", "imports")
+ } else if _, ok := godocURL.Query()["importers"]; ok {
+ q.Set("tab", "importedby")
+ } else {
+ q.Set("tab", "doc")
+ }
+ }
+ }
+
+ u.RawQuery = q.Encode()
+ return u
+}
+
func main() {
ctx := context.Background()
v, err := loadConfig(ctx, os.Args)
diff --git a/gddo-server/main_test.go b/gddo-server/main_test.go
index 269030a..9e9d3e8 100644
--- a/gddo-server/main_test.go
+++ b/gddo-server/main_test.go
@@ -9,6 +9,7 @@
import (
"net/http"
"net/http/httptest"
+ "net/url"
"testing"
"github.com/google/go-cmp/cmp"
@@ -51,7 +52,7 @@
{
name: "test pkggodev-redirect param is on",
url: "http://godoc.org/net/http?redirect=on",
- wantLocationHeader: "https://pkg.go.dev/net/http",
+ wantLocationHeader: "https://pkg.go.dev/net/http?tab=doc&utm_source=godoc",
wantSetCookieHeader: "pkggodev-redirect=on; Path=/",
wantStatusCode: http.StatusFound,
},
@@ -81,7 +82,7 @@
name: "pkggodev-redirect enabled cookie should redirect",
url: "http://godoc.org/net/http",
cookie: &http.Cookie{Name: "pkggodev-redirect", Value: "on"},
- wantLocationHeader: "https://pkg.go.dev/net/http",
+ wantLocationHeader: "https://pkg.go.dev/net/http?tab=doc&utm_source=godoc",
wantSetCookieHeader: "",
wantStatusCode: http.StatusFound,
},
@@ -120,6 +121,49 @@
}
}
+func TestGodoc(t *testing.T) {
+ testCases := []struct {
+ from, to string
+ }{
+ {
+ from: "https://godoc.org/-/about",
+ to: "https://pkg.go.dev/about?utm_source=godoc",
+ },
+ {
+ from: "https://godoc.org/-/go",
+ to: "https://pkg.go.dev/std?tab=packages&utm_source=godoc",
+ },
+ {
+ from: "https://godoc.org/?q=foo",
+ to: "https://pkg.go.dev/search?q=foo&utm_source=godoc",
+ },
+ {
+ from: "https://godoc.org/cloud.google.com/go/storage",
+ to: "https://pkg.go.dev/cloud.google.com/go/storage?tab=doc&utm_source=godoc",
+ },
+ {
+ from: "https://godoc.org/cloud.google.com/go/storage?imports",
+ to: "https://pkg.go.dev/cloud.google.com/go/storage?tab=imports&utm_source=godoc",
+ },
+ {
+ from: "https://godoc.org/cloud.google.com/go/storage?importers",
+ to: "https://pkg.go.dev/cloud.google.com/go/storage?tab=importedby&utm_source=godoc",
+ },
+ }
+
+ for _, tc := range testCases {
+ u, err := url.Parse(tc.from)
+ if err != nil {
+ t.Errorf("url.Parse(%q): %v", tc.from, err)
+ continue
+ }
+ to := pkgGoDevURL(u)
+ if got, want := to.String(), tc.to; got != want {
+ t.Errorf("pkgGoDevURL(%q) = %q; want %q", u, got, want)
+ }
+ }
+}
+
func TestNewGDDOEvent(t *testing.T) {
for _, test := range []struct {
url string