ソースを参照

auto update script executed

Toby Chui 1 年間 前
コミット
0c8f1f49f4

+ 2 - 0
api.go

@@ -55,6 +55,8 @@ func initAPIs() {
 	authRouter.HandleFunc("/api/proxy/setIncoming", HandleIncomingPortSet)
 	authRouter.HandleFunc("/api/proxy/useHttpsRedirect", HandleUpdateHttpsRedirect)
 	authRouter.HandleFunc("/api/proxy/requestIsProxied", HandleManagementProxyCheck)
+	//Reverse proxy root related APIs
+	authRouter.HandleFunc("/api/proxy/root/updateOptions", HandleRootOptionsUpdate)
 	//Reverse proxy auth related APIs
 	authRouter.HandleFunc("/api/proxy/auth/exceptions/list", ListProxyBasicAuthExceptionPaths)
 	authRouter.HandleFunc("/api/proxy/auth/exceptions/add", AddProxyBasicAuthExceptionPaths)

+ 13 - 21
mod/dynamicproxy/Server.go

@@ -3,10 +3,8 @@ package dynamicproxy
 import (
 	_ "embed"
 	"errors"
-	"fmt"
 	"log"
 	"net/http"
-	"net/url"
 	"os"
 	"strings"
 
@@ -123,22 +121,25 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		}
 	} else {
 		//No routing rules found.
-		if h.Parent.RootOptions.EnableRedirectForUnsetRules {
+		if h.Parent.RootRoutingOptions.EnableRedirectForUnsetRules {
 			//Route to custom domain
-			if h.Parent.RootOptions.UnsetRuleRedirectTarget == "" {
+			if h.Parent.RootRoutingOptions.UnsetRuleRedirectTarget == "" {
 				//Not set. Redirect to first level of domain redirectable
-				fld, err := h.getTopLevelRedirectableDomain(r.RequestURI)
+				fld, err := h.getTopLevelRedirectableDomain(domainOnly)
 				if err != nil {
 					//Redirect to proxy root
 					log.Println("[Router] Unable to resolve top level redirectable domain: " + err.Error())
 					h.proxyRequest(w, r, h.Parent.Root)
 				} else {
+					log.Println("[Router] Redirecting request from " + domainOnly + " to " + fld)
+					h.logRequest(r, false, 307, "root-redirect", domainOnly)
 					http.Redirect(w, r, fld, http.StatusTemporaryRedirect)
 				}
 				return
 			} else {
 				//Redirect to target
-				http.Redirect(w, r, h.Parent.RootOptions.UnsetRuleRedirectTarget, http.StatusTemporaryRedirect)
+				h.logRequest(r, false, 307, "root-redirect", domainOnly)
+				http.Redirect(w, r, h.Parent.RootRoutingOptions.UnsetRuleRedirectTarget, http.StatusTemporaryRedirect)
 				return
 			}
 		} else {
@@ -186,21 +187,12 @@ func (h *ProxyHandler) handleAccessRouting(w http.ResponseWriter, r *http.Reques
 
 // GetTopLevelRedirectableDomain returns the toppest level of domain
 // that is redirectable. E.g. a.b.c.example.co.uk will return example.co.uk
-func (h *ProxyHandler) getTopLevelRedirectableDomain(unsetSubdomainUri string) (string, error) {
-	//Extract hostname from URI
-	parsedURL, err := url.Parse(unsetSubdomainUri)
-	if err != nil {
-		return "", err
-	}
-	hostname := parsedURL.Hostname()
-
-	//Generate all levels of domains
-	//leveledDomains := []string{}
-	chunks := strings.Split(hostname, ".")
-	for i := len(chunks); i > 0; i-- {
-		thisChunk := chunks[i]
-		fmt.Println(thisChunk)
+func (h *ProxyHandler) getTopLevelRedirectableDomain(unsetSubdomainHost string) (string, error) {
+	parts := strings.Split(unsetSubdomainHost, ".")
+	if len(parts) > 1 {
+		newDomain := strings.Join(parts[1:], ".")
+		return "//" + newDomain, nil
 	}
 
-	return "", errors.New("wip")
+	return "", errors.New("unsupported top level domain given")
 }

+ 26 - 0
mod/dynamicproxy/dynamicproxy.go

@@ -8,12 +8,14 @@ import (
 	"log"
 	"net/http"
 	"net/url"
+	"os"
 	"strconv"
 	"strings"
 	"sync"
 	"time"
 
 	"imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
+	"imuslab.com/zoraxy/mod/utils"
 )
 
 /*
@@ -73,10 +75,34 @@ func (router *Router) StartProxyService() error {
 		return errors.New("Reverse proxy server already running")
 	}
 
+	//Check if root route is set
 	if router.Root == nil {
 		return errors.New("Reverse proxy router root not set")
 	}
 
+	//Load root options from file
+	rootConfigFilepath := "conf/root_config.json"
+	if !utils.FileExists(rootConfigFilepath) {
+		//Not found. Create a root option
+		js, _ := json.MarshalIndent(RootRoutingOptions{}, "", " ")
+		err := os.WriteFile(rootConfigFilepath, js, 0775)
+		if err != nil {
+			return errors.New("Unable to write root config to file: " + err.Error())
+		}
+	}
+	newRootOption := RootRoutingOptions{}
+	rootOptionsBytes, err := os.ReadFile(rootConfigFilepath)
+	if err != nil {
+		log.Println("[Error] Unable to read root config file at " + rootConfigFilepath + ": " + err.Error())
+		return err
+	}
+	err = json.Unmarshal(rootOptionsBytes, &newRootOption)
+	if err != nil {
+		log.Println("[Error] Unable to parse root config file: " + err.Error())
+		return err
+	}
+	router.RootRoutingOptions = &newRootOption
+
 	minVersion := tls.VersionTLS10
 	if router.Option.ForceTLSLatest {
 		minVersion = tls.VersionTLS12

+ 17 - 18
mod/dynamicproxy/typedef.go

@@ -33,23 +33,17 @@ type RouterOption struct {
 	StatisticCollector *statistic.Collector
 }
 
-type RootOption struct {
-	EnableRedirectForUnsetRules bool   //Force unset rules to redirect to custom domain
-	UnsetRuleRedirectTarget     string //Custom domain to redirect to for unset rules
-	DisableHTTPSOnProxyRoot     bool   //Bypass HTTPS for serving proxy root if UseTls is enabled in Router option
-}
-
 type Router struct {
-	Option            *RouterOption
-	ProxyEndpoints    *sync.Map
-	SubdomainEndpoint *sync.Map
-	Running           bool
-	Root              *ProxyEndpoint
-	RootOptions       *RootOption
-	mux               http.Handler
-	server            *http.Server
-	tlsListener       net.Listener
-	routingRules      []*RoutingRule
+	Option             *RouterOption
+	ProxyEndpoints     *sync.Map
+	SubdomainEndpoint  *sync.Map
+	Running            bool
+	Root               *ProxyEndpoint
+	RootRoutingOptions *RootRoutingOptions
+	mux                http.Handler
+	server             *http.Server
+	tlsListener        net.Listener
+	routingRules       []*RoutingRule
 
 	tlsRedirectStop chan bool      //Stop channel for tls redirection server
 	tldMap          map[string]int //Top level domain map, see tld.json
@@ -88,6 +82,7 @@ type ProxyEndpoint struct {
 	parent *Router
 }
 
+// Root options are those that are required for reverse proxy handler to work
 type RootOptions struct {
 	ProxyLocation       string //Proxy Root target, all unset traffic will be forward to here
 	RequireTLS          bool   //Proxy root target require TLS connection (not recommended)
@@ -98,10 +93,14 @@ type RootOptions struct {
 	RequireBasicAuth        bool //Require basic auth, CURRENTLY NOT USED
 	BasicAuthCredentials    []*BasicAuthCredentials
 	BasicAuthExceptionRules []*BasicAuthExceptionRule
+}
 
+// Additional options are here for letting router knows how to route exception cases for root
+type RootRoutingOptions struct {
 	//Root only configs
-	UnsetSubdomainRedirect bool   //If the router should redirect unset subdomains to another custom domain
-	UnsetRedirectTarget    string //Target for not found subdomain redirection. If not set, redirect to
+	EnableRedirectForUnsetRules bool   //Force unset rules to redirect to custom domain
+	UnsetRuleRedirectTarget     string //Custom domain to redirect to for unset rules
+	DisableHTTPSOnProxyRoot     bool   //Bypass HTTPS for serving proxy root if UseTls is enabled in Router option
 }
 
 type VdirOptions struct {

+ 6 - 0
reverseproxy.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"encoding/json"
+	"fmt"
 	"log"
 	"net/http"
 	"path/filepath"
@@ -814,3 +815,8 @@ func HandleIncomingPortSet(w http.ResponseWriter, r *http.Request) {
 
 	utils.SendOK(w)
 }
+
+func HandleRootOptionsUpdate(w http.ResponseWriter, r *http.Request) {
+	newRootOption := dynamicProxyRouter.RootRoutingOptions
+	fmt.Println(newRootOption)
+}

+ 26 - 1
web/components/rproot.html

@@ -14,6 +14,12 @@
                     <label>Root require TLS connection <br><small>Check this if your proxy root URL starts with https://</small></label>
                 </div>
             </div>
+            <br>
+            <button class="ui basic button" onclick="setProxyRoot()"><i class="teal home icon" ></i> Update Proxy Root</button>
+            <div class="ui divider"></div>
+            <div class="field">
+                <h4>Root Routing Options</h4>
+            </div>
             <div class="field">
                 <div class="ui checkbox">
                     <input type="checkbox" id="unsetRedirect">
@@ -48,7 +54,7 @@
                 </div>
             </div>
             <br>
-            <button class="ui basic button" onclick="setProxyRoot()"><i class="teal home icon" ></i> Update Proxy Root</button>
+            <button class="ui basic button" onclick="updateRootOptions()"><i class="blue save icon" ></i> Save Root Options</button>
         </div>
         <br>
         
@@ -158,4 +164,23 @@
         });
 
     }
+
+    function updateRootOptions(){
+        const jsonData = {
+            
+        };
+
+        $.ajax({
+            type: "POST",
+            url: "/api/proxy/root/updateOptions",
+            contentType: "application/json",
+            data: JSON.stringify(jsonData),
+            success: function(response) {
+                console.log("Success:", response);
+            },
+            error: function(error) {
+                console.log("Error:", error);
+            }
+        });
+    }
 </script>