diff --git a/go.mod b/go.mod index c7faca4..0715af7 100644 --- a/go.mod +++ b/go.mod @@ -1,27 +1,28 @@ module github.com/corazawaf/coraza-spoa -go 1.19 +go 1.21 require ( github.com/bluele/gcache v0.0.2 github.com/corazawaf/coraza/v3 v3.0.1 - github.com/criteo/haproxy-spoe-go v1.0.6 + github.com/dropmorepackets/haproxy-go v0.0.3 github.com/magefile/mage v1.15.0 go.uber.org/zap v1.24.0 gopkg.in/yaml.v3 v3.0.1 ) require ( + github.com/adrianbrad/queue v1.2.1 // indirect github.com/corazawaf/libinjection-go v0.1.2 // indirect + github.com/kr/text v0.2.0 // indirect github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/net v0.11.0 // indirect - golang.org/x/sys v0.9.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect rsc.io/binaryregexp v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index b796025..d7510c1 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,7 @@ +github.com/adrianbrad/queue v1.2.1 h1:CEVsjFQyuR0s5Hty/HJGWBZHsJ3KMmii0kEgLeam/mk= +github.com/adrianbrad/queue v1.2.1/go.mod h1:wYiPC/3MPbyT45QHLrPR4zcqJWPePubM1oEP/xTwhUs= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= github.com/corazawaf/coraza/v3 v3.0.1 h1:akPpTofIUhabGU1Zbo+YVBZK/HdcxjGy8yXkjoqVFMQ= @@ -6,13 +9,12 @@ github.com/corazawaf/coraza/v3 v3.0.1/go.mod h1:zvldIncYMuW8xmRcOs37OWRhY3CPWBKb github.com/corazawaf/libinjection-go v0.1.2 h1:oeiV9pc5rvJ+2oqOqXEAMJousPpGiup6f7Y3nZj5GoM= github.com/corazawaf/libinjection-go v0.1.2/go.mod h1:OP4TM7xdJ2skyXqNX1AN1wN5nNZEmJNuWbNPOItn7aw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/criteo/haproxy-spoe-go v1.0.6 h1:3GDQ8hm/fIkn4wxxI/pN0OoBfKon4ROzvpU5fIriYII= -github.com/criteo/haproxy-spoe-go v1.0.6/go.mod h1:o04s69MOZ7SvPthMtUt/tfn1hcorQQAS/nwzKPBlXQU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dropmorepackets/haproxy-go v0.0.3 h1:JD7ldNP6mPL2cQI+4ysM/NZJBASQrIXLm2By52+ATTU= +github.com/dropmorepackets/haproxy-go v0.0.3/go.mod h1:jO9LDRFek2auFuEFHl7rpTYZ8nh3g6ipPwaWqSGidOU= github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -22,19 +24,15 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 h1:lL+y4Xv20pVlCGyLzNHRC0I0rIHhIL1lTvHizoS/dU8= github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9/go.mod h1:EHPiTAKtiFmrMldLUNswFwfZ2eJIYBHktdaUTZxYWRw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -45,25 +43,22 @@ github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= diff --git a/internal/message.go b/internal/message.go index 549375e..d283d06 100644 --- a/internal/message.go +++ b/internal/message.go @@ -5,38 +5,42 @@ package internal import ( "fmt" - "net" + "net/netip" - spoe "github.com/criteo/haproxy-spoe-go" + "github.com/dropmorepackets/haproxy-go/pkg/encoding" ) type message struct { - msg *spoe.Message - args map[string]interface{} + args map[string]any } -func NewMessage(msg *spoe.Message) (*message, error) { - message := message{ - msg: msg, - args: make(map[string]interface{}, msg.Args.Count()), +func NewMessage(m *encoding.Message) (*message, error) { + msg := message{ + args: make(map[string]any), } - return &message, nil + + e := encoding.AcquireKVEntry() + defer encoding.ReleaseKVEntry(e) + + for m.KV.Next(e) { + switch e.Type() { + case encoding.DataTypeInt32, encoding.DataTypeInt64, + encoding.DataTypeUInt32, encoding.DataTypeUInt64: + msg.args[string(e.NameBytes())] = int(e.ValueInt()) + default: + msg.args[string(e.NameBytes())] = e.Value() + } + } + + return &msg, nil } -func (m *message) findArg(name string) (interface{}, error) { +func (m *message) findArg(name string) (any, error) { argVal, exist := m.args[name] if exist { return argVal, nil } - ai := m.msg.Args - for ai.Next() { - m.args[ai.Arg.Name] = ai.Arg.Value - if ai.Arg.Name == name { - return ai.Arg.Value, nil - } - } - return nil, &ArgNotFoundError{name} } @@ -85,17 +89,17 @@ func (m *message) getByteArrayArg(name string) ([]byte, error) { return val, nil } -func (m *message) getIpArg(name string) (net.IP, error) { +func (m *message) getIpArg(name string) (netip.Addr, error) { argVal, err := m.findArg(name) if err != nil { - return nil, err + return netip.Addr{}, err } if argVal == nil { - return nil, nil + return netip.Addr{}, nil } - val, ok := argVal.(net.IP) + val, ok := argVal.(netip.Addr) if !ok { - return nil, &typeMismatchError{name, "net.IP", argVal} + return netip.Addr{}, &typeMismatchError{name, "netip.Addr", argVal} } return val, nil } @@ -111,7 +115,7 @@ func (e *ArgNotFoundError) Error() string { type typeMismatchError struct { key string expectedType string - actualValue interface{} + actualValue any } func (e *typeMismatchError) Error() string { diff --git a/internal/request.go b/internal/request.go index d4b91fd..7f3d26a 100644 --- a/internal/request.go +++ b/internal/request.go @@ -5,18 +5,18 @@ package internal import ( "fmt" - "net" + "net/netip" - spoe "github.com/criteo/haproxy-spoe-go" + "github.com/dropmorepackets/haproxy-go/pkg/encoding" ) type request struct { msg *message app string id string - srcIp net.IP + srcIp netip.Addr srcPort int - dstIp net.IP + dstIp netip.Addr dstPort int method string path string @@ -26,7 +26,7 @@ type request struct { body []byte } -func NewRequest(spoeMsg *spoe.Message) (*request, error) { +func NewRequest(spoeMsg *encoding.Message) (*request, error) { msg, err := NewMessage(spoeMsg) if err != nil { return nil, err diff --git a/internal/response.go b/internal/response.go index 79dc162..af8839a 100644 --- a/internal/response.go +++ b/internal/response.go @@ -6,7 +6,7 @@ package internal import ( "fmt" - spoe "github.com/criteo/haproxy-spoe-go" + "github.com/dropmorepackets/haproxy-go/pkg/encoding" ) type response struct { @@ -19,7 +19,7 @@ type response struct { body []byte } -func NewResponse(spoeMsg *spoe.Message) (*response, error) { +func NewResponse(spoeMsg *encoding.Message) (*response, error) { msg, err := NewMessage(spoeMsg) if err != nil { return nil, err diff --git a/internal/spoa.go b/internal/spoa.go index d2a7f37..2455f61 100644 --- a/internal/spoa.go +++ b/internal/spoa.go @@ -4,6 +4,7 @@ package internal import ( + "context" "fmt" "net/http" "os" @@ -11,12 +12,14 @@ import ( "time" "github.com/bluele/gcache" - "github.com/corazawaf/coraza-spoa/config" "github.com/corazawaf/coraza/v3" "github.com/corazawaf/coraza/v3/types" - spoe "github.com/criteo/haproxy-spoe-go" + "github.com/dropmorepackets/haproxy-go/pkg/encoding" + "github.com/dropmorepackets/haproxy-go/spop" "go.uber.org/zap" "go.uber.org/zap/zapcore" + + "github.com/corazawaf/coraza-spoa/config" ) // TODO - in coraza v3 ErrorLogCallback is currently in the internal package @@ -36,64 +39,43 @@ type SPOA struct { defaultApplication string } +func (s *SPOA) HandleSPOE(_ context.Context, w *encoding.ActionWriter, m *encoding.Message) { + var err error + switch string(m.NameBytes()) { + case "coraza-req": + err = s.processRequest(w, m) + case "coraza-res": + err = s.processResponse(w, m) + } + if err != nil { + s.applications[s.defaultApplication].logger.Error("HandleSPOE", zap.Error(err)) + } +} + // Start starts the SPOA to detect the security risks. func (s *SPOA) Start(bind string) error { // s.logger.Info("Starting SPOA") - agent := spoe.New(func(messages *spoe.MessageIterator) ([]spoe.Action, error) { - for messages.Next() { - msg := messages.Message - - switch msg.Name { - case "coraza-req": - return s.processRequest(&msg) - case "coraza-res": - return s.processResponse(&msg) - } - } - return nil, nil - }) defer s.cleanApplications() - if err := agent.ListenAndServe(bind); err != nil { - return err - } - return nil + return spop.ListenAndServe(bind, s) } -func (s *SPOA) processInterruption(it *types.Interruption) []spoe.Action { - return []spoe.Action{ - spoe.ActionSetVar{ - Name: "status", - Scope: spoe.VarScopeTransaction, - Value: it.Status, - }, - spoe.ActionSetVar{ - Name: "action", - Scope: spoe.VarScopeTransaction, - Value: it.Action, - }, - spoe.ActionSetVar{ - Name: "data", - Scope: spoe.VarScopeTransaction, - Value: it.Data, - }, - spoe.ActionSetVar{ - Name: "ruleid", - Scope: spoe.VarScopeTransaction, - Value: it.RuleID, - }, +func (s *SPOA) processInterruption(w *encoding.ActionWriter, it *types.Interruption) error { + if err := w.SetInt64(encoding.VarScopeTransaction, "status", int64(it.Status)); err != nil { + return err + } + if err := w.SetString(encoding.VarScopeTransaction, "action", it.Action); err != nil { + return err } + if err := w.SetString(encoding.VarScopeTransaction, "data", it.Data); err != nil { + return err + } + + return w.SetInt64(encoding.VarScopeTransaction, "ruleid", int64(it.RuleID)) } -func (s *SPOA) allowAction() []spoe.Action { - act := []spoe.Action{ - spoe.ActionSetVar{ - Name: "action", - Scope: spoe.VarScopeTransaction, - Value: "allow", - }, - } - return act +func (s *SPOA) allowAction(w *encoding.ActionWriter) error { + return w.SetString(encoding.VarScopeTransaction, "action", "allow") } func (s *SPOA) readHeaders(headers string) (http.Header, error) { @@ -238,7 +220,7 @@ func (s *SPOA) getApplication(appName string) (*application, error) { return nil, fmt.Errorf("application not found, application %s, default: %s", appName, s.defaultApplication) } -func (s *SPOA) processRequest(spoeMsg *spoe.Message) ([]spoe.Action, error) { +func (s *SPOA) processRequest(w *encoding.ActionWriter, m *encoding.Message) error { var ( err error req *request @@ -266,30 +248,30 @@ func (s *SPOA) processRequest(spoeMsg *spoe.Message) ([]spoe.Action, error) { } }() - req, err = NewRequest(spoeMsg) + req, err = NewRequest(m) if err != nil { - return nil, err + return err } app, err = s.getApplication(req.app) if err != nil { - return nil, err + return err } tx = app.waf.NewTransactionWithID(req.id) if tx.IsRuleEngineOff() { app.logger.Warn("Rule engine is Off, Coraza is not going to process any rule") - return s.allowAction(), nil + return s.allowAction(w) } err = req.init() if err != nil { - return nil, err + return err } headers, err := s.readHeaders(req.headers) if err != nil { - return nil, err + return err } for key, values := range headers { for _, v := range values { @@ -299,10 +281,10 @@ func (s *SPOA) processRequest(spoeMsg *spoe.Message) ([]spoe.Action, error) { it, _, err := tx.WriteRequestBody(req.body) if err != nil { - return nil, err + return err } if it != nil { - return s.processInterruption(it), nil + return s.processInterruption(w, it) } tx.ProcessConnection(req.srcIp.String(), req.srcPort, req.dstIp.String(), req.dstPort) @@ -310,21 +292,21 @@ func (s *SPOA) processRequest(spoeMsg *spoe.Message) ([]spoe.Action, error) { it = tx.ProcessRequestHeaders() if it != nil { - return s.processInterruption(it), nil + return s.processInterruption(w, it) } it, err = tx.ProcessRequestBody() if err != nil { - return nil, err + return err } if it != nil { - return s.processInterruption(it), nil + return s.processInterruption(w, it) } - return s.allowAction(), nil + return s.allowAction(w) } -func (s *SPOA) processResponse(spoeMsg *spoe.Message) ([]spoe.Action, error) { +func (s *SPOA) processResponse(w *encoding.ActionWriter, m *encoding.Message) error { var ( err error resp *response @@ -335,33 +317,33 @@ func (s *SPOA) processResponse(spoeMsg *spoe.Message) ([]spoe.Action, error) { app.cache.Remove(resp.id) }() - resp, err = NewResponse(spoeMsg) + resp, err = NewResponse(m) if err != nil { - return nil, err + return err } app, err = s.getApplication(resp.app) if err != nil { - return nil, err + return err } txInterface, err := app.cache.Get(resp.id) if err != nil { - return nil, fmt.Errorf("failed to get transaction from cache, transaction_id: %s, app: %s, error: %s", resp.id, app.name, err.Error()) + return fmt.Errorf("failed to get transaction from cache, transaction_id: %s, app: %s, error: %s", resp.id, app.name, err.Error()) } tx, ok := txInterface.(types.Transaction) if !ok { - return nil, fmt.Errorf("application cache is corrupted, transaction_id: %s, app: %s", resp.id, app.name) + return fmt.Errorf("application cache is corrupted, transaction_id: %s, app: %s", resp.id, app.name) } err = resp.init() if err != nil { - return nil, err + return err } headers, err := s.readHeaders(resp.headers) if err != nil { - return nil, err + return err } for key, values := range headers { for _, v := range values { @@ -371,24 +353,24 @@ func (s *SPOA) processResponse(spoeMsg *spoe.Message) ([]spoe.Action, error) { it, _, err := tx.WriteResponseBody(resp.body) if err != nil { - return nil, err + return err } if it != nil { - return s.processInterruption(it), nil + return s.processInterruption(w, it) } it = tx.ProcessResponseHeaders(resp.status, "HTTP/"+resp.version) if it != nil { - return s.processInterruption(it), nil + return s.processInterruption(w, it) } it, err = tx.ProcessResponseBody() if err != nil { - return nil, err + return err } if it != nil { - return s.processInterruption(it), nil + return s.processInterruption(w, it) } - return s.allowAction(), nil + return s.allowAction(w) }