aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas S. Husin <nsh@golang.org>2025-11-20 17:25:03 -0500
committerNicholas Husin <nsh@golang.org>2025-11-20 15:15:27 -0800
commit8f9da77619fd679c63e77756af5d9b4bf0f81e99 (patch)
treefbac2ee64eddb5e7ecf3f2502eb917fbad955d61
parent7b82d6b8b40d831f0ad2ee33a0fb8d798910fdf0 (diff)
downloadgo-x-website-8f9da77619fd679c63e77756af5d9b4bf0f81e99.tar.xz
internal/redirect: add redirect from go.dev/cs to cs.opensource.google
This change makes it so that go.dev/cs redirects to cs.opensource.google/go while keeping any path and URL parameter intact. This allows users to link code within cs.opensource.google/go using go.dev/cs. As a special case, go.dev/cs/search/ has also been added. Anything that comes after /search/ will be used as the Code Search query parameter within the "go" project in cs.opensource.google/search. This allows users to search within the codebase in one go from their browser's URL bar. Change-Id: I1eae8c2e0d18c7e94bc85cced81404716f29ed99 Reviewed-on: https://go-review.googlesource.com/c/website/+/722560 Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Nicholas Husin <husin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
-rw-r--r--internal/redirect/redirect.go33
-rw-r--r--internal/redirect/redirect_test.go10
2 files changed, 43 insertions, 0 deletions
diff --git a/internal/redirect/redirect.go b/internal/redirect/redirect.go
index e12455b8..d3e242d2 100644
--- a/internal/redirect/redirect.go
+++ b/internal/redirect/redirect.go
@@ -13,6 +13,7 @@ import (
"fmt"
"html/template"
"net/http"
+ "net/url"
"regexp"
"strconv"
"strings"
@@ -44,6 +45,7 @@ func Register(mux *http.ServeMux) {
// NB: /src/pkg (sans trailing slash) is the index of packages.
mux.HandleFunc("/src/pkg/", srcPkgHandler)
mux.HandleFunc("/cl/", clHandler)
+ mux.HandleFunc("/cs/", csHandler)
mux.HandleFunc("/change/", changeHandler)
mux.HandleFunc("/design/", designHandler)
}
@@ -101,6 +103,7 @@ var redirects = map[string]string{
"/build": "https://build.golang.org",
"/change": "https://go.googlesource.com/go",
"/cl": "https://go-review.googlesource.com",
+ "/cs": "https://cs.opensource.google/go",
"/cmd/godoc/": "https://pkg.go.dev/golang.org/x/tools/cmd/godoc",
"/issue": "https://github.com/golang/go/issues",
"/issues": "https://github.com/golang/go/issues",
@@ -372,3 +375,33 @@ func designHandler(w http.ResponseWriter, r *http.Request) {
target := "https://go.googlesource.com/proposal/+/master/design/" + name + ".md"
http.Redirect(w, r, target, http.StatusFound)
}
+
+func csHandler(w http.ResponseWriter, r *http.Request) {
+ path, ok := strings.CutPrefix(r.URL.Path, "/cs/")
+ if !ok || path == "" {
+ http.Redirect(w, r, "/cs", http.StatusFound)
+ return
+ }
+
+ // /cs/search/<query> redirects to cs.opensource.google/search. <query>
+ // represents Code Search syntax which we will automatically put as part of
+ // the URL query parameter for convenience. The search will always be
+ // scoped to "go".
+ if query, ok := strings.CutPrefix(path, "search/"); ok {
+ target := "https://cs.opensource.google/search?ss=go"
+ if query != "" {
+ target += "&q=" + url.QueryEscape(query)
+ }
+ http.Redirect(w, r, target, http.StatusFound)
+ return
+ }
+
+ // Any other /cs/ redirects to cs.opensource.google/go while keeping the
+ // path and URL query intact.
+ target := "https://cs.opensource.google/go/"
+ target += path
+ if query := r.URL.RawQuery; query != "" {
+ target += "?" + query
+ }
+ http.Redirect(w, r, target, http.StatusFound)
+}
diff --git a/internal/redirect/redirect_test.go b/internal/redirect/redirect_test.go
index 10d4de05..e7e2cd9d 100644
--- a/internal/redirect/redirect_test.go
+++ b/internal/redirect/redirect_test.go
@@ -108,6 +108,16 @@ func TestRedirects(t *testing.T) {
// And verify we're using the "bigEnoughAssumeRietveld" value:
"/cl/3999999": {302, "https://go-review.googlesource.com/3999999"},
"/cl/4000000": {302, "https://codereview.appspot.com/4000000"},
+
+ "/cs": {301, "https://cs.opensource.google/go"},
+ "/cs/": {302, "/cs"},
+ "/cs/x/pkgsite": {302, "https://cs.opensource.google/go/x/pkgsite"},
+ "/cs/x/net/+/master:http/httpguts/httplex.go;l=57-69;drc=0a24555f5cc06e8caf23d84a4f8b7102dcab838e": {302, "https://cs.opensource.google/go/x/net/+/master:http/httpguts/httplex.go;l=57-69;drc=0a24555f5cc06e8caf23d84a4f8b7102dcab838e"},
+
+ "/cs/search/": {302, "https://cs.opensource.google/search?ss=go"},
+ "/cs/search/f:test.go": {302, "https://cs.opensource.google/search?ss=go&q=f%3Atest.go"},
+ "/cs/search/func:Bench AND f:bench.go": {302, "https://cs.opensource.google/search?ss=go&q=func%3ABench+AND+f%3Abench.go"},
+ "/cs/search/\"&\"": {302, "https://cs.opensource.google/search?ss=go&q=%22%26%22"},
}
mux := http.NewServeMux()