diff --git a/src/mod/dynamicproxy/Server.go b/src/mod/dynamicproxy/Server.go
index a9b1aa7..17ec73b 100644
--- a/src/mod/dynamicproxy/Server.go
+++ b/src/mod/dynamicproxy/Server.go
@@ -48,7 +48,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//Check if this is a redirection url
if h.Parent.Option.RedirectRuleTable.IsRedirectable(r) {
statusCode := h.Parent.Option.RedirectRuleTable.HandleRedirect(w, r)
- h.Parent.logRequest(r, statusCode != 500, statusCode, "redirect", r.Host, "")
+ h.Parent.logRequest(r, statusCode != 500, statusCode, "redirect", r.Host, "", nil)
return
}
@@ -70,7 +70,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//Use default rule
ruleID = "default"
}
- if h.handleAccessRouting(ruleID, w, r) {
+ if h.handleAccessRouting(ruleID, w, r, sep) {
//Request handled by subroute
return
}
@@ -79,7 +79,9 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if sep.RequireRateLimit {
err := h.handleRateLimitRouting(w, r, sep)
if err != nil {
- h.Parent.Option.Logger.LogHTTPRequest(r, "host", 307, r.Host, "")
+ if !sep.DisableLogging {
+ h.Parent.Option.Logger.LogHTTPRequest(r, "host", 307, r.Host, "")
+ }
return
}
}
@@ -109,7 +111,9 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if potentialProxtEndpoint != nil && !potentialProxtEndpoint.Disabled {
//Missing tailing slash. Redirect to target proxy endpoint
http.Redirect(w, r, r.RequestURI+"/", http.StatusTemporaryRedirect)
- h.Parent.Option.Logger.LogHTTPRequest(r, "redirect", 307, r.Host, "")
+ if !sep.DisableLogging {
+ h.Parent.Option.Logger.LogHTTPRequest(r, "redirect", 307, r.Host, "")
+ }
return
}
}
@@ -124,7 +128,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
*/
//Root access control based on default rule
- blocked := h.handleAccessRouting("default", w, r)
+ blocked := h.handleAccessRouting("default", w, r, h.Parent.Root)
if blocked {
return
}
@@ -210,19 +214,19 @@ func (h *ProxyHandler) handleRootRouting(w http.ResponseWriter, r *http.Request)
}
hostname := parsedURL.Hostname()
if hostname == domainOnly {
- h.Parent.logRequest(r, false, 500, "root-redirect", domainOnly, "")
+ h.Parent.logRequest(r, false, 500, "root-redirect", domainOnly, "", h.Parent.Root)
http.Error(w, "Loopback redirects due to invalid settings", 500)
return
}
- h.Parent.logRequest(r, false, 307, "root-redirect", domainOnly, "")
+ h.Parent.logRequest(r, false, 307, "root-redirect", domainOnly, "", h.Parent.Root)
http.Redirect(w, r, redirectTarget, http.StatusTemporaryRedirect)
case DefaultSite_NotFoundPage:
//Serve the not found page, use template if exists
h.serve404PageWithTemplate(w, r)
case DefaultSite_NoResponse:
//No response. Just close the connection
- h.Parent.logRequest(r, false, 444, "root-no_resp", domainOnly, "")
+ h.Parent.logRequest(r, false, 444, "root-no_resp", domainOnly, "", h.Parent.Root)
hijacker, ok := w.(http.Hijacker)
if !ok {
w.WriteHeader(http.StatusNoContent)
@@ -236,11 +240,11 @@ func (h *ProxyHandler) handleRootRouting(w http.ResponseWriter, r *http.Request)
conn.Close()
case DefaultSite_TeaPot:
//I'm a teapot
- h.Parent.logRequest(r, false, 418, "root-teapot", domainOnly, "")
+ h.Parent.logRequest(r, false, 418, "root-teapot", domainOnly, "", h.Parent.Root)
http.Error(w, "I'm a teapot", http.StatusTeapot)
default:
//Unknown routing option. Send empty response
- h.Parent.logRequest(r, false, 544, "root-unknown", domainOnly, "")
+ h.Parent.logRequest(r, false, 544, "root-unknown", domainOnly, "", h.Parent.Root)
http.Error(w, "544 - No Route Defined", 544)
}
}
diff --git a/src/mod/dynamicproxy/access.go b/src/mod/dynamicproxy/access.go
index dca919c..1044fc3 100644
--- a/src/mod/dynamicproxy/access.go
+++ b/src/mod/dynamicproxy/access.go
@@ -13,7 +13,7 @@ import (
// Handle access check (blacklist / whitelist), return true if request is handled (aka blocked)
// if the return value is false, you can continue process the response writer
-func (h *ProxyHandler) handleAccessRouting(ruleID string, w http.ResponseWriter, r *http.Request) bool {
+func (h *ProxyHandler) handleAccessRouting(ruleID string, w http.ResponseWriter, r *http.Request, sep *ProxyEndpoint) bool {
accessRule, err := h.Parent.Option.AccessController.GetAccessRuleByID(ruleID)
if err != nil {
//Unable to load access rule. Target rule not found?
@@ -25,7 +25,7 @@ func (h *ProxyHandler) handleAccessRouting(ruleID string, w http.ResponseWriter,
isBlocked, blockedReason := accessRequestBlocked(accessRule, h.Parent.Option.WebDirectory, w, r)
if isBlocked {
- h.Parent.logRequest(r, false, 403, blockedReason, r.Host, "")
+ h.Parent.logRequest(r, false, 403, blockedReason, r.Host, "", sep)
}
return isBlocked
}
diff --git a/src/mod/dynamicproxy/dynamicproxy.go b/src/mod/dynamicproxy/dynamicproxy.go
index c4421c1..f90f1d2 100644
--- a/src/mod/dynamicproxy/dynamicproxy.go
+++ b/src/mod/dynamicproxy/dynamicproxy.go
@@ -156,7 +156,7 @@ func (router *Router) StartProxyService() error {
if err != nil {
http.ServeFile(w, r, "./web/hosterror.html")
router.Option.Logger.PrintAndLog("dprouter", "failed to get upstream for hostname", err)
- router.logRequest(r, false, 404, "vdir-http", r.Host, "")
+ router.logRequest(r, false, 404, "vdir-http", r.Host, "", sep)
}
endpointProxyRewriteRules := GetDefaultHeaderRewriteRules()
diff --git a/src/mod/dynamicproxy/proxyRequestHandler.go b/src/mod/dynamicproxy/proxyRequestHandler.go
index 366dcc4..dba00bd 100644
--- a/src/mod/dynamicproxy/proxyRequestHandler.go
+++ b/src/mod/dynamicproxy/proxyRequestHandler.go
@@ -141,7 +141,7 @@ func (h *ProxyHandler) upstreamHostSwap(w http.ResponseWriter, r *http.Request,
} else {
//Endpoint disabled, return 503
http.ServeFile(w, r, "./web/rperror.html")
- h.Parent.logRequest(r, false, 521, "host-http", r.Host, upstreamHostname)
+ h.Parent.logRequest(r, false, 521, "host-http", r.Host, upstreamHostname, currentTarget)
}
return true
}
@@ -159,7 +159,7 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
if err != nil {
http.ServeFile(w, r, "./web/rperror.html")
h.Parent.Option.Logger.PrintAndLog("proxy", "Failed to assign an upstream for this request", err)
- h.Parent.logRequest(r, false, 521, "subdomain-http", r.URL.Hostname(), r.Host)
+ h.Parent.logRequest(r, false, 521, "subdomain-http", r.URL.Hostname(), r.Host, target)
return
}
@@ -187,7 +187,7 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
if selectedUpstream.RequireTLS {
u, _ = url.Parse("wss://" + wsRedirectionEndpoint + requestURL)
}
- h.Parent.logRequest(r, true, 101, "host-websocket", reqHostname, selectedUpstream.OriginIpOrDomain)
+ h.Parent.logRequest(r, true, 101, "host-websocket", reqHostname, selectedUpstream.OriginIpOrDomain, target)
if target.HeaderRewriteRules == nil {
target.HeaderRewriteRules = GetDefaultHeaderRewriteRules()
@@ -249,18 +249,18 @@ func (h *ProxyHandler) hostRequest(w http.ResponseWriter, r *http.Request, targe
if err != nil {
if errors.As(err, &dnsError) {
http.ServeFile(w, r, "./web/hosterror.html")
- h.Parent.logRequest(r, false, 404, "host-http", reqHostname, upstreamHostname)
+ h.Parent.logRequest(r, false, 404, "host-http", reqHostname, upstreamHostname, target)
} else if errors.Is(err, context.Canceled) {
//Request canceled by client, usually due to manual refresh before page load
http.Error(w, "Request canceled", http.StatusRequestTimeout)
- h.Parent.logRequest(r, false, http.StatusRequestTimeout, "host-http", reqHostname, upstreamHostname)
+ h.Parent.logRequest(r, false, http.StatusRequestTimeout, "host-http", reqHostname, upstreamHostname, target)
} else {
http.ServeFile(w, r, "./web/rperror.html")
- h.Parent.logRequest(r, false, 521, "host-http", reqHostname, upstreamHostname)
+ h.Parent.logRequest(r, false, 521, "host-http", reqHostname, upstreamHostname, target)
}
}
- h.Parent.logRequest(r, true, statusCode, "host-http", reqHostname, upstreamHostname)
+ h.Parent.logRequest(r, true, statusCode, "host-http", reqHostname, upstreamHostname, target)
}
// Handle vdir type request
@@ -286,7 +286,7 @@ func (h *ProxyHandler) vdirRequest(w http.ResponseWriter, r *http.Request, targe
target.parent.HeaderRewriteRules = GetDefaultHeaderRewriteRules()
}
- h.Parent.logRequest(r, true, 101, "vdir-websocket", r.Host, target.Domain)
+ h.Parent.logRequest(r, true, 101, "vdir-websocket", r.Host, target.Domain, target.parent)
wspHandler := websocketproxy.NewProxy(u, websocketproxy.Options{
SkipTLSValidation: target.SkipCertValidations,
SkipOriginCheck: true, //You should not use websocket via virtual directory. But keep this to true for compatibility
@@ -342,19 +342,25 @@ func (h *ProxyHandler) vdirRequest(w http.ResponseWriter, r *http.Request, targe
if errors.As(err, &dnsError) {
http.ServeFile(w, r, "./web/hosterror.html")
log.Println(err.Error())
- h.Parent.logRequest(r, false, 404, "vdir-http", reqHostname, target.Domain)
+ h.Parent.logRequest(r, false, 404, "vdir-http", reqHostname, target.Domain, target.parent)
} else {
http.ServeFile(w, r, "./web/rperror.html")
log.Println(err.Error())
- h.Parent.logRequest(r, false, 521, "vdir-http", reqHostname, target.Domain)
+ h.Parent.logRequest(r, false, 521, "vdir-http", reqHostname, target.Domain, target.parent)
}
}
- h.Parent.logRequest(r, true, statusCode, "vdir-http", reqHostname, target.Domain)
+ h.Parent.logRequest(r, true, statusCode, "vdir-http", reqHostname, target.Domain, target.parent)
}
// This logger collect data for the statistical analysis. For log to file logger, check the Logger and LogHTTPRequest handler
-func (router *Router) logRequest(r *http.Request, succ bool, statusCode int, forwardType string, originalHostname string, upstreamHostname string) {
+func (router *Router) logRequest(r *http.Request, succ bool, statusCode int, forwardType string, originalHostname string, upstreamHostname string, endpoint *ProxyEndpoint) {
+ if endpoint != nil && endpoint.DisableLogging {
+ // Notes: endpoint can be nil if the request has been handled before a host name can be resolved
+ // e.g. Redirection matching rule
+ // in that case we will log it by default and will not enter this routine
+ return
+ }
if router.Option.StatisticCollector != nil {
go func() {
requestInfo := statistic.RequestInfo{
diff --git a/src/mod/dynamicproxy/ratelimit.go b/src/mod/dynamicproxy/ratelimit.go
index a809cc9..04fa1e7 100644
--- a/src/mod/dynamicproxy/ratelimit.go
+++ b/src/mod/dynamicproxy/ratelimit.go
@@ -51,7 +51,7 @@ func (t *RequestCountPerIpTable) Clear() {
func (h *ProxyHandler) handleRateLimitRouting(w http.ResponseWriter, r *http.Request, pe *ProxyEndpoint) error {
err := h.Parent.handleRateLimit(w, r, pe)
if err != nil {
- h.Parent.logRequest(r, false, 429, "ratelimit", r.URL.Hostname(), "")
+ h.Parent.logRequest(r, false, 429, "ratelimit", r.URL.Hostname(), "", pe)
}
return err
}
diff --git a/src/mod/dynamicproxy/typedef.go b/src/mod/dynamicproxy/typedef.go
index 3caf5b3..414b6d7 100644
--- a/src/mod/dynamicproxy/typedef.go
+++ b/src/mod/dynamicproxy/typedef.go
@@ -208,6 +208,7 @@ type ProxyEndpoint struct {
//Uptime Monitor
DisableUptimeMonitor bool //Disable uptime monitor for this endpoint
+ DisableLogging bool //Disable logging of reverse proxy requests
// Chunked Transfer Encoding
DisableChunkedTransferEncoding bool //Disable chunked transfer encoding for this endpoint
diff --git a/src/reverseproxy.go b/src/reverseproxy.go
index 9eea778..652ae66 100644
--- a/src/reverseproxy.go
+++ b/src/reverseproxy.go
@@ -244,6 +244,9 @@ func ReverseProxyHandleAddEndpoint(w http.ResponseWriter, r *http.Request) {
enableUtm = true
}
+ // Disable logging?
+ disableLog, _ := utils.PostBool(r, "disableLog")
+
useBypassGlobalTLS := bypassGlobalTLS == "true"
//Enable TLS validation?
@@ -416,6 +419,7 @@ func ReverseProxyHandleAddEndpoint(w http.ResponseWriter, r *http.Request) {
Tags: tags,
DisableUptimeMonitor: !enableUtm,
+ DisableLogging: disableLog,
}
preparedEndpoint, err := dynamicProxyRouter.PrepareProxyRoute(&thisProxyEndpoint)
@@ -570,6 +574,9 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) {
// Disable chunked Encoding
disableChunkedEncoding, _ := utils.PostBool(r, "dChunkedEnc")
+ // Disable logging
+ disableLogging, _ := utils.PostBool(r, "dLogging")
+
//Load the previous basic auth credentials from current proxy rules
targetProxyEntry, err := dynamicProxyRouter.LoadProxy(rootNameOrMatchingDomain)
if err != nil {
@@ -611,6 +618,7 @@ func ReverseProxyHandleEditEndpoint(w http.ResponseWriter, r *http.Request) {
newProxyEndpoint.UseStickySession = useStickySession
newProxyEndpoint.DisableUptimeMonitor = disbleUtm
newProxyEndpoint.DisableChunkedTransferEncoding = disableChunkedEncoding
+ newProxyEndpoint.DisableLogging = disableLogging
newProxyEndpoint.Tags = tags
//Prepare to replace the current routing rule
diff --git a/src/web/components/httprp.html b/src/web/components/httprp.html
index 6e63f80..15de241 100644
--- a/src/web/components/httprp.html
+++ b/src/web/components/httprp.html
@@ -284,6 +284,12 @@
+
+