From bf2340151ff0cf3410525340f349b4522ffb7c66 Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Tue, 27 Feb 2024 10:41:20 -0500 Subject: [PATCH] cmd/coordinator: rewrite scheme-less URLs and redirects in dev mode This was created in preparation of removal of dashboard v2, which was going to use a redirect. However dashboard v2 turned out to be useful enough to warrant keeping and maintaining it. Apply this enhancement to the local development serving path since it is generally useful and already prepared. For golang/go#65913. Change-Id: I6006bfa02d512675b63773c22c9ed21d8d5b4ab4 Reviewed-on: https://go-review.googlesource.com/c/build/+/567497 Reviewed-by: Dmitri Shuralyov Auto-Submit: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Knyszek --- cmd/coordinator/coordinator.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go index 14cf9bc060..05f8ba7da6 100644 --- a/cmd/coordinator/coordinator.go +++ b/cmd/coordinator/coordinator.go @@ -174,8 +174,8 @@ func hostPathHandler(h http.Handler) http.Handler { // A linkRewriter is a ResponseWriter that rewrites links in HTML output. // It rewrites relative links /foo to be /host/foo, and it rewrites any link -// https://h/foo, where h is in validHosts, to be /h/foo. This corrects the -// links to have the right form for the test server. +// https://h/foo or //h/foo, where h is in validHosts, to be /h/foo. +// This corrects the links to have the right form for the local development mode. type linkRewriter struct { http.ResponseWriter host string @@ -183,6 +183,21 @@ type linkRewriter struct { ct string // content-type } +func (r *linkRewriter) WriteHeader(code int) { + if l := r.Header().Get("Location"); l != "" { + if u, err := url.Parse(l); err == nil { + if u.Host == "" { + u.Path = "/" + r.host + u.Path + } else if validHosts[u.Host] { + u.Path = "/" + u.Host + u.Path + u.Scheme, u.Host = "", "" + } + r.Header().Set("Location", u.String()) + } + } + r.ResponseWriter.WriteHeader(code) +} + func (r *linkRewriter) Write(data []byte) (int, error) { if r.ct == "" { ct := r.Header().Get("Content-Type") @@ -200,12 +215,12 @@ func (r *linkRewriter) Write(data []byte) (int, error) { } func (r *linkRewriter) Flush() { - repl := []string{ - `href="/`, `href="/` + r.host + `/`, - } + var repl []string for host := range validHosts { repl = append(repl, `href="https://`+host, `href="/`+host) + repl = append(repl, `href="//`+host, `href="/`+host) // Handle scheme-less URLs. } + repl = append(repl, `href="/`, `href="/`+r.host+`/`) strings.NewReplacer(repl...).WriteString(r.ResponseWriter, string(r.buf)) r.buf = nil }