mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-12-17 21:07:03 +01:00
Added loopback proxy support
- Added support for shortcut loopback setup in local setups
This commit is contained in:
@@ -92,7 +92,6 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Plugin routing
|
//Plugin routing
|
||||||
|
|
||||||
if h.Parent.Option.PluginManager != nil && h.Parent.Option.PluginManager.HandleRoute(w, r, sep.Tags) {
|
if h.Parent.Option.PluginManager != nil && h.Parent.Option.PluginManager.HandleRoute(w, r, sep.Tags) {
|
||||||
//Request handled by subroute
|
//Request handled by subroute
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -438,7 +438,15 @@ func (p *ReverseProxy) ProxyHTTPS(rw http.ResponseWriter, req *http.Request) (in
|
|||||||
if !strings.Contains(host, ":") {
|
if !strings.Contains(host, ":") {
|
||||||
host += ":443"
|
host += ":443"
|
||||||
}
|
}
|
||||||
serverName := req.URL.Hostname()
|
serverName := ""
|
||||||
|
//if p.Transport != nil {
|
||||||
|
// if tr, ok := p.Transport.(*http.Transport); ok && tr.TLSClientConfig != nil && tr.TLSClientConfig.ServerName != "" {
|
||||||
|
// serverName = tr.TLSClientConfig.ServerName
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
if serverName == "" {
|
||||||
|
serverName = req.URL.Hostname()
|
||||||
|
}
|
||||||
|
|
||||||
// Connect with SNI offload
|
// Connect with SNI offload
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
|
"imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
|
||||||
|
"imuslab.com/zoraxy/mod/dynamicproxy/loadbalance"
|
||||||
"imuslab.com/zoraxy/mod/dynamicproxy/rewrite"
|
"imuslab.com/zoraxy/mod/dynamicproxy/rewrite"
|
||||||
"imuslab.com/zoraxy/mod/netutils"
|
"imuslab.com/zoraxy/mod/netutils"
|
||||||
"imuslab.com/zoraxy/mod/statistic"
|
"imuslab.com/zoraxy/mod/statistic"
|
||||||
@@ -95,27 +96,41 @@ func (router *Router) GetProxyEndpointFromHostname(hostname string) *ProxyEndpoi
|
|||||||
return targetSubdomainEndpoint
|
return targetSubdomainEndpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clearn URL Path (without the http:// part) replaces // in a URL to /
|
|
||||||
func (router *Router) clearnURL(targetUrlOPath string) string {
|
|
||||||
return strings.ReplaceAll(targetUrlOPath, "//", "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewrite URL rewrite the prefix part of a virtual directory URL with /
|
// Rewrite URL rewrite the prefix part of a virtual directory URL with /
|
||||||
func (router *Router) rewriteURL(rooturl string, requestURL string) string {
|
func (router *Router) rewriteURL(rooturl string, requestURL string) string {
|
||||||
rewrittenURL := requestURL
|
rewrittenURL := requestURL
|
||||||
rewrittenURL = strings.TrimPrefix(rewrittenURL, strings.TrimSuffix(rooturl, "/"))
|
rewrittenURL = strings.TrimPrefix(rewrittenURL, strings.TrimSuffix(rooturl, "/"))
|
||||||
|
|
||||||
if strings.Contains(rewrittenURL, "//") {
|
if strings.Contains(rewrittenURL, "//") {
|
||||||
rewrittenURL = router.clearnURL(rewrittenURL)
|
rewrittenURL = strings.ReplaceAll(rewrittenURL, "//", "/")
|
||||||
}
|
}
|
||||||
return rewrittenURL
|
return rewrittenURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// upstreamHostSwap check if this loopback to one of the proxy rule in the system. If yes, do a shortcut target swap
|
||||||
|
// this prevents unnecessary external DNS lookup and connection, return true if swapped and request is already handled
|
||||||
|
// by the loopback handler. Only continue if return is false
|
||||||
|
func (h *ProxyHandler) upstreamHostSwap(w http.ResponseWriter, r *http.Request, selectedUpstream *loadbalance.Upstream) bool {
|
||||||
|
upstreamHostanme := selectedUpstream.OriginIpOrDomain
|
||||||
|
if strings.Contains(upstreamHostanme, ":") {
|
||||||
|
upstreamHostanme = strings.Split(upstreamHostanme, ":")[0]
|
||||||
|
}
|
||||||
|
loopbackProxyEndpoint := h.Parent.GetProxyEndpointFromHostname(upstreamHostanme)
|
||||||
|
if loopbackProxyEndpoint != nil {
|
||||||
|
//This is a loopback request. Swap the target to the loopback target
|
||||||
|
//h.Parent.Option.Logger.PrintAndLog("proxy", "Detected a loopback request to self. Swap the target to "+loopbackProxyEndpoint.RootOrMatchingDomain, nil)
|
||||||
|
h.hostRequest(w, r, loopbackProxyEndpoint)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Handle host request
|
// Handle host request
|
||||||
func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, target *ProxyEndpoint) {
|
func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, target *ProxyEndpoint) {
|
||||||
r.Header.Set("X-Forwarded-Host", r.Host)
|
r.Header.Set("X-Forwarded-Host", r.Host)
|
||||||
r.Header.Set("X-Forwarded-Server", "zoraxy-"+h.Parent.Option.HostUUID)
|
r.Header.Set("X-Forwarded-Server", "zoraxy-"+h.Parent.Option.HostUUID)
|
||||||
reqHostname := r.Host
|
reqHostname := r.Host
|
||||||
|
|
||||||
/* Load balancing */
|
/* Load balancing */
|
||||||
selectedUpstream, err := h.Parent.loadBalancer.GetRequestUpstreamTarget(w, r, target.ActiveOrigins, target.UseStickySession)
|
selectedUpstream, err := h.Parent.loadBalancer.GetRequestUpstreamTarget(w, r, target.ActiveOrigins, target.UseStickySession)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -125,6 +140,12 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Upstream Host Swap (use to detect loopback to self) */
|
||||||
|
if h.upstreamHostSwap(w, r, selectedUpstream) {
|
||||||
|
//Request handled by the loopback handler
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/* WebSocket automatic proxy */
|
/* WebSocket automatic proxy */
|
||||||
requestURL := r.URL.String()
|
requestURL := r.URL.String()
|
||||||
if r.Header["Upgrade"] != nil && strings.ToLower(r.Header["Upgrade"][0]) == "websocket" {
|
if r.Header["Upgrade"] != nil && strings.ToLower(r.Header["Upgrade"][0]) == "websocket" {
|
||||||
|
|||||||
@@ -211,7 +211,6 @@ func getWebsiteStatus(url string) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
//resp, err := client.Get(url)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//Try replace the http with https and vise versa
|
//Try replace the http with https and vise versa
|
||||||
rewriteURL := ""
|
rewriteURL := ""
|
||||||
|
|||||||
Reference in New Issue
Block a user