From c2d61dbcb51638ecce61adf063bfe19802769617 Mon Sep 17 00:00:00 2001
From: Gianni Carafa
Date: Thu, 9 Apr 2026 21:06:51 +0200
Subject: [PATCH] add a debug icon and drawer
---
handlers/proxy.go | 191 +++++++++++++++++++++++++++++++++++++++--
handlers/proxy.test.go | 31 +++++++
2 files changed, 214 insertions(+), 8 deletions(-)
diff --git a/handlers/proxy.go b/handlers/proxy.go
index 55d79f55..48b1c86e 100644
--- a/handlers/proxy.go
+++ b/handlers/proxy.go
@@ -52,14 +52,23 @@ type FlareSolverrResponse struct {
}
var (
- UserAgent = getenv("USER_AGENT", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
- ForwardedFor = getenv("X_FORWARDED_FOR", "66.249.66.1")
+ UserAgent = getenv("USER_AGENT", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
+ ForwardedFor = getenv("X_FORWARDED_FOR", "66.249.66.1")
flareSolverrHost = os.Getenv("FLARESOLVERR_HOST")
- rulesSet = ruleset.NewRulesetFromEnv()
- allowedDomains = []string{}
- defaultTimeout = 15 // in seconds
+ rulesSet = ruleset.NewRulesetFromEnv()
+ allowedDomains = []string{}
+ defaultTimeout = 15 // in seconds
)
+const ladderParamPrefix = "__ladder_"
+
+type debugUIOptions struct {
+ Enabled bool
+ ShowRequest bool
+ HasUI bool
+ ShowUI bool
+}
+
func init() {
allowedDomains = strings.Split(os.Getenv("ALLOWED_DOMAINS"), ",")
if os.Getenv("ALLOWED_DOMAINS_RULESET") == "true" {
@@ -180,13 +189,19 @@ func ProxySite(rulesetPath string) fiber.Handler {
}
queries := c.Queries()
- body, _, resp, err := fetchSite(url, queries)
+ proxyQueries, debugOptions := splitProxyQueries(queries)
+ body, _, resp, err := fetchSite(url, proxyQueries)
if err != nil {
log.Println("ERROR:", err)
c.SendStatus(fiber.StatusInternalServerError)
return c.SendString(err.Error())
}
+ contentType := strings.ToLower(resp.Header.Get("Content-Type"))
+ if strings.Contains(contentType, "text/html") && shouldInjectDebugUI(debugOptions) {
+ body = injectDebugUI(body, debugOptions)
+ }
+
c.Cookie(&fiber.Cookie{})
c.Set("Content-Type", resp.Header.Get("Content-Type"))
c.Set("Content-Security-Policy", resp.Header.Get("Content-Security-Policy"))
@@ -195,6 +210,166 @@ func ProxySite(rulesetPath string) fiber.Handler {
}
}
+func shouldInjectDebugUI(options debugUIOptions) bool {
+ if os.Getenv("DEBUG_UI") == "false" {
+ return false
+ }
+
+ if options.HasUI {
+ return options.ShowUI
+ }
+
+ if os.Getenv("DEBUG_UI") == "true" {
+ return true
+ }
+
+ return true
+}
+
+func splitProxyQueries(queries map[string]string) (map[string]string, debugUIOptions) {
+ proxyQueries := map[string]string{}
+ options := debugUIOptions{}
+
+ for key, value := range queries {
+ switch key {
+ case "__ladder_debug":
+ options.Enabled = value == "1"
+ continue
+ case "__ladder_show_request":
+ options.ShowRequest = value == "1"
+ continue
+ case "__ladder_ui":
+ options.HasUI = true
+ options.ShowUI = value == "1"
+ continue
+ }
+
+ if strings.HasPrefix(key, ladderParamPrefix) {
+ continue
+ }
+
+ proxyQueries[key] = value
+ }
+
+ return proxyQueries, options
+}
+
+func injectDebugUI(body string, options debugUIOptions) string {
+ if !strings.Contains(strings.ToLower(body), "Request: `
+ }
+
+ injection := fmt.Sprintf(`
+
+
+
+`, debugChecked, showRequestChecked, requestInfo)
+
+ bodyClose := regexp.MustCompile(`(?i)`)
+ if bodyClose.MatchString(body) {
+ return bodyClose.ReplaceAllString(body, injection+"
hello