package http import ( "context" "net/http" "testing" "forge.cadoles.com/cadoles/bouncer/internal/rule" "github.com/pkg/errors" ) func TestSetRequestHost(t *testing.T) { type Vars struct { NewHost string `expr:"newHost"` } engine := createRuleEngine[Vars](t, rule.WithExpr(setRequestHostFunc()), rule.WithRules( "set_host(ctx, vars.newHost)", ), ) req, err := http.NewRequest("GET", "http://example.net", nil) if err != nil { t.Fatalf("%+v", errors.WithStack(err)) } ctx := context.Background() ctx = WithRequest(ctx, req) vars := Vars{ NewHost: "foobar", } if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if e, g := vars.NewHost, req.Host; e != g { t.Errorf("req.Host: expected '%v', got '%v'", e, g) } } func TestSetRequestURL(t *testing.T) { type Vars struct { NewURL string `expr:"newURL"` } engine := createRuleEngine[Vars](t, rule.WithExpr(setRequestURLFunc()), rule.WithRules( "set_url(ctx, vars.newURL)", ), ) req, err := http.NewRequest("GET", "http://example.net", nil) if err != nil { t.Fatalf("%+v", errors.WithStack(err)) } ctx := context.Background() ctx = WithRequest(ctx, req) vars := Vars{ NewURL: "http://localhost", } if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if e, g := vars.NewURL, req.URL.String(); e != g { t.Errorf("req.URL.String(): expected '%v', got '%v'", e, g) } } func TestAddRequestHeader(t *testing.T) { type Vars struct { NewHeaderKey string `expr:"newHeaderKey"` NewHeaderValue string `expr:"newHeaderValue"` } engine := createRuleEngine[Vars](t, rule.WithExpr(addRequestHeaderFunc()), rule.WithRules( "add_header(ctx, vars.newHeaderKey, vars.newHeaderValue)", ), ) req, err := http.NewRequest("GET", "http://example.net", nil) if err != nil { t.Fatalf("%+v", errors.WithStack(err)) } ctx := context.Background() ctx = WithRequest(ctx, req) vars := Vars{ NewHeaderKey: "X-My-Header", NewHeaderValue: "foobar", } if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if e, g := vars.NewHeaderValue, req.Header.Get(vars.NewHeaderKey); e != g { t.Errorf("req.Header.Get(vars.NewHeaderKey): expected '%v', got '%v'", e, g) } } func TestSetRequestHeader(t *testing.T) { type Vars struct { HeaderKey string `expr:"headerKey"` HeaderValue string `expr:"headerValue"` } engine := createRuleEngine[Vars](t, rule.WithExpr(setRequestHeaderFunc()), rule.WithRules( "set_header(ctx, vars.headerKey, vars.headerValue)", ), ) req, err := http.NewRequest("GET", "http://example.net", nil) if err != nil { t.Fatalf("%+v", errors.WithStack(err)) } vars := Vars{ HeaderKey: "X-My-Header", HeaderValue: "foobar", } req.Header.Set(vars.HeaderKey, "test") ctx := context.Background() ctx = WithRequest(ctx, req) if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if e, g := vars.HeaderValue, req.Header.Get(vars.HeaderKey); e != g { t.Errorf("req.Header.Get(vars.HeaderKey): expected '%v', got '%v'", e, g) } } func TestDelRequestHeaders(t *testing.T) { type Vars struct { HeaderPattern string `expr:"headerPattern"` } engine := createRuleEngine[Vars](t, rule.WithExpr(delRequestHeadersFunc()), rule.WithRules( "del_headers(ctx, vars.headerPattern)", ), ) req, err := http.NewRequest("GET", "http://example.net", nil) if err != nil { t.Fatalf("%+v", errors.WithStack(err)) } vars := Vars{ HeaderPattern: "X-My-*", } req.Header.Set("X-My-Header", "test") ctx := context.Background() ctx = WithRequest(ctx, req) if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if val := req.Header.Get("X-My-Header"); val != "" { t.Errorf("req.Header.Get(\"X-My-Header\") should be empty, got '%v'", val) } } func createRuleEngine[V any](t *testing.T, funcs ...rule.OptionFunc) *rule.Engine[V] { engine, err := rule.NewEngine[V](funcs...) if err != nil { t.Fatalf("%+v", errors.WithStack(err)) } return engine }