diff --git a/fe/http.go b/fe/http.go index 1e1b072ce80c742fcca54b38cb809ffd591f9f99..a0346d843dbf9bf7399ff06a44640a20aacaac22 100644 --- a/fe/http.go +++ b/fe/http.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "net/url" + "path" "path/filepath" "strconv" "strings" @@ -129,6 +130,41 @@ func (h *HttpRedirector) serveM3U(mount *autoradio.Mount, w http.ResponseWriter, io.WriteString(w, m3u) } +// redirect replies to the request with a redirect to url, adding some +// cache-busting headers. Code is mostly verbatim from net/http. +func redirect(w http.ResponseWriter, r *http.Request, urlStr string, code int) { + if u, err := url.Parse(urlStr); err == nil { + oldpath := r.URL.Path + if oldpath == "" { + oldpath = "/" + } + if u.Scheme == "" { + if urlStr == "" || urlStr[0] != '/' { + olddir, _ := path.Split(oldpath) + urlStr = olddir + urlStr + } + + var query string + if i := strings.Index(urlStr, "?"); i != -1 { + urlStr, query = urlStr[:i], urlStr[i:] + } + + trailing := strings.HasSuffix(urlStr, "/") + urlStr = path.Clean(urlStr) + if trailing && !strings.HasSuffix(urlStr, "/") { + urlStr += "/" + } + urlStr += query + } + } + + w.Header().Set("Location", urlStr) + w.Header().Set("Cache-Control", "max-age=0,no-cache,no-store") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Expires", "Thu, 1 Jan 1970 00:00:00 GMT") + w.WriteHeader(code) +} + // Serve a response for a client connection to a relay. func (h *HttpRedirector) serveRelay(mount *autoradio.Mount, w http.ResponseWriter, r *http.Request) { // Find an active node. @@ -144,7 +180,7 @@ func (h *HttpRedirector) serveRelay(mount *autoradio.Mount, w http.ResponseWrite h.serveM3U(mount, w, r) } else { targetURL := streamUrl(relayAddr, mount.Name) - http.Redirect(w, r, targetURL, 302) + redirect(w, r, targetURL, 302) } }