From fcd33bbfd8e4aa7a110bce18b8380a450efbc85a Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Sat, 23 May 2015 12:12:45 +0200 Subject: [PATCH] Improve web redirection and 404 behavior. Previously we redirected any non-existent path to the root (or path prefix). The new behavior: With no path prefix: - "" -> "/" - "/biz" -> 404 With path prefix of "/foo/bar": - "" -> "/foo/bar/" - "/" -> "/foo/bar/" - "/foo/bar" -> "/foo/bar/" - "/biz" -> /foo/bar/biz" (anything not starting with the path prefix gets the prefix prepended) - "/foo/bar/biz" -> 404 --- web/web.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/web/web.go b/web/web.go index 2b33104b1..aee83be9c 100644 --- a/web/web.go +++ b/web/web.go @@ -64,9 +64,21 @@ func (ws WebService) ServeForever(pathPrefix string) { http.Error(w, "", 404) })) - http.Handle(pathPrefix, prometheus.InstrumentHandler( - pathPrefix, ws.StatusHandler, - )) + http.HandleFunc("/", prometheus.InstrumentHandlerFunc(pathPrefix, func(rw http.ResponseWriter, req *http.Request) { + // The "/" pattern matches everything, so we need to check + // that we're at the root here. + if req.URL.Path == pathPrefix { + ws.StatusHandler.ServeHTTP(rw, req) + } else if req.URL.Path == strings.TrimRight(pathPrefix, "/") { + http.Redirect(rw, req, pathPrefix, http.StatusFound) + } else if !strings.HasPrefix(req.URL.Path, pathPrefix) { + // We're running under a prefix but the user requested something + // outside of it. Let's see if this page exists under the prefix. + http.Redirect(rw, req, pathPrefix+strings.TrimLeft(req.URL.Path, "/"), http.StatusFound) + } else { + http.NotFound(rw, req) + } + })) http.Handle(pathPrefix+"alerts", prometheus.InstrumentHandler( pathPrefix+"alerts", ws.AlertsHandler, )) @@ -102,12 +114,6 @@ func (ws WebService) ServeForever(pathPrefix string) { http.Handle(pathPrefix+"-/quit", http.HandlerFunc(ws.quitHandler)) } - if pathPrefix != "/" { - http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, pathPrefix, http.StatusFound) - })) - } - log.Infof("Listening on %s", *listenAddress) // If we cannot bind to a port, retry after 30 seconds.