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()
+}