diff --git a/package.json b/package.json index 658c72c..bb7d648 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.8.0-unstable4", + "version": "0.8.0-unstable5", "description": "", "main": "test-server.js", "bugs": { diff --git a/src/proxy/routeTo.go b/src/proxy/routeTo.go index 7ec122c..91ec5ec 100644 --- a/src/proxy/routeTo.go +++ b/src/proxy/routeTo.go @@ -4,11 +4,47 @@ import ( "net/http" "net/http/httputil" "net/url" + "strings" "crypto/tls" spa "github.com/roberthodgen/spa-server" "github.com/azukaar/cosmos-server/src/utils" ) + +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 +} + +func joinURLPath(a, b *url.URL) (path, rawpath string) { + if a.RawPath == "" && b.RawPath == "" { + return singleJoiningSlash(a.Path, b.Path), "" + } + // Same as singleJoiningSlash, but uses EscapedPath to determine + // whether a slash should be added + apath := a.EscapedPath() + bpath := b.EscapedPath() + + aslash := strings.HasSuffix(apath, "/") + bslash := strings.HasPrefix(bpath, "/") + + switch { + case aslash && bslash: + return a.Path + b.Path[1:], apath + bpath[1:] + case !aslash && !bslash: + return a.Path + "/" + b.Path, apath + "/" + bpath + } + return a.Path + b.Path, apath + bpath +} + + // NewProxy takes target host and creates a reverse proxy func NewProxy(targetHost string, AcceptInsecureHTTPSTarget bool) (*httputil.ReverseProxy, error) { url, err := url.Parse(targetHost) @@ -19,6 +55,16 @@ func NewProxy(targetHost string, AcceptInsecureHTTPSTarget bool) (*httputil.Reve proxy := httputil.NewSingleHostReverseProxy(url) proxy.Director = func(req *http.Request) { + urlQuery := url.RawQuery + req.URL.Scheme = url.Scheme + req.URL.Host = url.Host + req.URL.Path, req.URL.RawPath = joinURLPath(url, req.URL) + if urlQuery == "" || req.URL.RawQuery == "" { + req.URL.RawQuery = urlQuery + req.URL.RawQuery + } else { + req.URL.RawQuery = urlQuery + "&" + req.URL.RawQuery + } + req.Header.Set("X-Forwarded-Proto", url.Scheme) }