feat: reusable rule engine to prevent memory reallocation
All checks were successful
Cadoles/bouncer/pipeline/pr-develop This commit looks good

This commit is contained in:
2024-09-24 15:46:42 +02:00
parent f37425018b
commit fea0610346
23 changed files with 885 additions and 198 deletions

View File

@ -1,22 +1,33 @@
package http
import (
"context"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"forge.cadoles.com/Cadoles/go-proxy/wildcard"
"forge.cadoles.com/cadoles/bouncer/internal/rule"
"github.com/expr-lang/expr"
"github.com/pkg/errors"
)
func addResponseHeaderFunc(r *http.Response) expr.Option {
func addResponseHeaderFunc() expr.Option {
return expr.Function(
"add_header",
func(params ...any) (any, error) {
name := params[0].(string)
rawValue := params[1]
ctx, err := rule.Assert[context.Context](params[0])
if err != nil {
return nil, errors.WithStack(err)
}
name, err := rule.Assert[string](params[1])
if err != nil {
return nil, errors.WithStack(err)
}
rawValue := params[2]
var value string
switch v := rawValue.(type) {
@ -30,20 +41,34 @@ func addResponseHeaderFunc(r *http.Response) expr.Option {
value = fmt.Sprintf("%v", rawValue)
}
r, ok := ctxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
r.Header.Add(name, value)
return true, nil
},
new(func(string, string) bool),
new(func(context.Context, string, string) bool),
)
}
func setResponseHeaderFunc(r *http.Response) expr.Option {
func setResponseHeaderFunc() expr.Option {
return expr.Function(
"set_header",
func(params ...any) (any, error) {
name := params[0].(string)
rawValue := params[1]
ctx, err := rule.Assert[context.Context](params[0])
if err != nil {
return nil, errors.WithStack(err)
}
name, err := rule.Assert[string](params[1])
if err != nil {
return nil, errors.WithStack(err)
}
rawValue := params[2]
var value string
switch v := rawValue.(type) {
@ -57,19 +82,38 @@ func setResponseHeaderFunc(r *http.Response) expr.Option {
value = fmt.Sprintf("%v", rawValue)
}
r, ok := ctxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
r.Header.Set(name, value)
return true, nil
},
new(func(string, string) bool),
new(func(context.Context, string, string) bool),
)
}
func delResponseHeadersFunc(r *http.Response) expr.Option {
func delResponseHeadersFunc() expr.Option {
return expr.Function(
"del_headers",
func(params ...any) (any, error) {
pattern := params[0].(string)
ctx, err := rule.Assert[context.Context](params[0])
if err != nil {
return nil, errors.WithStack(err)
}
pattern, err := rule.Assert[string](params[1])
if err != nil {
return nil, errors.WithStack(err)
}
r, ok := ctxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
deleted := false
for key := range r.Header {
@ -83,6 +127,6 @@ func delResponseHeadersFunc(r *http.Response) expr.Option {
return deleted, nil
},
new(func(string) bool),
new(func(context.Context, string) bool),
)
}