feat(rewriter): add redirect(), get_cookie(), add_cookie() methods to rule engine (#36)
Some checks are pending
Cadoles/bouncer/pipeline/pr-develop Build started...

This commit is contained in:
2024-09-25 15:50:13 +02:00
committed by wpetit
parent cb9260ac2b
commit 04b41baea3
11 changed files with 710 additions and 110 deletions

View File

@ -3,6 +3,7 @@ package http
import (
"context"
"fmt"
"net/http"
"strconv"
"strings"
"time"
@ -41,7 +42,7 @@ func addResponseHeaderFunc() expr.Option {
value = fmt.Sprintf("%v", rawValue)
}
r, ok := ctxResponse(ctx)
r, ok := CtxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
@ -82,7 +83,7 @@ func setResponseHeaderFunc() expr.Option {
value = fmt.Sprintf("%v", rawValue)
}
r, ok := ctxResponse(ctx)
r, ok := CtxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
@ -109,7 +110,7 @@ func delResponseHeadersFunc() expr.Option {
return nil, errors.WithStack(err)
}
r, ok := ctxResponse(ctx)
r, ok := CtxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
@ -130,3 +131,84 @@ func delResponseHeadersFunc() expr.Option {
new(func(context.Context, string) bool),
)
}
func addResponseCookieFunc() expr.Option {
return expr.Function(
"add_cookie",
func(params ...any) (any, error) {
ctx, err := rule.Assert[context.Context](params[0])
if err != nil {
return nil, errors.WithStack(err)
}
values, err := rule.Assert[map[string]any](params[1])
if err != nil {
return nil, errors.WithStack(err)
}
cookie, err := cookieFrom(values)
if err != nil {
return nil, errors.WithStack(err)
}
r, ok := CtxResponse(ctx)
if !ok {
return nil, errors.New("could not find http request in context")
}
r.Header.Add("Set-Cookie", cookie.String())
return true, nil
},
new(func(context.Context, map[string]any) bool),
)
}
func getResponseCookieFunc() expr.Option {
return expr.Function(
"get_cookie",
func(params ...any) (any, error) {
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)
}
res, ok := CtxResponse(ctx)
if !ok {
return nil, errors.New("could not find http response in context")
}
var cookie *http.Cookie
for _, c := range res.Cookies() {
if c.Name != name {
continue
}
cookie = c
break
}
if cookie == nil {
return nil, nil
}
return CookieVar{
Name: cookie.Name,
Value: cookie.Value,
Path: cookie.Path,
Domain: cookie.Domain,
Expires: cookie.Expires,
MaxAge: cookie.MaxAge,
Secure: cookie.Secure,
HttpOnly: cookie.HttpOnly,
SameSite: cookie.SameSite,
}, nil
},
new(func(context.Context, string) CookieVar),
)
}