package middleware import ( "net/http" "net/url" "strings" "github.com/telanflow/mps" ) // SingleHostReverseProxy returns a mps.Middleware // URLs to the scheme, host, and base path provided in target. If the // target's path is "/base" and the incoming request was for "/dir", // the target request will be for /base/dir. // SingleHostReverseProxy does not rewrite the Host header. // To rewrite Host headers, use ReverseProxy directly with a custom // Director policy. func SingleHostReverseProxy(target *url.URL) mps.MiddlewareFunc { targetQuery := target.RawQuery return func(req *http.Request, ctx *mps.Context) (*http.Response, error) { // changed request Host req.Host = target.Host // changed request URL req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery } else { req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery } if _, ok := req.Header["User-Agent"]; !ok { // explicitly disable User-Agent so it's not set to default value req.Header.Set("User-Agent", "") } return ctx.Next(req) } } func singleJoiningSlash(a, b string) string { aslash := strings.HasSuffix(a, "/") bslash := strings.HasPrefix(b, "/") switch { case aslash && bslash: return a + b[1:] case !aslash && !bslash: return a + "/" + b } return a + b }