Skip to content

Commit

Permalink
Merge pull request #101 from acruikshank/bug/reusing_type_struct_in_d…
Browse files Browse the repository at this point in the history
…ecode_replicates_data_in_cli

Rezero struct between each decode
  • Loading branch information
Stebalien authored Apr 23, 2018
2 parents 6d7f4fc + aef8948 commit 66802ba
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
17 changes: 12 additions & 5 deletions http/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ipfs/go-ipfs-cmdkit"
"github.com/ipfs/go-ipfs-cmds"
"reflect"
)

var (
Expand Down Expand Up @@ -58,14 +59,20 @@ func (res *Response) RawNext() (interface{}, error) {
if res.dec == nil {
if res.rr == nil {
return nil, io.EOF
} else {
rr := res.rr
res.rr = nil
return rr, nil
}
rr := res.rr
res.rr = nil
return rr, nil
}

m := &cmds.MaybeError{Value: res.req.Command.Type}
var value interface{}
if valueType := reflect.TypeOf(res.req.Command.Type); valueType != nil {
if valueType.Kind() == reflect.Ptr {
valueType = valueType.Elem()
}
value = reflect.New(valueType).Interface()
}
m := &cmds.MaybeError{Value: value}
err := res.dec.Decode(m)

// last error was sent as value, now we get the same error from the headers. ignore and EOF!
Expand Down
81 changes: 81 additions & 0 deletions http/response_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package http

import (
"testing"

"github.com/ipfs/go-ipfs-cmds"
)

type testResponseType struct {
a int
b int
}

type testDecoder struct {
a *int
b *int
}

func (td *testDecoder) Decode(value interface{}) error {
me := value.(*cmds.MaybeError)
o := me.Value.(*testResponseType)

if td.a != nil {
o.a = *td.a
}

if td.b != nil {
o.b = *td.b
}

return nil
}

func TestRawNextDecodesIntoNewStruct(t *testing.T) {
a1 := 1
b1 := 2
testCommand := &cmds.Command{
Type: &testResponseType{},
}
decoder := &testDecoder{
a: &a1,
b: &b1,
}
r := &cmds.Request{
Command: testCommand,
}
response := &Response{
req: r,
dec: decoder,
}

v, err := response.RawNext()
if err != nil {
t.Fatal("error decoding response", err)
}

tv := v.(*testResponseType)
if tv.a != 1 {
t.Errorf("tv.a is %#v, expected 1", tv.a)
}
if tv.b != 2 {
t.Errorf("tv.b is %#v, expected 2", tv.b)
}

a2 := 3
decoder.a = &a2
decoder.b = nil

v2, err := response.RawNext()
if err != nil {
t.Fatal("error decoding response", err)
}

tv2 := v2.(*testResponseType)
if tv2.a != 3 {
t.Errorf("tv2.a is %#v, expected 3", tv2.a)
}
if tv2.b != 0 {
t.Errorf("tv.b is %#v, expected it to be reset to 0", tv2.b)
}
}

0 comments on commit 66802ba

Please sign in to comment.