mirror of
https://github.com/kataras/iris.git
synced 2026-01-26 05:15:56 +00:00
@@ -6,6 +6,7 @@ import (
|
|||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/iris/v12/core/netutil"
|
"github.com/kataras/iris/v12/core/netutil"
|
||||||
@@ -19,7 +20,11 @@ import (
|
|||||||
// Relative to httputil.NewSingleHostReverseProxy with some additions.
|
// Relative to httputil.NewSingleHostReverseProxy with some additions.
|
||||||
//
|
//
|
||||||
// Look `ProxyHandlerRemote` too.
|
// Look `ProxyHandlerRemote` too.
|
||||||
func ProxyHandler(target *url.URL) *httputil.ReverseProxy {
|
func ProxyHandler(target *url.URL, config *tls.Config) *httputil.ReverseProxy {
|
||||||
|
if config == nil {
|
||||||
|
config = &tls.Config{}
|
||||||
|
}
|
||||||
|
|
||||||
director := func(req *http.Request) {
|
director := func(req *http.Request) {
|
||||||
modifyProxiedRequest(req, target)
|
modifyProxiedRequest(req, target)
|
||||||
req.Host = target.Host
|
req.Host = target.Host
|
||||||
@@ -30,7 +35,7 @@ func ProxyHandler(target *url.URL) *httputil.ReverseProxy {
|
|||||||
|
|
||||||
if netutil.IsLoopbackHost(target.Host) {
|
if netutil.IsLoopbackHost(target.Host) {
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // lint:ignore
|
TLSClientConfig: config, // lint:ignore
|
||||||
}
|
}
|
||||||
p.Transport = transport
|
p.Transport = transport
|
||||||
}
|
}
|
||||||
@@ -38,15 +43,35 @@ func ProxyHandler(target *url.URL) *httputil.ReverseProxy {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// mergeQuery return a query string that combines targetQuery and reqQuery
|
||||||
|
// and remove the duplicated query parameters of them.
|
||||||
|
func mergeQuery(targetQuery, reqQuery string) string {
|
||||||
|
var paramSlice []string
|
||||||
|
if targetQuery != "" {
|
||||||
|
paramSlice = strings.Split(targetQuery, "&")
|
||||||
|
}
|
||||||
|
|
||||||
|
if reqQuery != "" {
|
||||||
|
paramSlice = append(paramSlice, strings.Split(reqQuery, "&")...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var mergedSlice []string
|
||||||
|
queryMap := make(map[string]bool)
|
||||||
|
for _, param := range paramSlice {
|
||||||
|
size := len(queryMap)
|
||||||
|
queryMap[param] = true
|
||||||
|
if size != len(queryMap) {
|
||||||
|
mergedSlice = append(mergedSlice, param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(mergedSlice, "&")
|
||||||
|
}
|
||||||
|
|
||||||
func modifyProxiedRequest(req *http.Request, target *url.URL) {
|
func modifyProxiedRequest(req *http.Request, target *url.URL) {
|
||||||
req.URL.Scheme = target.Scheme
|
req.URL.Scheme = target.Scheme
|
||||||
req.URL.Host = target.Host
|
req.URL.Host = target.Host
|
||||||
|
req.URL.RawQuery = mergeQuery(target.RawQuery, req.URL.RawQuery)
|
||||||
if target.RawQuery == "" || req.URL.RawQuery == "" {
|
|
||||||
req.URL.RawQuery = target.RawQuery + req.URL.RawQuery
|
|
||||||
} else {
|
|
||||||
req.URL.RawQuery = target.RawQuery + "&" + req.URL.RawQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := req.Header["User-Agent"]; !ok {
|
if _, ok := req.Header["User-Agent"]; !ok {
|
||||||
// explicitly disable User-Agent so it's not set to default value
|
// explicitly disable User-Agent so it's not set to default value
|
||||||
@@ -63,7 +88,11 @@ func modifyProxiedRequest(req *http.Request, target *url.URL) {
|
|||||||
// insecureSkipVerify indicates enable ssl certificate verification or not.
|
// insecureSkipVerify indicates enable ssl certificate verification or not.
|
||||||
//
|
//
|
||||||
// Look `ProxyHandler` too.
|
// Look `ProxyHandler` too.
|
||||||
func ProxyHandlerRemote(target *url.URL, insecureSkipVerify bool) *httputil.ReverseProxy {
|
func ProxyHandlerRemote(target *url.URL, config *tls.Config) *httputil.ReverseProxy {
|
||||||
|
if config == nil {
|
||||||
|
config = &tls.Config{}
|
||||||
|
}
|
||||||
|
|
||||||
director := func(req *http.Request) {
|
director := func(req *http.Request) {
|
||||||
modifyProxiedRequest(req, target)
|
modifyProxiedRequest(req, target)
|
||||||
|
|
||||||
@@ -78,11 +107,11 @@ func ProxyHandlerRemote(target *url.URL, insecureSkipVerify bool) *httputil.Reve
|
|||||||
p := &httputil.ReverseProxy{Director: director}
|
p := &httputil.ReverseProxy{Director: director}
|
||||||
|
|
||||||
if netutil.IsLoopbackHost(target.Host) {
|
if netutil.IsLoopbackHost(target.Host) {
|
||||||
insecureSkipVerify = true
|
config.InsecureSkipVerify = true
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecureSkipVerify}, // lint:ignore
|
TLSClientConfig: config, // lint:ignore
|
||||||
}
|
}
|
||||||
p.Transport = transport
|
p.Transport = transport
|
||||||
return p
|
return p
|
||||||
@@ -96,8 +125,8 @@ func ProxyHandlerRemote(target *url.URL, insecureSkipVerify bool) *httputil.Reve
|
|||||||
// target, _ := url.Parse("https://mydomain.com")
|
// target, _ := url.Parse("https://mydomain.com")
|
||||||
// proxy := NewProxy("mydomain.com:80", target)
|
// proxy := NewProxy("mydomain.com:80", target)
|
||||||
// proxy.ListenAndServe() // use of `proxy.Shutdown` to close the proxy server.
|
// proxy.ListenAndServe() // use of `proxy.Shutdown` to close the proxy server.
|
||||||
func NewProxy(hostAddr string, target *url.URL) *Supervisor {
|
func NewProxy(hostAddr string, target *url.URL, config *tls.Config) *Supervisor {
|
||||||
proxyHandler := ProxyHandler(target)
|
proxyHandler := ProxyHandler(target, config)
|
||||||
proxy := New(&http.Server{
|
proxy := New(&http.Server{
|
||||||
Addr: hostAddr,
|
Addr: hostAddr,
|
||||||
Handler: proxyHandler,
|
Handler: proxyHandler,
|
||||||
@@ -114,8 +143,8 @@ func NewProxy(hostAddr string, target *url.URL) *Supervisor {
|
|||||||
// target, _ := url.Parse("https://anotherdomain.com/abc")
|
// target, _ := url.Parse("https://anotherdomain.com/abc")
|
||||||
// proxy := NewProxyRemote("mydomain.com", target, false)
|
// proxy := NewProxyRemote("mydomain.com", target, false)
|
||||||
// proxy.ListenAndServe() // use of `proxy.Shutdown` to close the proxy server.
|
// proxy.ListenAndServe() // use of `proxy.Shutdown` to close the proxy server.
|
||||||
func NewProxyRemote(hostAddr string, target *url.URL, insecureSkipVerify bool) *Supervisor {
|
func NewProxyRemote(hostAddr string, target *url.URL, config *tls.Config) *Supervisor {
|
||||||
proxyHandler := ProxyHandlerRemote(target, insecureSkipVerify)
|
proxyHandler := ProxyHandlerRemote(target, config)
|
||||||
proxy := New(&http.Server{
|
proxy := New(&http.Server{
|
||||||
Addr: hostAddr,
|
Addr: hostAddr,
|
||||||
Handler: proxyHandler,
|
Handler: proxyHandler,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package host_test
|
package host_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -24,7 +25,11 @@ func TestProxy(t *testing.T) {
|
|||||||
t.Fatalf("%v while parsing url", err)
|
t.Fatalf("%v while parsing url", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy := host.NewProxy("", u)
|
config := &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
MaxVersion: tls.VersionTLS12,
|
||||||
|
}
|
||||||
|
proxy := host.NewProxy("", u, config)
|
||||||
|
|
||||||
addr := &net.TCPAddr{
|
addr := &net.TCPAddr{
|
||||||
IP: net.IPv4(127, 0, 0, 1),
|
IP: net.IPv4(127, 0, 0, 1),
|
||||||
|
|||||||
Reference in New Issue
Block a user