diff --git a/CHANGELOG.md b/CHANGELOG.md index de58475..f2f5c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Golang Module Release Notes +## 1.14.0 2024-11-18 + +* 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/go.mod b/go.mod index 8f60d90..e9ae513 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ 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 +require github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect diff --git a/go.sum b/go.sum index 43d1d59..4e64735 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ -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/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= diff --git a/module.go b/module.go index ac214c6..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) + rw := newResponseWriter(w, out.RespActions) wafresponse := out.WAFResponse switch { diff --git a/responsewriter.go b/responsewriter.go index b442d08..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 @@ -24,12 +26,17 @@ type ResponseWriterFlusher interface { // NewResponseWriter returns a ResponseWriter or ResponseWriterFlusher depending on the base http.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. w := &responseRecorder{ - base: base, - code: 200, + base: base, + code: 200, + actions: actions, } if _, ok := w.base.(http.Flusher); ok { return &responseRecorderFlusher{w} @@ -39,9 +46,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 []schema.Action } // BaseResponseWriter returns the base http.ResponseWriter allowing access if needed @@ -66,12 +74,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 schema.AddHdr: + hdr.Add(a.Args[0], a.Args[1]) + case schema.SetHdr: + hdr.Set(a.Args[0], a.Args[1]) + case schema.SetNEHdr: + if len(hdr.Get(a.Args[0])) == 0 { + hdr.Set(a.Args[0], a.Args[1]) + } + case schema.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..e56f768 100644 --- a/responsewriter_test.go +++ b/responsewriter_test.go @@ -6,7 +6,10 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "reflect" "testing" + + "github.com/signalsciences/sigsci-module-golang/schema" ) // testResponseRecorder is a httptest.ResponseRecorder without the Flusher interface @@ -123,3 +126,31 @@ func TestResponseWriter(t *testing.T) { func TestResponseWriterFlusher(t *testing.T) { testResponseWriter(t, NewResponseWriter(&testResponseRecorderFlusher{httptest.NewRecorder()}), 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 := []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")) + + 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/schema/rpc.go similarity index 78% rename from rpc.go rename to schema/rpc.go index 0fd74db..49cb0a4 100644 --- a/rpc.go +++ b/schema/rpc.go @@ -1,6 +1,6 @@ -package sigsci +package schema -//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/schema/rpc_gen.go similarity index 77% rename from rpc_gen.go rename to schema/rpc_gen.go index d2e95dd..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. @@ -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 } 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/ 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"