From 4c263cd011b41bf7f4735b8e5ffb6c4f6d1103df Mon Sep 17 00:00:00 2001 From: sada-sigsci Date: Fri, 8 Nov 2024 10:00:48 -0800 Subject: [PATCH 1/5] Allow the agent to edit application response headers --- go.mod | 6 +- go.sum | 75 +++++++- module.go | 2 +- responsewriter.go | 39 +++- responsewriter_test.go | 33 +++- rpc.go | 20 ++- rpc_gen.go | 400 ++++++++++++++++++++++++++++++++++++----- 7 files changed, 508 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index 8f60d90..6c6c9df 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,8 @@ module github.com/signalsciences/sigsci-module-golang -go 1.13 +go 1.21 require ( github.com/signalsciences/tlstext v1.2.0 - github.com/tinylib/msgp v1.1.0 + github.com/tinylib/msgp v1.2.4 ) - -require github.com/philhofer/fwd v1.0.0 // indirect diff --git a/go.sum b/go.sum index 43d1d59..f166759 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,73 @@ -github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= +github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/signalsciences/tlstext v1.2.0 h1:ps1ZCoDz93oMK0ySe7G/2J0dpTT32cN20U+/xy0S7uk= github.com/signalsciences/tlstext v1.2.0/go.mod h1:DKD8bjL8ZiedHAgWtcpgZm6TBAnmAlImuyJX2whrm3k= -github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tinylib/msgp v1.2.4 h1:yLFeUGostXXSGW5vxfT5dXG/qzkn4schv2I7at5+hVU= +github.com/tinylib/msgp v1.2.4/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/module.go b/module.go index ac214c6..425480b 100644 --- a/module.go +++ b/module.go @@ -115,7 +115,7 @@ func (m *Module) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - rw := NewResponseWriter(w) + rw := NewResponseWriter(w, out.RespActions) wafresponse := out.WAFResponse switch { diff --git a/responsewriter.go b/responsewriter.go index b442d08..a6c51ed 100644 --- a/responsewriter.go +++ b/responsewriter.go @@ -23,13 +23,14 @@ type ResponseWriterFlusher interface { } // NewResponseWriter returns a ResponseWriter or ResponseWriterFlusher depending on the base http.ResponseWriter. -func NewResponseWriter(base http.ResponseWriter) ResponseWriter { +func NewResponseWriter(base http.ResponseWriter, actions []Action) ResponseWriter { // NOTE: according to net/http docs, if WriteHeader is not called explicitly, // the first call to Write will trigger an implicit WriteHeader(http.StatusOK). // this is why the default code is 200 and it only changes if WriteHeader is called. w := &responseRecorder{ - base: base, - code: 200, + base: base, + code: 200, + actions: actions, } if _, ok := w.base.(http.Flusher); ok { return &responseRecorderFlusher{w} @@ -39,9 +40,10 @@ func NewResponseWriter(base http.ResponseWriter) ResponseWriter { // responseRecorder wraps a base http.ResponseWriter allowing extraction of additional inspection data type responseRecorder struct { - base http.ResponseWriter - code int - size int64 + base http.ResponseWriter + code int + size int64 + actions []Action } // BaseResponseWriter returns the base http.ResponseWriter allowing access if needed @@ -66,12 +68,37 @@ func (w *responseRecorder) Header() http.Header { // WriteHeader writes the header, recording the status code for inspection func (w *responseRecorder) WriteHeader(status int) { + if w.actions != nil { + w.mergeHeader() + } w.code = status w.base.WriteHeader(status) } +func (w *responseRecorder) mergeHeader() { + hdr := w.base.Header() + for _, a := range w.actions { + switch a.Code { + case AddHdr: + hdr.Add(a.Args[0], a.Args[1]) + case SetHdr: + hdr.Set(a.Args[0], a.Args[1]) + case SetNEHdr: + if len(hdr.Get(a.Args[0])) == 0 { + hdr.Set(a.Args[0], a.Args[1]) + } + case DelHdr: + hdr.Del(a.Args[0]) + } + } + w.actions = nil +} + // Write writes data, tracking the length written for inspection func (w *responseRecorder) Write(b []byte) (int, error) { + if w.actions != nil { + w.mergeHeader() + } w.size += int64(len(b)) return w.base.Write(b) } diff --git a/responsewriter_test.go b/responsewriter_test.go index 8543f95..1f01bfc 100644 --- a/responsewriter_test.go +++ b/responsewriter_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "reflect" "testing" ) @@ -116,10 +117,38 @@ func testResponseWriter(t *testing.T, w ResponseWriter, flusher bool) { // TestResponseWriter tests a non-flusher ResponseWriter func TestResponseWriter(t *testing.T) { - testResponseWriter(t, NewResponseWriter(&testResponseRecorder{httptest.NewRecorder()}), false) + testResponseWriter(t, NewResponseWriter(&testResponseRecorder{httptest.NewRecorder()}, nil), false) } // TestResponseWriterFlusher tests a flusher ResponseWriter func TestResponseWriterFlusher(t *testing.T) { - testResponseWriter(t, NewResponseWriter(&testResponseRecorderFlusher{httptest.NewRecorder()}), true) + testResponseWriter(t, NewResponseWriter(&testResponseRecorderFlusher{httptest.NewRecorder()}, nil), true) +} + +func TestResponseHeaders(t *testing.T) { + + resp := &httptest.ResponseRecorder{ + HeaderMap: http.Header{ + "X-Powered-By": []string{"aa"}, + "Content-Type": []string{"text/plain"}, + "X-Report": []string{"bb"}, + }, + } + actions := []Action{ + {AddHdr, []string{"csp", "src=abc"}}, + {SetHdr, []string{"content-type", "text/json"}}, + {DelHdr, []string{"x-powered-by"}}, + {SetNEHdr, []string{"x-report", "cc"}}, + } + NewResponseWriter(resp, actions).Write([]byte("foo")) + + got := resp.Header() + expected := http.Header{ + "Csp": []string{"src=abc"}, + "Content-Type": []string{"text/json"}, + "X-Report": []string{"bb"}, + } + if !reflect.DeepEqual(got, expected) { + t.Fatalf("expected %v, got %v", expected, got) + } } diff --git a/rpc.go b/rpc.go index 0fd74db..b7e0e23 100644 --- a/rpc.go +++ b/rpc.go @@ -1,6 +1,6 @@ package sigsci -//go:generate msgp -unexported -tests=false +//go:generate go run github.com/tinylib/msgp@v1.2.4 -unexported -tests=false // // This is for messages to and from the agent @@ -34,8 +34,22 @@ type RPCMsgIn struct { // RPCMsgOut is sent back to the webserver type RPCMsgOut struct { WAFResponse int32 - RequestID string `json:",omitempty"` // Set if the server expects an UpdateRequest with this ID (UUID) - RequestHeaders [][2]string `json:",omitempty"` // Any additional information in the form of additional request headers + RequestID string `json:",omitempty"` // Set if the server expects an UpdateRequest with this ID (UUID) + RequestHeaders [][2]string `json:",omitempty"` // Any additional information in the form of additional request headers + RespActions []Action `json:",omitempty" msg:",omitempty"` // Add or Delete application response headers +} + +const ( + AddHdr int8 = iota + 1 + SetHdr + SetNEHdr + DelHdr +) + +//msgp:tuple Action +type Action struct { + Code int8 + Args []string } // RPCMsgIn2 is a follow-up message from the webserver to the Agent diff --git a/rpc_gen.go b/rpc_gen.go index d2e95dd..ced7e99 100644 --- a/rpc_gen.go +++ b/rpc_gen.go @@ -6,6 +6,132 @@ import ( "github.com/tinylib/msgp/msgp" ) +// DecodeMsg implements msgp.Decodable +func (z *Action) DecodeMsg(dc *msgp.Reader) (err error) { + var zb0001 uint32 + zb0001, err = dc.ReadArrayHeader() + if err != nil { + err = msgp.WrapError(err) + return + } + if zb0001 != 2 { + err = msgp.ArrayError{Wanted: 2, Got: zb0001} + return + } + z.Code, err = dc.ReadInt8() + if err != nil { + err = msgp.WrapError(err, "Code") + return + } + var zb0002 uint32 + zb0002, err = dc.ReadArrayHeader() + if err != nil { + err = msgp.WrapError(err, "Args") + return + } + if cap(z.Args) >= int(zb0002) { + z.Args = (z.Args)[:zb0002] + } else { + z.Args = make([]string, zb0002) + } + for za0001 := range z.Args { + z.Args[za0001], err = dc.ReadString() + if err != nil { + err = msgp.WrapError(err, "Args", za0001) + return + } + } + return +} + +// EncodeMsg implements msgp.Encodable +func (z *Action) EncodeMsg(en *msgp.Writer) (err error) { + // array header, size 2 + err = en.Append(0x92) + if err != nil { + return + } + err = en.WriteInt8(z.Code) + if err != nil { + err = msgp.WrapError(err, "Code") + return + } + err = en.WriteArrayHeader(uint32(len(z.Args))) + if err != nil { + err = msgp.WrapError(err, "Args") + return + } + for za0001 := range z.Args { + err = en.WriteString(z.Args[za0001]) + if err != nil { + err = msgp.WrapError(err, "Args", za0001) + return + } + } + return +} + +// MarshalMsg implements msgp.Marshaler +func (z *Action) MarshalMsg(b []byte) (o []byte, err error) { + o = msgp.Require(b, z.Msgsize()) + // array header, size 2 + o = append(o, 0x92) + o = msgp.AppendInt8(o, z.Code) + o = msgp.AppendArrayHeader(o, uint32(len(z.Args))) + for za0001 := range z.Args { + o = msgp.AppendString(o, z.Args[za0001]) + } + return +} + +// UnmarshalMsg implements msgp.Unmarshaler +func (z *Action) UnmarshalMsg(bts []byte) (o []byte, err error) { + var zb0001 uint32 + zb0001, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err) + return + } + if zb0001 != 2 { + err = msgp.ArrayError{Wanted: 2, Got: zb0001} + return + } + z.Code, bts, err = msgp.ReadInt8Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "Code") + return + } + var zb0002 uint32 + zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "Args") + return + } + if cap(z.Args) >= int(zb0002) { + z.Args = (z.Args)[:zb0002] + } else { + z.Args = make([]string, zb0002) + } + for za0001 := range z.Args { + z.Args[za0001], bts, err = msgp.ReadStringBytes(bts) + if err != nil { + err = msgp.WrapError(err, "Args", za0001) + return + } + } + o = bts + return +} + +// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message +func (z *Action) Msgsize() (s int) { + s = 1 + msgp.Int8Size + msgp.ArrayHeaderSize + for za0001 := range z.Args { + s += msgp.StringPrefixSize + len(z.Args[za0001]) + } + return +} + // DecodeMsg implements msgp.Decodable func (z *RPCMsgIn) DecodeMsg(dc *msgp.Reader) (err error) { var field []byte @@ -1103,6 +1229,53 @@ func (z *RPCMsgOut) DecodeMsg(dc *msgp.Reader) (err error) { } } } + case "RespActions": + var zb0004 uint32 + zb0004, err = dc.ReadArrayHeader() + if err != nil { + err = msgp.WrapError(err, "RespActions") + return + } + if cap(z.RespActions) >= int(zb0004) { + z.RespActions = (z.RespActions)[:zb0004] + } else { + z.RespActions = make([]Action, zb0004) + } + for za0003 := range z.RespActions { + var zb0005 uint32 + zb0005, err = dc.ReadArrayHeader() + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003) + return + } + if zb0005 != 2 { + err = msgp.ArrayError{Wanted: 2, Got: zb0005} + return + } + z.RespActions[za0003].Code, err = dc.ReadInt8() + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Code") + return + } + var zb0006 uint32 + zb0006, err = dc.ReadArrayHeader() + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Args") + return + } + if cap(z.RespActions[za0003].Args) >= int(zb0006) { + z.RespActions[za0003].Args = (z.RespActions[za0003].Args)[:zb0006] + } else { + z.RespActions[za0003].Args = make([]string, zb0006) + } + for za0004 := range z.RespActions[za0003].Args { + z.RespActions[za0003].Args[za0004], err = dc.ReadString() + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Args", za0004) + return + } + } + } default: err = dc.Skip() if err != nil { @@ -1116,49 +1289,101 @@ func (z *RPCMsgOut) DecodeMsg(dc *msgp.Reader) (err error) { // EncodeMsg implements msgp.Encodable func (z *RPCMsgOut) EncodeMsg(en *msgp.Writer) (err error) { - // map header, size 3 - // write "WAFResponse" - err = en.Append(0x83, 0xab, 0x57, 0x41, 0x46, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65) - if err != nil { - return + // check for omitted fields + zb0001Len := uint32(4) + var zb0001Mask uint8 /* 4 bits */ + _ = zb0001Mask + if z.RespActions == nil { + zb0001Len-- + zb0001Mask |= 0x8 } - err = en.WriteInt32(z.WAFResponse) - if err != nil { - err = msgp.WrapError(err, "WAFResponse") - return - } - // write "RequestID" - err = en.Append(0xa9, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44) - if err != nil { - return - } - err = en.WriteString(z.RequestID) - if err != nil { - err = msgp.WrapError(err, "RequestID") - return - } - // write "RequestHeaders" - err = en.Append(0xae, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73) - if err != nil { - return - } - err = en.WriteArrayHeader(uint32(len(z.RequestHeaders))) + // variable map header, size zb0001Len + err = en.Append(0x80 | uint8(zb0001Len)) if err != nil { - err = msgp.WrapError(err, "RequestHeaders") return } - for za0001 := range z.RequestHeaders { - err = en.WriteArrayHeader(uint32(2)) + + // skip if no fields are to be emitted + if zb0001Len != 0 { + // write "WAFResponse" + err = en.Append(0xab, 0x57, 0x41, 0x46, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65) if err != nil { - err = msgp.WrapError(err, "RequestHeaders", za0001) return } - for za0002 := range z.RequestHeaders[za0001] { - err = en.WriteString(z.RequestHeaders[za0001][za0002]) + err = en.WriteInt32(z.WAFResponse) + if err != nil { + err = msgp.WrapError(err, "WAFResponse") + return + } + // write "RequestID" + err = en.Append(0xa9, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44) + if err != nil { + return + } + err = en.WriteString(z.RequestID) + if err != nil { + err = msgp.WrapError(err, "RequestID") + return + } + // write "RequestHeaders" + err = en.Append(0xae, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73) + if err != nil { + return + } + err = en.WriteArrayHeader(uint32(len(z.RequestHeaders))) + if err != nil { + err = msgp.WrapError(err, "RequestHeaders") + return + } + for za0001 := range z.RequestHeaders { + err = en.WriteArrayHeader(uint32(2)) if err != nil { - err = msgp.WrapError(err, "RequestHeaders", za0001, za0002) + err = msgp.WrapError(err, "RequestHeaders", za0001) return } + for za0002 := range z.RequestHeaders[za0001] { + err = en.WriteString(z.RequestHeaders[za0001][za0002]) + if err != nil { + err = msgp.WrapError(err, "RequestHeaders", za0001, za0002) + return + } + } + } + if (zb0001Mask & 0x8) == 0 { // if not omitted + // write "RespActions" + err = en.Append(0xab, 0x52, 0x65, 0x73, 0x70, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73) + if err != nil { + return + } + err = en.WriteArrayHeader(uint32(len(z.RespActions))) + if err != nil { + err = msgp.WrapError(err, "RespActions") + return + } + for za0003 := range z.RespActions { + // array header, size 2 + err = en.Append(0x92) + if err != nil { + return + } + err = en.WriteInt8(z.RespActions[za0003].Code) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Code") + return + } + err = en.WriteArrayHeader(uint32(len(z.RespActions[za0003].Args))) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Args") + return + } + for za0004 := range z.RespActions[za0003].Args { + err = en.WriteString(z.RespActions[za0003].Args[za0004]) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Args", za0004) + return + } + } + } } } return @@ -1167,20 +1392,47 @@ func (z *RPCMsgOut) EncodeMsg(en *msgp.Writer) (err error) { // MarshalMsg implements msgp.Marshaler func (z *RPCMsgOut) MarshalMsg(b []byte) (o []byte, err error) { o = msgp.Require(b, z.Msgsize()) - // map header, size 3 - // string "WAFResponse" - o = append(o, 0x83, 0xab, 0x57, 0x41, 0x46, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65) - o = msgp.AppendInt32(o, z.WAFResponse) - // string "RequestID" - o = append(o, 0xa9, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44) - o = msgp.AppendString(o, z.RequestID) - // string "RequestHeaders" - o = append(o, 0xae, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.RequestHeaders))) - for za0001 := range z.RequestHeaders { - o = msgp.AppendArrayHeader(o, uint32(2)) - for za0002 := range z.RequestHeaders[za0001] { - o = msgp.AppendString(o, z.RequestHeaders[za0001][za0002]) + // check for omitted fields + zb0001Len := uint32(4) + var zb0001Mask uint8 /* 4 bits */ + _ = zb0001Mask + if z.RespActions == nil { + zb0001Len-- + zb0001Mask |= 0x8 + } + // variable map header, size zb0001Len + o = append(o, 0x80|uint8(zb0001Len)) + + // skip if no fields are to be emitted + if zb0001Len != 0 { + // string "WAFResponse" + o = append(o, 0xab, 0x57, 0x41, 0x46, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65) + o = msgp.AppendInt32(o, z.WAFResponse) + // string "RequestID" + o = append(o, 0xa9, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x44) + o = msgp.AppendString(o, z.RequestID) + // string "RequestHeaders" + o = append(o, 0xae, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73) + o = msgp.AppendArrayHeader(o, uint32(len(z.RequestHeaders))) + for za0001 := range z.RequestHeaders { + o = msgp.AppendArrayHeader(o, uint32(2)) + for za0002 := range z.RequestHeaders[za0001] { + o = msgp.AppendString(o, z.RequestHeaders[za0001][za0002]) + } + } + if (zb0001Mask & 0x8) == 0 { // if not omitted + // string "RespActions" + o = append(o, 0xab, 0x52, 0x65, 0x73, 0x70, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73) + o = msgp.AppendArrayHeader(o, uint32(len(z.RespActions))) + for za0003 := range z.RespActions { + // array header, size 2 + o = append(o, 0x92) + o = msgp.AppendInt8(o, z.RespActions[za0003].Code) + o = msgp.AppendArrayHeader(o, uint32(len(z.RespActions[za0003].Args))) + for za0004 := range z.RespActions[za0003].Args { + o = msgp.AppendString(o, z.RespActions[za0003].Args[za0004]) + } + } } } return @@ -1247,6 +1499,53 @@ func (z *RPCMsgOut) UnmarshalMsg(bts []byte) (o []byte, err error) { } } } + case "RespActions": + var zb0004 uint32 + zb0004, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "RespActions") + return + } + if cap(z.RespActions) >= int(zb0004) { + z.RespActions = (z.RespActions)[:zb0004] + } else { + z.RespActions = make([]Action, zb0004) + } + for za0003 := range z.RespActions { + var zb0005 uint32 + zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003) + return + } + if zb0005 != 2 { + err = msgp.ArrayError{Wanted: 2, Got: zb0005} + return + } + z.RespActions[za0003].Code, bts, err = msgp.ReadInt8Bytes(bts) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Code") + return + } + var zb0006 uint32 + zb0006, bts, err = msgp.ReadArrayHeaderBytes(bts) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Args") + return + } + if cap(z.RespActions[za0003].Args) >= int(zb0006) { + z.RespActions[za0003].Args = (z.RespActions[za0003].Args)[:zb0006] + } else { + z.RespActions[za0003].Args = make([]string, zb0006) + } + for za0004 := range z.RespActions[za0003].Args { + z.RespActions[za0003].Args[za0004], bts, err = msgp.ReadStringBytes(bts) + if err != nil { + err = msgp.WrapError(err, "RespActions", za0003, "Args", za0004) + return + } + } + } default: bts, err = msgp.Skip(bts) if err != nil { @@ -1268,5 +1567,12 @@ func (z *RPCMsgOut) Msgsize() (s int) { s += msgp.StringPrefixSize + len(z.RequestHeaders[za0001][za0002]) } } + s += 12 + msgp.ArrayHeaderSize + for za0003 := range z.RespActions { + s += 1 + msgp.Int8Size + msgp.ArrayHeaderSize + for za0004 := range z.RespActions[za0003].Args { + s += msgp.StringPrefixSize + len(z.RespActions[za0003].Args[za0004]) + } + } return } From fafb5456dc7f22016b65f00910f9f764ad652ad3 Mon Sep 17 00:00:00 2001 From: sada-sigsci Date: Fri, 8 Nov 2024 10:38:24 -0800 Subject: [PATCH 2/5] run mod tidy --- go.mod | 2 ++ go.sum | 67 ---------------------------------------------------------- 2 files changed, 2 insertions(+), 67 deletions(-) diff --git a/go.mod b/go.mod index 6c6c9df..e9ae513 100644 --- a/go.mod +++ b/go.mod @@ -6,3 +6,5 @@ require ( github.com/signalsciences/tlstext v1.2.0 github.com/tinylib/msgp v1.2.4 ) + +require github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect diff --git a/go.sum b/go.sum index f166759..4e64735 100644 --- a/go.sum +++ b/go.sum @@ -1,73 +1,6 @@ -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY= github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/signalsciences/tlstext v1.2.0 h1:ps1ZCoDz93oMK0ySe7G/2J0dpTT32cN20U+/xy0S7uk= github.com/signalsciences/tlstext v1.2.0/go.mod h1:DKD8bjL8ZiedHAgWtcpgZm6TBAnmAlImuyJX2whrm3k= github.com/tinylib/msgp v1.2.4 h1:yLFeUGostXXSGW5vxfT5dXG/qzkn4schv2I7at5+hVU= github.com/tinylib/msgp v1.2.4/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 932a76fe02cd3b5eaf24f3c6a660c455a6423a29 Mon Sep 17 00:00:00 2001 From: sada-sigsci Date: Fri, 8 Nov 2024 11:11:59 -0800 Subject: [PATCH 3/5] updated version --- CHANGELOG.md | 4 ++++ VERSION | 2 +- version.go | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de58475..af80c22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Golang Module Release Notes +## 1.14.0 2024-11-08 + +* Allow the agent to edit application response headers + ## 1.13.0 2023-07-06 * Added new module configuration option for more granular inspection diff --git a/VERSION b/VERSION index feaae22..850e742 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.13.0 +1.14.0 diff --git a/version.go b/version.go index bc6f60f..cc99581 100644 --- a/version.go +++ b/version.go @@ -1,3 +1,3 @@ package sigsci -const version = "1.13.0" +const version = "1.14.0" From d4fb21b6978425642751f2b082bb55c895bc7349 Mon Sep 17 00:00:00 2001 From: sada-sigsci Date: Wed, 13 Nov 2024 16:58:13 -0800 Subject: [PATCH 4/5] address review comments --- module.go | 7 ++++++- responsewriter.go | 18 ++++++++++++------ responsewriter_test.go | 18 ++++++++++-------- rpc.go => schema/rpc.go | 2 +- rpc_gen.go => schema/rpc_gen.go | 2 +- scripts/build.sh | 4 ++-- 6 files changed, 32 insertions(+), 19 deletions(-) rename rpc.go => schema/rpc.go (99%) rename rpc_gen.go => schema/rpc_gen.go (99%) diff --git a/module.go b/module.go index 425480b..84f7b10 100644 --- a/module.go +++ b/module.go @@ -12,9 +12,14 @@ import ( "sync" "time" + "github.com/signalsciences/sigsci-module-golang/schema" "github.com/signalsciences/tlstext" ) +type RPCMsgIn = schema.RPCMsgIn +type RPCMsgIn2 = schema.RPCMsgIn2 +type RPCMsgOut = schema.RPCMsgOut + // Module is an http.Handler that wraps an existing handler with // data collection and sends it to the Signal Sciences Agent for // inspection. @@ -115,7 +120,7 @@ func (m *Module) ServeHTTP(w http.ResponseWriter, req *http.Request) { return } - rw := NewResponseWriter(w, out.RespActions) + rw := newResponseWriter(w, out.RespActions) wafresponse := out.WAFResponse switch { diff --git a/responsewriter.go b/responsewriter.go index a6c51ed..761a7c4 100644 --- a/responsewriter.go +++ b/responsewriter.go @@ -6,6 +6,8 @@ import ( "io" "net" "net/http" + + "github.com/signalsciences/sigsci-module-golang/schema" ) // ResponseWriter is a http.ResponseWriter allowing extraction of data needed for inspection @@ -23,7 +25,11 @@ type ResponseWriterFlusher interface { } // NewResponseWriter returns a ResponseWriter or ResponseWriterFlusher depending on the base http.ResponseWriter. -func NewResponseWriter(base http.ResponseWriter, actions []Action) ResponseWriter { +func NewResponseWriter(base http.ResponseWriter) ResponseWriter { + return newResponseWriter(base, nil) +} + +func newResponseWriter(base http.ResponseWriter, actions []schema.Action) ResponseWriter { // NOTE: according to net/http docs, if WriteHeader is not called explicitly, // the first call to Write will trigger an implicit WriteHeader(http.StatusOK). // this is why the default code is 200 and it only changes if WriteHeader is called. @@ -43,7 +49,7 @@ type responseRecorder struct { base http.ResponseWriter code int size int64 - actions []Action + actions []schema.Action } // BaseResponseWriter returns the base http.ResponseWriter allowing access if needed @@ -79,15 +85,15 @@ func (w *responseRecorder) mergeHeader() { hdr := w.base.Header() for _, a := range w.actions { switch a.Code { - case AddHdr: + case schema.AddHdr: hdr.Add(a.Args[0], a.Args[1]) - case SetHdr: + case schema.SetHdr: hdr.Set(a.Args[0], a.Args[1]) - case SetNEHdr: + case schema.SetNEHdr: if len(hdr.Get(a.Args[0])) == 0 { hdr.Set(a.Args[0], a.Args[1]) } - case DelHdr: + case schema.DelHdr: hdr.Del(a.Args[0]) } } diff --git a/responsewriter_test.go b/responsewriter_test.go index 1f01bfc..e56f768 100644 --- a/responsewriter_test.go +++ b/responsewriter_test.go @@ -8,6 +8,8 @@ import ( "net/http/httptest" "reflect" "testing" + + "github.com/signalsciences/sigsci-module-golang/schema" ) // testResponseRecorder is a httptest.ResponseRecorder without the Flusher interface @@ -117,12 +119,12 @@ func testResponseWriter(t *testing.T, w ResponseWriter, flusher bool) { // TestResponseWriter tests a non-flusher ResponseWriter func TestResponseWriter(t *testing.T) { - testResponseWriter(t, NewResponseWriter(&testResponseRecorder{httptest.NewRecorder()}, nil), false) + testResponseWriter(t, NewResponseWriter(&testResponseRecorder{httptest.NewRecorder()}), false) } // TestResponseWriterFlusher tests a flusher ResponseWriter func TestResponseWriterFlusher(t *testing.T) { - testResponseWriter(t, NewResponseWriter(&testResponseRecorderFlusher{httptest.NewRecorder()}, nil), true) + testResponseWriter(t, NewResponseWriter(&testResponseRecorderFlusher{httptest.NewRecorder()}), true) } func TestResponseHeaders(t *testing.T) { @@ -134,13 +136,13 @@ func TestResponseHeaders(t *testing.T) { "X-Report": []string{"bb"}, }, } - actions := []Action{ - {AddHdr, []string{"csp", "src=abc"}}, - {SetHdr, []string{"content-type", "text/json"}}, - {DelHdr, []string{"x-powered-by"}}, - {SetNEHdr, []string{"x-report", "cc"}}, + actions := []schema.Action{ + {schema.AddHdr, []string{"csp", "src=abc"}}, + {schema.SetHdr, []string{"content-type", "text/json"}}, + {schema.DelHdr, []string{"x-powered-by"}}, + {schema.SetNEHdr, []string{"x-report", "cc"}}, } - NewResponseWriter(resp, actions).Write([]byte("foo")) + newResponseWriter(resp, actions).Write([]byte("foo")) got := resp.Header() expected := http.Header{ diff --git a/rpc.go b/schema/rpc.go similarity index 99% rename from rpc.go rename to schema/rpc.go index b7e0e23..49cb0a4 100644 --- a/rpc.go +++ b/schema/rpc.go @@ -1,4 +1,4 @@ -package sigsci +package schema //go:generate go run github.com/tinylib/msgp@v1.2.4 -unexported -tests=false diff --git a/rpc_gen.go b/schema/rpc_gen.go similarity index 99% rename from rpc_gen.go rename to schema/rpc_gen.go index ced7e99..9ff9705 100644 --- a/rpc_gen.go +++ b/schema/rpc_gen.go @@ -1,4 +1,4 @@ -package sigsci +package schema // Code generated by github.com/tinylib/msgp DO NOT EDIT. diff --git a/scripts/build.sh b/scripts/build.sh index c49fcb6..76d2d53 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -30,9 +30,9 @@ go test . rm -rf artifacts/ mkdir -p artifacts/sigsci-module-golang -cp -rf \ +cp --parents -rf \ VERSION CHANGELOG.md LICENSE.md README.md \ - clientcodec.go rpc.go rpc_gen.go rpcinspector.go inspector.go responsewriter.go module.go version.go config.go \ + clientcodec.go schema/rpc.go schema/rpc_gen.go rpcinspector.go inspector.go responsewriter.go module.go version.go config.go \ responsewriter_test.go module_test.go config_test.go \ examples \ artifacts/sigsci-module-golang/ From b54cf723dc9b2718122b634efdd231b992e13f5f Mon Sep 17 00:00:00 2001 From: sada-sigsci Date: Mon, 18 Nov 2024 11:34:36 -0800 Subject: [PATCH 5/5] updated release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af80c22..f2f5c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Golang Module Release Notes -## 1.14.0 2024-11-08 +## 1.14.0 2024-11-18 * Allow the agent to edit application response headers