add ruleset path support

This commit is contained in:
Kevin Pham
2023-12-07 09:23:12 -06:00
parent 4779229b32
commit 8166eb31af
5 changed files with 87 additions and 9 deletions

View File

@@ -167,7 +167,7 @@ func main() {
app.Get("styles.css", handlers.Styles) app.Get("styles.css", handlers.Styles)
app.Get("script.js", handlers.Script) app.Get("script.js", handlers.Script)
app.Get("ruleset", handlers.Ruleset) app.Get("ruleset/*", handlers.NewRulesetSiteHandler(proxyOpts))
app.All("raw/*", handlers.NewRawProxySiteHandler(proxyOpts)) app.All("raw/*", handlers.NewRawProxySiteHandler(proxyOpts))

View File

@@ -1,7 +1,6 @@
package handlers package handlers
import ( import (
"fmt"
"ladder/proxychain" "ladder/proxychain"
rx "ladder/proxychain/requestmodifiers" rx "ladder/proxychain/requestmodifiers"
tx "ladder/proxychain/responsemodifiers" tx "ladder/proxychain/responsemodifiers"

View File

@@ -1,9 +1,93 @@
package handlers package handlers
import ( import (
"encoding/json"
"fmt"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"gopkg.in/yaml.v3"
"net/url"
"strings"
) )
func Ruleset(c *fiber.Ctx) error { func NewRulesetSiteHandler(opts *ProxyOptions) fiber.Handler {
return nil
return func(c *fiber.Ctx) error {
if opts == nil {
c.SendStatus(404)
c.SendString("No ruleset specified. Set the RULESET environment variable or use the --ruleset flag.")
}
// no specific rule requested, return the entire ruleset
if c.Params("*") == "" {
switch c.Get("accept") {
case "application/json":
jsn, err := opts.Ruleset.JSON()
if err != nil {
return err
}
c.Set("content-type", "application/json")
return c.Send([]byte(jsn))
default:
// TODO: the ruleset.MarshalYAML() method is currently broken and panics
yml, err := opts.Ruleset.YAML()
if err != nil {
return err
}
c.Set("content-type", "application/yaml")
return c.Send([]byte(yml))
}
}
// a specific rule was requested by path /ruleset/https://example.com
// return only that particular rule
reqURL, err := extractURLFromContext(c, "ruleset/")
if err != nil {
return err
}
rule, exists := opts.Ruleset.GetRule(reqURL)
if !exists {
c.SendStatus(404)
c.SendString(fmt.Sprintf("A rule that matches '%s' was not found in the ruleset.", reqURL))
}
switch c.Get("accept") {
case "application/json":
jsn, err := json.MarshalIndent(rule, "", " ")
if err != nil {
return err
}
c.Set("content-type", "application/json")
return c.Send(jsn)
default:
yml, err := yaml.Marshal(rule)
if err != nil {
return err
}
c.Set("content-type", "application/yaml")
return c.Send(yml)
}
}
}
// extractURLFromContext extracts a URL from the request ctx.
func extractURLFromContext(ctx *fiber.Ctx, apiPrefix string) (*url.URL, error) {
reqURL := ctx.Params("*")
reqURL = strings.TrimPrefix(reqURL, apiPrefix)
// sometimes client requests doubleroot '//'
// there is a bug somewhere else, but this is a workaround until we find it
if strings.HasPrefix(reqURL, "/") || strings.HasPrefix(reqURL, `%2F`) {
reqURL = strings.TrimPrefix(reqURL, "/")
reqURL = strings.TrimPrefix(reqURL, `%2F`)
}
// unescape url query
uReqURL, err := url.QueryUnescape(reqURL)
if err == nil {
reqURL = uReqURL
}
return url.Parse(reqURL)
} }

View File

@@ -283,10 +283,6 @@ func (chain *ProxyChain) extractURLFromSubdomain() (*url.URL, error) {
func (chain *ProxyChain) extractURLFromPath() (*url.URL, error) { func (chain *ProxyChain) extractURLFromPath() (*url.URL, error) {
reqURL := chain.Context.Params("*") reqURL := chain.Context.Params("*")
fmt.Println("XXXXXXXXXXXXXXXX")
fmt.Println(reqURL)
fmt.Println(chain.APIPrefix)
reqURL = strings.TrimPrefix(reqURL, chain.APIPrefix) reqURL = strings.TrimPrefix(reqURL, chain.APIPrefix)
// sometimes client requests doubleroot '//' // sometimes client requests doubleroot '//'
@@ -530,7 +526,6 @@ func (chain *ProxyChain) Execute() error {
} }
// in case api user did not set or forward content-type, we do it for them // in case api user did not set or forward content-type, we do it for them
// warning: the fiber method chain.Context.Get() doesn't seem to work as described
ct := chain.Context.Response().Header.Peek("content-type") ct := chain.Context.Response().Header.Peek("content-type")
CT := chain.Context.Response().Header.Peek("Content-Type") CT := chain.Context.Response().Header.Peek("Content-Type")
if ct == nil && CT == nil { if ct == nil && CT == nil {

BIN
tmp/main Executable file

Binary file not shown.