package http import ( "context" "io" "net/http" "testing" "forge.cadoles.com/cadoles/bouncer/internal/rule" "github.com/pkg/errors" ) func TestAddResponseHeader(t *testing.T) { type Vars struct { NewHeaderKey string `expr:"newHeaderKey"` NewHeaderValue string `expr:"newHeaderValue"` } engine := createRuleEngine[Vars](t, rule.WithExpr(addResponseHeaderFunc()), 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)) } resp := createResponse(req, http.StatusOK, nil) ctx := context.Background() ctx = WithResponse(ctx, resp) 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, resp.Header.Get(vars.NewHeaderKey); e != g { t.Errorf("resp.Header.Get(vars.NewHeaderKey): expected '%v', got '%v'", e, g) } } func TestResponseSetHeader(t *testing.T) { type Vars struct { HeaderKey string `expr:"headerKey"` HeaderValue string `expr:"headerValue"` } engine := createRuleEngine[Vars](t, rule.WithExpr(setResponseHeaderFunc()), 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)) } resp := createResponse(req, http.StatusOK, nil) vars := Vars{ HeaderKey: "X-My-Header", HeaderValue: "foobar", } resp.Header.Set(vars.HeaderKey, "test") ctx := context.Background() ctx = WithResponse(ctx, resp) if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if e, g := vars.HeaderValue, resp.Header.Get(vars.HeaderKey); e != g { t.Errorf("resp.Header.Get(vars.HeaderKey): expected '%v', got '%v'", e, g) } } func TestResponseDelHeaders(t *testing.T) { type Vars struct { HeaderPattern string `expr:"headerPattern"` } engine := createRuleEngine[Vars](t, rule.WithExpr(delResponseHeadersFunc()), 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)) } resp := createResponse(req, http.StatusOK, nil) vars := Vars{ HeaderPattern: "X-My-*", } resp.Header.Set("X-My-Header", "test") ctx := context.Background() ctx = WithResponse(ctx, resp) if _, err := engine.Apply(ctx, vars); err != nil { t.Fatalf("%+v", errors.WithStack(err)) } if val := resp.Header.Get("X-My-Header"); val != "" { t.Errorf("resp.Header.Get(\"X-My-Header\") should be empty, got '%v'", val) } } func createResponse(req *http.Request, statusCode int, body io.Reader) *http.Response { return &http.Response{ Status: http.StatusText(statusCode), StatusCode: statusCode, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Body: io.NopCloser(body), ContentLength: -1, Request: req, Header: make(http.Header, 0), } }