internal/middleware: delete GodocURL
Delete the GodocURL middleware since it is no longer needed.
Change-Id: I24b717e4d060ed19320e778afae6803b5404e49f
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/286512
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Trust: Julie Qiu <julie@golang.org>
diff --git a/cmd/frontend/main.go b/cmd/frontend/main.go
index b69c470..a98c274 100644
--- a/cmd/frontend/main.go
+++ b/cmd/frontend/main.go
@@ -191,7 +191,6 @@
middleware.RequestLog(cmdconfig.Logger(ctx, cfg, "frontend-log")),
middleware.AcceptRequests(http.MethodGet, http.MethodPost, http.MethodHead), // accept only GETs, POSTs and HEADs
middleware.Quota(cfg.Quota, cacheClient),
- middleware.GodocURL(), // potentially redirects so should be early in chain
middleware.RedirectedFrom(),
middleware.SecureHeaders(!*disableCSP), // must come before any caching for nonces to work
middleware.Experiment(experimenter),
diff --git a/content/static/html/pages/search.tmpl b/content/static/html/pages/search.tmpl
index a15d8f8..959fe48 100644
--- a/content/static/html/pages/search.tmpl
+++ b/content/static/html/pages/search.tmpl
@@ -6,7 +6,6 @@
{{define "main_content"}}
<div class="Container">
- <a class="GodocButton" href="{{.GodocURL}}">Back to godoc.org</a>
<div class="SearchResults">
<h1 class="SearchResults-header">Results for “{{.Query}}”</h1>
<div class="SearchResults-help"><a href="/search-help">Search help</a></div>
diff --git a/internal/frontend/server.go b/internal/frontend/server.go
index f841446..a00f001 100644
--- a/internal/frontend/server.go
+++ b/internal/frontend/server.go
@@ -243,9 +243,6 @@
// Experiments contains the experiments currently active.
Experiments *experiment.Set
- // GodocURL is the URL of the corresponding page on godoc.org (if applicable).
- GodocURL string
-
// DevMode indicates whether the server is running in development mode.
DevMode bool
@@ -285,7 +282,6 @@
HTMLTitle: title,
Query: searchQuery(r),
Experiments: experiment.FromContext(r.Context()),
- GodocURL: middleware.GodocURLPlaceholder,
DevMode: s.devMode,
AppVersionLabel: s.appVersionLabel,
GoogleTagManagerID: s.googleTagManagerID,
diff --git a/internal/middleware/godoc.go b/internal/middleware/godoc.go
deleted file mode 100644
index e93b828..0000000
--- a/internal/middleware/godoc.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2020 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 middleware
-
-import (
- "bytes"
- "net/http"
- "net/url"
-
- "golang.org/x/pkgsite/internal/log"
-)
-
-// GodocURLPlaceholder should be used as the value for any godoc.org URL in rendered
-// content. It is substituted for the actual godoc.org URL value by the GodocURL middleware.
-const GodocURLPlaceholder = "$$GODISCOVERY_GODOCURL$$"
-
-// GodocURL adds a corresponding godoc.org URL value to the rendered page
-// if the request is due to godoc.org automatically redirecting a user.
-// The value is empty otherwise.
-func GodocURL() Middleware {
- // In order to reliably know that a request is coming to pkg.go.dev from
- // godoc.org, we look for a utm_source GET parameter set to 'godoc'.
- // If we see this, we set a temporary cookie and redirect to the
- // pkg.go.dev URL with the utm_source param stripped (so that it doesn’t
- // remain in all our URLs coming from godoc.org). If this temporary cookie
- // is seen, a non-empty value for the “Back to godoc.org” link is set.
- // The existence of this value will be used to determine whether to show the
- // button in the UI.
- return func(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- const tmpCookieName = "tmp-from-godoc"
-
- // If the user is redirected from godoc.org, the request’s URL will have
- // utm_source=godoc.
- if r.FormValue("utm_source") == "godoc" {
- http.SetCookie(w, &http.Cookie{
- Name: tmpCookieName,
- Value: "1",
- SameSite: http.SameSiteLaxMode, // request can originate from another domain via redirect
- })
-
- // Redirect to the same URL only without the utm_source parameter.
- u := r.URL
- q := u.Query()
- q.Del("utm_source")
- u.RawQuery = q.Encode()
- http.Redirect(w, r, u.String(), http.StatusFound)
- return
- }
-
- godocURL := godoc(r.URL)
- if _, err := r.Cookie(tmpCookieName); err == http.ErrNoCookie {
- // Cookie isn’t set, indicating user is not coming from godoc.org.
- godocURL = ""
- } else {
- http.SetCookie(w, &http.Cookie{
- Name: tmpCookieName,
- MaxAge: -1,
- })
- }
-
- crw := &capturingResponseWriter{ResponseWriter: w}
- h.ServeHTTP(crw, r)
- body := crw.bytes()
- body = bytes.ReplaceAll(body, []byte(GodocURLPlaceholder), []byte(godocURL))
- if _, err := w.Write(body); err != nil {
- log.Errorf(r.Context(), "GodocURL, writing: %v", err)
- }
- })
- }
-}
-
-// godoc takes a Discovery URL and returns the corresponding godoc.org equivalent.
-func godoc(u *url.URL) string {
- result := &url.URL{Scheme: "https", Host: "godoc.org"}
-
- switch u.Path {
- case "/std":
- result.Path = "/-/go"
- case "/about":
- result.Path = "/-/about"
- case "/search":
- result.Path = "/"
- result.RawQuery = u.RawQuery
- default:
- {
- result.Path = u.Path
- switch u.Query().Get("tab") {
- case "imports":
- result.RawQuery = "imports"
- case "importedby":
- result.RawQuery = "importers"
- case "subdirectories":
- result.Fragment = "pkg-subdirectories"
- }
- }
- }
- q := result.Query()
- q.Add("utm_source", "backtogodoc")
- result.RawQuery = q.Encode()
- return result.String()
-}
-
-// capturingResponseWriter is an http.ResponseWriter that captures
-// the body for later processing.
-type capturingResponseWriter struct {
- http.ResponseWriter
- buf bytes.Buffer
-}
-
-func (c *capturingResponseWriter) Write(b []byte) (int, error) {
- return c.buf.Write(b)
-}
-
-func (c *capturingResponseWriter) bytes() []byte {
- return c.buf.Bytes()
-}
diff --git a/internal/middleware/godoc_test.go b/internal/middleware/godoc_test.go
deleted file mode 100644
index d656ead..0000000
--- a/internal/middleware/godoc_test.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2020 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 middleware
-
-import (
- "bytes"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "net/url"
- "testing"
-)
-
-func TestGodocURL(t *testing.T) {
- mw := GodocURL()
- mwh := mw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- body := []byte(`<a href="$$GODISCOVERY_GODOCURL$$">godoc</a>`)
- if _, err := w.Write(body); err != nil {
- t.Fatalf("w.Write(%q) = %v", body, err)
- }
- }))
-
- testCases := []struct {
- desc string
-
- // Request values
- path string
- cookies map[string]string
-
- // Response values
- code int
- body []byte
- headers map[string]string
- }{
- {
- desc: "Unaffected request",
- path: "/cloud.google.com/go/storage",
- code: http.StatusOK,
- body: []byte(`<a href="">godoc</a>`),
- },
- {
- desc: "Strip utm_source, set temporary cookie, and redirect",
- path: "/cloud.google.com/go/storage?utm_source=godoc",
- code: http.StatusFound,
- headers: map[string]string{
- "Location": "/cloud.google.com/go/storage",
- "Set-Cookie": "tmp-from-godoc=1; SameSite=Lax",
- },
- },
- {
- desc: "Delete temporary cookie; godoc URL should be set",
- path: "/cloud.google.com/go/storage",
- cookies: map[string]string{
- "tmp-from-godoc": "1",
- },
- code: http.StatusOK,
- body: []byte(`<a href="https://godoc.org/cloud.google.com/go/storage?utm_source=backtogodoc">godoc</a>`),
- headers: map[string]string{
- "Set-Cookie": "tmp-from-godoc=; Max-Age=0",
- },
- },
- }
-
- for _, test := range testCases {
- t.Run(test.desc, func(t *testing.T) {
- req := httptest.NewRequest("GET", test.path, nil)
- for k, v := range test.cookies {
- req.AddCookie(&http.Cookie{
- Name: k,
- Value: v,
- })
- }
- w := httptest.NewRecorder()
- mwh.ServeHTTP(w, req)
- resp := w.Result()
- defer resp.Body.Close()
- if got, want := resp.StatusCode, test.code; got != want {
- t.Errorf("Status code = %d; want %d", got, want)
- }
- if resp.StatusCode >= 200 && resp.StatusCode < 300 {
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- t.Fatalf("ioutil.ReadAll(resp.Body) = %v", err)
- }
- if got, want := body, test.body; !bytes.Equal(got, want) {
- t.Errorf("Response body = %q; want %q", got, want)
- }
- }
- for k, v := range test.headers {
- if _, ok := resp.Header[k]; !ok {
- t.Errorf("%q not present in response headers", k)
- continue
- }
- if got, want := resp.Header.Get(k), v; got != want {
- t.Errorf("Response header mismatch for %q: got %q; want %q", k, got, want)
- }
- }
- })
- }
-}
-
-func TestGodoc(t *testing.T) {
- testCases := []struct {
- from, to string
- }{
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage",
- to: "https://godoc.org/cloud.google.com/go/storage?utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage?tab=overview",
- to: "https://godoc.org/cloud.google.com/go/storage?utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage?tab=versions",
- to: "https://godoc.org/cloud.google.com/go/storage?utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage?tab=licenses",
- to: "https://godoc.org/cloud.google.com/go/storage?utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage?tab=subdirectories",
- to: "https://godoc.org/cloud.google.com/go/storage?utm_source=backtogodoc#pkg-subdirectories",
- },
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage?tab=imports",
- to: "https://godoc.org/cloud.google.com/go/storage?imports=&utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/cloud.google.com/go/storage?tab=importedby",
- to: "https://godoc.org/cloud.google.com/go/storage?importers=&utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/std?tab=packages",
- to: "https://godoc.org/-/go?utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/search?q=foo",
- to: "https://godoc.org/?q=foo&utm_source=backtogodoc",
- },
- {
- from: "https://pkg.go.dev/about",
- to: "https://godoc.org/-/about?utm_source=backtogodoc",
- },
- }
-
- for _, test := range testCases {
- u, err := url.Parse(test.from)
- if err != nil {
- t.Errorf("url.Parse(%q): %v", test.from, err)
- continue
- }
- to := godoc(u)
- if got, want := to, test.to; got != want {
- t.Errorf("godocURL(%q) = %q; want %q", u, got, want)
- }
- }
-}
diff --git a/internal/middleware/latestversion.go b/internal/middleware/latestversion.go
index 6409168..f3bc9ab 100644
--- a/internal/middleware/latestversion.go
+++ b/internal/middleware/latestversion.go
@@ -85,3 +85,18 @@
})
}
}
+
+// capturingResponseWriter is an http.ResponseWriter that captures
+// the body for later processing.
+type capturingResponseWriter struct {
+ http.ResponseWriter
+ buf bytes.Buffer
+}
+
+func (c *capturingResponseWriter) Write(b []byte) (int, error) {
+ return c.buf.Write(b)
+}
+
+func (c *capturingResponseWriter) bytes() []byte {
+ return c.buf.Bytes()
+}