add ruleset path support
This commit is contained in:
@@ -167,7 +167,7 @@ func main() {
|
||||
|
||||
app.Get("styles.css", handlers.Styles)
|
||||
app.Get("script.js", handlers.Script)
|
||||
app.Get("ruleset", handlers.Ruleset)
|
||||
app.Get("ruleset/*", handlers.NewRulesetSiteHandler(proxyOpts))
|
||||
|
||||
app.All("raw/*", handlers.NewRawProxySiteHandler(proxyOpts))
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"ladder/proxychain"
|
||||
rx "ladder/proxychain/requestmodifiers"
|
||||
tx "ladder/proxychain/responsemodifiers"
|
||||
|
||||
@@ -1,9 +1,93 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Ruleset(c *fiber.Ctx) error {
|
||||
return nil
|
||||
func NewRulesetSiteHandler(opts *ProxyOptions) fiber.Handler {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -283,10 +283,6 @@ func (chain *ProxyChain) extractURLFromSubdomain() (*url.URL, error) {
|
||||
func (chain *ProxyChain) extractURLFromPath() (*url.URL, error) {
|
||||
reqURL := chain.Context.Params("*")
|
||||
|
||||
fmt.Println("XXXXXXXXXXXXXXXX")
|
||||
fmt.Println(reqURL)
|
||||
fmt.Println(chain.APIPrefix)
|
||||
|
||||
reqURL = strings.TrimPrefix(reqURL, chain.APIPrefix)
|
||||
|
||||
// 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
|
||||
// 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")
|
||||
if ct == nil && CT == nil {
|
||||
|
||||
Reference in New Issue
Block a user