From 36b17ce4cf93edeab7620a6e45e743766370b202 Mon Sep 17 00:00:00 2001 From: Toby Chui Date: Thu, 6 Jul 2023 11:01:33 +0800 Subject: [PATCH] acme and redirection patch + Added experimental fix for redirection tailing problem + Added acme widget for first time users to setup https --- src/mod/acme/acmewizard/acmewizard.go | 4 +++ src/mod/dynamicproxy/dpcore/dpcore.go | 10 ++----- src/mod/dynamicproxy/dpcore/utils.go | 29 +++++++++++++++++++-- src/mod/dynamicproxy/proxyRequestHandler.go | 1 + src/mod/dynamicproxy/redirection/handler.go | 5 +--- src/web/components/redirection.html | 2 +- src/web/snippet/acme.html | 3 ++- src/web/tools/https.html | 8 +++++- 8 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/mod/acme/acmewizard/acmewizard.go b/src/mod/acme/acmewizard/acmewizard.go index f833019..fcdbb74 100644 --- a/src/mod/acme/acmewizard/acmewizard.go +++ b/src/mod/acme/acmewizard/acmewizard.go @@ -98,6 +98,10 @@ func isLocalhostListening() (isListening bool, err error) { conn.Close() } + if isListening { + return true, nil + } + return isListening, err } diff --git a/src/mod/dynamicproxy/dpcore/dpcore.go b/src/mod/dynamicproxy/dpcore/dpcore.go index 1dfdb5b..b84a721 100644 --- a/src/mod/dynamicproxy/dpcore/dpcore.go +++ b/src/mod/dynamicproxy/dpcore/dpcore.go @@ -357,11 +357,6 @@ func (p *ReverseProxy) ProxyHTTP(rw http.ResponseWriter, req *http.Request, rrr //Custom header rewriter functions if res.Header.Get("Location") != "" { - /* - fmt.Println(">>> REQ", req) - fmt.Println(">>> OUTR", outreq) - fmt.Println(">>> RESP", res) - */ locationRewrite := res.Header.Get("Location") originLocation := res.Header.Get("Location") res.Header.Set("zr-origin-location", originLocation) @@ -369,12 +364,10 @@ func (p *ReverseProxy) ProxyHTTP(rw http.ResponseWriter, req *http.Request, rrr if strings.HasPrefix(originLocation, "http://") || strings.HasPrefix(originLocation, "https://") { //Full path //Replace the forwarded target with expected Host - lr, err := replaceLocationHost(locationRewrite, rrr.OriginalHost, req.TLS != nil) + lr, err := replaceLocationHost(locationRewrite, rrr, req.TLS != nil) if err == nil { locationRewrite = lr } - //locationRewrite = strings.ReplaceAll(locationRewrite, rrr.ProxyDomain, rrr.OriginalHost) - //locationRewrite = strings.ReplaceAll(locationRewrite, domainWithoutPort, rrr.OriginalHost) } else if strings.HasPrefix(originLocation, "/") && rrr.PathPrefix != "" { //Back to the root of this proxy object //fmt.Println(rrr.ProxyDomain, rrr.OriginalHost) @@ -387,6 +380,7 @@ func (p *ReverseProxy) ProxyHTTP(rw http.ResponseWriter, req *http.Request, rrr //Custom redirection to this rproxy relative path res.Header.Set("Location", locationRewrite) } + // Copy header from response to client. copyHeader(rw.Header(), res.Header) diff --git a/src/mod/dynamicproxy/dpcore/utils.go b/src/mod/dynamicproxy/dpcore/utils.go index 75f68a6..6f1b823 100644 --- a/src/mod/dynamicproxy/dpcore/utils.go +++ b/src/mod/dynamicproxy/dpcore/utils.go @@ -2,20 +2,45 @@ package dpcore import ( "net/url" + "strings" ) -func replaceLocationHost(urlString string, newHost string, useTLS bool) (string, error) { +// replaceLocationHost rewrite the backend server's location header to a new URL based on the given proxy rules +// If you have issues with tailing slash, you can try to fix them here (and remember to PR :D ) +func replaceLocationHost(urlString string, rrr *ResponseRewriteRuleSet, useTLS bool) (string, error) { u, err := url.Parse(urlString) if err != nil { return "", err } + //Update the schemetic if the proxying target is http + //but exposed as https to the internet via Zoraxy if useTLS { u.Scheme = "https" } else { u.Scheme = "http" } - u.Host = newHost + u.Host = rrr.OriginalHost + + if strings.Contains(rrr.ProxyDomain, "/") { + //The proxy domain itself seems contain subpath. + //Trim it off from Location header to prevent URL segment duplicate + //E.g. Proxy config: blog.example.com -> example.com/blog + //Location Header: /blog/post?id=1 + //Expected Location Header send to client: + // blog.example.com/post?id=1 instead of blog.example.com/blog/post?id=1 + + ProxyDomainURL := "http://" + rrr.ProxyDomain + if rrr.UseTLS { + ProxyDomainURL = "https://" + rrr.ProxyDomain + } + ru, err := url.Parse(ProxyDomainURL) + if err == nil { + //Trim off the subpath + u.Path = strings.TrimPrefix(u.Path, ru.Path) + } + } + return u.String(), nil } diff --git a/src/mod/dynamicproxy/proxyRequestHandler.go b/src/mod/dynamicproxy/proxyRequestHandler.go index 260eb68..6a10ff7 100644 --- a/src/mod/dynamicproxy/proxyRequestHandler.go +++ b/src/mod/dynamicproxy/proxyRequestHandler.go @@ -95,6 +95,7 @@ func (h *ProxyHandler) subdomainRequest(w http.ResponseWriter, r *http.Request, UseTLS: target.RequireTLS, PathPrefix: "", }) + var dnsError *net.DNSError if err != nil { if errors.As(err, &dnsError) { diff --git a/src/mod/dynamicproxy/redirection/handler.go b/src/mod/dynamicproxy/redirection/handler.go index 952cde7..0b15378 100644 --- a/src/mod/dynamicproxy/redirection/handler.go +++ b/src/mod/dynamicproxy/redirection/handler.go @@ -28,10 +28,7 @@ func (t *RuleTable) HandleRedirect(w http.ResponseWriter, r *http.Request) int { rr := t.MatchRedirectRule(requestPath) if rr != nil { redirectTarget := rr.TargetURL - //Always pad a / at the back of the target URL - if redirectTarget[len(redirectTarget)-1:] != "/" { - redirectTarget += "/" - } + if rr.ForwardChildpath { //Remove the first / in the path redirectTarget += strings.TrimPrefix(r.URL.Path, "/") diff --git a/src/web/components/redirection.html b/src/web/components/redirection.html index e7d9786..66657f5 100644 --- a/src/web/components/redirection.html +++ b/src/web/components/redirection.html @@ -39,7 +39,7 @@
- The target URL request being redirected to, e.g. dest.example.com/mysite + The target URL request being redirected to, e.g. dest.example.com/mysite/ or dest.example.com/script.php, sometime you might need to add tailing slash (/) to your URL depending on your use cases
diff --git a/src/web/snippet/acme.html b/src/web/snippet/acme.html index 49f3c1c..4c05009 100644 --- a/src/web/snippet/acme.html +++ b/src/web/snippet/acme.html @@ -115,7 +115,8 @@
- +
+ First time setting up HTTPS?
Try out our wizard




diff --git a/src/web/tools/https.html b/src/web/tools/https.html index c05faf5..79d3efb 100644 --- a/src/web/tools/https.html +++ b/src/web/tools/https.html @@ -21,6 +21,11 @@
This Wizard require both client and server connected to the internet. +
+ As different deployment methods might involve different network environment, + this wizard is only provided for assistant and the correctness of the setup is not guaranteed. + If you need to verify your TLS/SSL certificate installation is valid, please seek help + from IT professionals.

@@ -114,7 +119,8 @@