Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update host.ProxyHandler to compatiable with different hosts in target url and request host #1703

Merged
merged 3 commits into from
Jan 21, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions core/host/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,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.
Expand All @@ -67,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:
Expand Down