From 9eb7d9386d5720dd2f5a3710970fc542338f7692 Mon Sep 17 00:00:00 2001 From: tuhao Date: Sat, 16 Jan 2021 11:49:33 +0800 Subject: [PATCH] add ProxyHandlerRemote and NewProxyRemote --- core/host/proxy.go | 80 ++++++++++++++++++++++++++++++++++------- core/host/proxy_test.go | 4 +-- 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/core/host/proxy.go b/core/host/proxy.go index 241f0436..25fa9cbc 100644 --- a/core/host/proxy.go +++ b/core/host/proxy.go @@ -12,27 +12,20 @@ import ( ) // ProxyHandler returns a new ReverseProxy that rewrites -// URLs to the scheme, host, and base path provided in target. -// Case 1: req.Host == target.Host -// If the target's path is "/base" and the incoming request was for "/dir", +// 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. -// Case 2: req.Host != target.Host -// the target request will be forwarded to the target's url +// // Relative to httputil.NewSingleHostReverseProxy with some additions. func ProxyHandler(target *url.URL) *httputil.ReverseProxy { targetQuery := target.RawQuery director := func(req *http.Request) { req.URL.Scheme = target.Scheme - - if req.Host != target.Host { - req.URL.Path = target.Path - } else { - req.URL.Path = path.Join(target.Path, req.URL.Path) - } - req.URL.Host = target.Host req.Host = target.Host + req.URL.Path = path.Join(target.Path, req.URL.Path) + if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery } else { @@ -56,6 +49,51 @@ func ProxyHandler(target *url.URL) *httputil.ReverseProxy { return p } +// ProxyHandlerRemote returns a new ReverseProxy that rewrites +// URLs to the scheme, host, and path provided in target. +// Case 1: req.Host == target.Host +// behavior same as ProxyHandler +// Case 2: req.Host != target.Host +// the target request will be forwarded to the target's url +// insecureSkipVerify indicates enable ssl certificate verification or not +func ProxyHandlerRemote(target *url.URL, insecureSkipVerify bool) *httputil.ReverseProxy { + targetQuery := target.RawQuery + director := func(req *http.Request) { + req.URL.Scheme = target.Scheme + + if req.Host != target.Host { + req.URL.Path = target.Path + } else { + req.URL.Path = path.Join(target.Path, req.URL.Path) + } + + req.URL.Host = target.Host + req.Host = target.Host + + 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", "") + } + } + p := &httputil.ReverseProxy{Director: director} + + if netutil.IsLoopbackHost(target.Host) { + insecureSkipVerify = true + } + + transport := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: insecureSkipVerify}, // lint:ignore + } + p.Transport = transport + return p +} + // NewProxy returns a new host (server supervisor) which // proxies all requests to the target. // It uses the httputil.NewSingleHostReverseProxy. @@ -74,6 +112,24 @@ func NewProxy(hostAddr string, target *url.URL) *Supervisor { return proxy } +// NewProxyRemote returns a new host (server supervisor) which +// proxies all requests to the target. +// It uses the httputil.NewSingleHostReverseProxy. +// +// Usage: +// target, _ := url.Parse("https://anotherdomain.com/abc") +// proxy := NewProxyRemote("mydomain.com", target, false) +// proxy.ListenAndServe() // use of `proxy.Shutdown` to close the proxy server. +func NewProxyRemote(hostAddr string, target *url.URL, insecureSkipVerify bool) *Supervisor { + proxyHandler := ProxyHandlerRemote(target, insecureSkipVerify) + proxy := New(&http.Server{ + Addr: hostAddr, + Handler: proxyHandler, + }) + + return proxy +} + // NewRedirection returns a new host (server supervisor) which // redirects all requests to the target. // Usage: diff --git a/core/host/proxy_test.go b/core/host/proxy_test.go index f9e20b63..3ef18860 100644 --- a/core/host/proxy_test.go +++ b/core/host/proxy_test.go @@ -64,6 +64,6 @@ func TestProxy(t *testing.T) { e := httptest.NewInsecure(t, httptest.URL("http://"+listener.Addr().String())) e.GET("/").Expect().Status(iris.StatusOK).Body().Equal(expectedIndex) - e.GET("/about").Expect().Status(iris.StatusOK).Body().Equal(expectedIndex) - e.GET("/notfound").Expect().Status(iris.StatusOK).Body().Equal(expectedIndex) + e.GET("/about").Expect().Status(iris.StatusOK).Body().Equal(expectedAbout) + e.GET("/notfound").Expect().Status(iris.StatusNotFound).Body().Equal(unexpectedRoute) }