123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- package dynamicproxy
- import (
- "net/http"
- "net/url"
- "os"
- "path/filepath"
- "strings"
- )
- func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-
-
-
- matchedRoutingRule := h.Parent.GetMatchingRoutingRule(r)
- if matchedRoutingRule != nil {
-
- matchedRoutingRule.Route(w, r)
- return
- }
-
-
- if h.Parent.Option.RedirectRuleTable.IsRedirectable(r) {
- statusCode := h.Parent.Option.RedirectRuleTable.HandleRedirect(w, r)
- h.Parent.logRequest(r, statusCode != 500, statusCode, "redirect", "")
- return
- }
-
-
- domainOnly := r.Host
- if strings.Contains(r.Host, ":") {
- hostPath := strings.Split(r.Host, ":")
- domainOnly = hostPath[0]
- }
- sep := h.Parent.getProxyEndpointFromHostname(domainOnly)
- if sep != nil && !sep.Disabled {
-
-
- ruleID := sep.AccessFilterUUID
- if sep.AccessFilterUUID == "" {
-
- ruleID = "default"
- }
- if h.handleAccessRouting(ruleID, w, r) {
-
- return
- }
-
- if sep.RequireRateLimit {
- err := h.handleRateLimitRouting(w, r, sep)
- if err != nil {
- h.Parent.Option.Logger.LogHTTPRequest(r, "host", 429)
- return
- }
- }
-
- if sep.RequireBasicAuth {
- err := h.handleBasicAuthRouting(w, r, sep)
- if err != nil {
- h.Parent.Option.Logger.LogHTTPRequest(r, "host", 401)
- return
- }
- }
-
- proxyingPath := strings.TrimSpace(r.RequestURI)
- targetProxyEndpoint := sep.GetVirtualDirectoryHandlerFromRequestURI(proxyingPath)
- if targetProxyEndpoint != nil && !targetProxyEndpoint.Disabled {
-
- h.vdirRequest(w, r, targetProxyEndpoint)
- return
- } else if !strings.HasSuffix(proxyingPath, "/") && sep.ProxyType != ProxyType_Root {
- potentialProxtEndpoint := sep.GetVirtualDirectoryHandlerFromRequestURI(proxyingPath + "/")
- if potentialProxtEndpoint != nil && !potentialProxtEndpoint.Disabled {
-
- http.Redirect(w, r, r.RequestURI+"/", http.StatusTemporaryRedirect)
- h.Parent.Option.Logger.LogHTTPRequest(r, "redirect", 307)
- return
- }
- }
-
- h.hostRequest(w, r, sep)
- return
- }
-
-
- blocked := h.handleAccessRouting("default", w, r)
- if blocked {
- return
- }
-
- proxyingPath := strings.TrimSpace(r.RequestURI)
- if !strings.HasSuffix(proxyingPath, "/") {
- potentialProxtEndpoint := h.Parent.getTargetProxyEndpointFromRequestURI(proxyingPath + "/")
- if potentialProxtEndpoint != nil {
-
- http.Redirect(w, r, r.RequestURI+"/", http.StatusTemporaryRedirect)
- } else {
-
- h.handleRootRouting(w, r)
- }
- } else {
-
- h.handleRootRouting(w, r)
- }
- }
- func (h *ProxyHandler) handleRootRouting(w http.ResponseWriter, r *http.Request) {
- domainOnly := r.Host
- if strings.Contains(r.Host, ":") {
- hostPath := strings.Split(r.Host, ":")
- domainOnly = hostPath[0]
- }
-
- proot := h.Parent.Root
- switch proot.DefaultSiteOption {
- case DefaultSite_InternalStaticWebServer:
- fallthrough
- case DefaultSite_ReverseProxy:
-
-
- proxyingPath := strings.TrimSpace(r.RequestURI)
- targetProxyEndpoint := proot.GetVirtualDirectoryHandlerFromRequestURI(proxyingPath)
- if targetProxyEndpoint != nil && !targetProxyEndpoint.Disabled {
-
- h.vdirRequest(w, r, targetProxyEndpoint)
- return
- } else if !strings.HasSuffix(proxyingPath, "/") && proot.ProxyType != ProxyType_Root {
- potentialProxtEndpoint := proot.GetVirtualDirectoryHandlerFromRequestURI(proxyingPath + "/")
- if potentialProxtEndpoint != nil && !targetProxyEndpoint.Disabled {
-
- http.Redirect(w, r, r.RequestURI+"/", http.StatusTemporaryRedirect)
- return
- }
- }
-
- h.hostRequest(w, r, h.Parent.Root)
- case DefaultSite_Redirect:
- redirectTarget := strings.TrimSpace(proot.DefaultSiteValue)
- if redirectTarget == "" {
- redirectTarget = "about:blank"
- }
-
- parsedURL, err := url.Parse(proot.DefaultSiteValue)
- if err != nil {
-
- h.hostRequest(w, r, h.Parent.Root)
- return
- }
- hostname := parsedURL.Hostname()
- if hostname == domainOnly {
- h.Parent.logRequest(r, false, 500, "root-redirect", domainOnly)
- http.Error(w, "Loopback redirects due to invalid settings", 500)
- return
- }
- h.Parent.logRequest(r, false, 307, "root-redirect", domainOnly)
- http.Redirect(w, r, redirectTarget, http.StatusTemporaryRedirect)
- case DefaultSite_NotFoundPage:
-
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- w.WriteHeader(http.StatusNotFound)
- template, err := os.ReadFile(filepath.Join(h.Parent.Option.WebDirectory, "templates/notfound.html"))
- if err != nil {
- w.Write(page_hosterror)
- } else {
- w.Write(template)
- }
- }
- }
|