diff --git a/cmd/falco/help.go b/cmd/falco/help.go index c0b2e013..6ac47231 100644 --- a/cmd/falco/help.go +++ b/cmd/falco/help.go @@ -98,6 +98,7 @@ Flags: -h, --help : Show this help -r, --remote : Connect with Fastly API -request : Simulate request config + -body : Output response body -debug : Enable debug mode --max_backends : Override max backends limitation --max_acls : Override max acls limitation diff --git a/cmd/falco/runner.go b/cmd/falco/runner.go index 99715e15..9d7d785f 100644 --- a/cmd/falco/runner.go +++ b/cmd/falco/runner.go @@ -428,6 +428,7 @@ func (r *Runner) Simulate(rslv resolver.Resolver) error { icontext.WithResolver(rslv), icontext.WithMaxBackends(r.config.OverrideMaxBackends), icontext.WithMaxAcls(r.config.OverrideMaxAcls), + icontext.WithOutputResponseBody(r.config.Simulator.OutputResponseBody), } if r.snippets != nil { options = append(options, icontext.WithSnippets(r.snippets)) diff --git a/config/config.go b/config/config.go index 0f87d387..80fe5308 100644 --- a/config/config.go +++ b/config/config.go @@ -33,7 +33,8 @@ type SimulatorConfig struct { IncludePaths []string // Copy from root field // Override Request configuration - OverrideRequest *RequestConfig + OverrideRequest *RequestConfig + OutputResponseBody bool `cli:"body" yaml:"output_response_body"` } // Testing configuration @@ -52,7 +53,7 @@ type Config struct { IncludePaths []string `cli:"I,include_path" yaml:"include_paths"` Transforms []string `cli:"t,transformer" yaml:"transformers"` Help bool `cli:"h,help"` - Version bool `cli:"V"` + Version bool `cli:"V,version"` Remote bool `cli:"r,remote" yaml:"remote"` Json bool `cli:"json"` Request string `cli:"request"` diff --git a/interpreter/context/context.go b/interpreter/context/context.go index 0f0ccbdf..67d4c6c1 100644 --- a/interpreter/context/context.go +++ b/interpreter/context/context.go @@ -55,6 +55,7 @@ type Context struct { Gotos map[string]*ast.GotoStatement SubroutineFunctions map[string]*ast.SubroutineDeclaration OriginalHost string + OutputResponseBody bool OverrideMaxBackends int OverrideMaxAcls int diff --git a/interpreter/context/option.go b/interpreter/context/option.go index baa5e440..e6b34a86 100644 --- a/interpreter/context/option.go +++ b/interpreter/context/option.go @@ -49,3 +49,9 @@ func WithOverrideHost(host string) Option { c.OriginalHost = host } } + +func WithOutputResponseBody(o bool) Option { + return func(c *Context) { + c.OutputResponseBody = o + } +} diff --git a/interpreter/interpreter.go b/interpreter/interpreter.go index cd481e11..6ace7d87 100644 --- a/interpreter/interpreter.go +++ b/interpreter/interpreter.go @@ -131,7 +131,7 @@ func (i *Interpreter) ProcessInit(r *http.Request) error { i.ctx.OriginalHost = r.Host } - i.process = process.New() + i.process = process.New(i.ctx.OutputResponseBody) i.ctx.Scope = context.InitScope i.vars = variable.NewAllScopeVariables(i.ctx) diff --git a/interpreter/process/flow.go b/interpreter/process/flow.go index 90a794c0..2c3bdf4e 100644 --- a/interpreter/process/flow.go +++ b/interpreter/process/flow.go @@ -12,6 +12,7 @@ type Flow struct { Line int `json:"line"` Position int `json:"position"` Subroutine string `json:"subroutine"` + Backend string `json:"backend,omitempty"` Request *HttpFlow `json:"req,omitempty"` BackendRequest *HttpFlow `json:"bereq,omitempty"` BackendResponse *HttpFlow `json:"beresp,omitempty"` @@ -29,6 +30,9 @@ func NewFlow(ctx *icontext.Context, sub *ast.SubroutineDeclaration) *Flow { Position: token.Position, Subroutine: sub.Name.Value, } + if ctx.Backend != nil { + f.Backend = ctx.Backend.String() + } if ctx.Request != nil { f.Request = newFlowRequest(ctx.Request.Clone(c)) } diff --git a/interpreter/process/process.go b/interpreter/process/process.go index 06b32122..a75494c1 100644 --- a/interpreter/process/process.go +++ b/interpreter/process/process.go @@ -12,6 +12,8 @@ import ( ) type Process struct { + includeBody bool + Flows []*Flow Logs []*Log Restarts int @@ -22,11 +24,12 @@ type Process struct { Response *http.Response } -func New() *Process { +func New(includeBody bool) *Process { return &Process{ - Flows: []*Flow{}, - Logs: []*Log{}, - StartTime: time.Now().UnixMicro(), + Flows: []*Flow{}, + Logs: []*Log{}, + StartTime: time.Now().UnixMicro(), + includeBody: includeBody, } } @@ -56,6 +59,11 @@ func (p *Process) Finalize(resp *http.Response) ([]byte, error) { } } + var body string + if p.includeBody { + body = buf.String() + } + return json.MarshalIndent(struct { Flows []*Flow `json:"flows"` Logs []*Log `json:"logs"` @@ -68,6 +76,7 @@ func (p *Process) Finalize(resp *http.Response) ([]byte, error) { ClientResponse struct { StatusCode int `json:"status_code"` ResponseBytes int `json:"body_bytes"` + ResponseBody string `json:"body,omitempty"` Headers map[string]string `json:"headers"` } `json:"client_response"` }{ @@ -82,10 +91,12 @@ func (p *Process) Finalize(resp *http.Response) ([]byte, error) { ClientResponse: struct { StatusCode int `json:"status_code"` ResponseBytes int `json:"body_bytes"` + ResponseBody string `json:"body,omitempty"` Headers map[string]string `json:"headers"` }{ StatusCode: statusCode, ResponseBytes: len(buf.Bytes()), + ResponseBody: body, Headers: headers, }, }, "", " ")