2017-05-05 22:17:35 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type interceptingResponseWriter struct {
|
|
|
|
http.ResponseWriter
|
|
|
|
Prefix string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *interceptingResponseWriter) WriteHeader(status int) {
|
|
|
|
if status >= 300 && status < 400 {
|
|
|
|
location := i.ResponseWriter.Header().Get("Location")
|
|
|
|
if u, err := url.Parse(location); err == nil && !u.IsAbs() {
|
2017-05-09 19:05:10 +00:00
|
|
|
hasPrefix := strings.HasPrefix(u.Path, i.Prefix)
|
|
|
|
if !hasPrefix || (hasPrefix && !strings.HasPrefix(u.Path[len(i.Prefix):], i.Prefix)) {
|
2017-05-05 22:17:35 +00:00
|
|
|
i.ResponseWriter.Header().Set("Location", path.Join(i.Prefix, location)+"/")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i.ResponseWriter.WriteHeader(status)
|
|
|
|
}
|
|
|
|
|
|
|
|
// PrefixingRedirector alters the Location header of downstream http.Handlers
|
|
|
|
// to include a specified prefix
|
|
|
|
func PrefixedRedirect(prefix string, next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
iw := &interceptingResponseWriter{w, prefix}
|
|
|
|
next.ServeHTTP(iw, r)
|
|
|
|
})
|
|
|
|
}
|