Merge pull request #56 from fangyincheng/master
Imp: add response
diff --git a/hessian.go b/hessian.go
index 2b05bc8..ff39d92 100644
--- a/hessian.go
+++ b/hessian.go
@@ -94,10 +94,10 @@
var err error
- buf, err := h.reader.Peek(HEADER_LENGTH)
- if err == bufio.ErrBufferFull {
+ if h.reader.Size() < HEADER_LENGTH {
return ErrHeaderNotEnough
}
+ buf, err := h.reader.Peek(HEADER_LENGTH)
if err != nil { // this is impossible
return perrors.WithStack(err)
}
@@ -165,10 +165,10 @@
// ReadBody uses hessian codec to read response body
func (h *HessianCodec) ReadBody(rspObj interface{}) error {
- buf, err := h.reader.Peek(h.bodyLen)
- if err == bufio.ErrBufferFull {
- return ErrBodyNotEnough
+ if h.reader.Buffered() < h.bodyLen {
+ return ErrHeaderNotEnough
}
+ buf, err := h.reader.Peek(h.bodyLen)
if err != nil {
return perrors.WithStack(err)
}
@@ -191,7 +191,11 @@
case PackageResponse:
if rspObj != nil {
- if err = unpackResponseBody(buf, rspObj); err != nil {
+ rsp, ok := rspObj.(*Response)
+ if !ok {
+ break
+ }
+ if err = unpackResponseBody(buf, rsp); err != nil {
return perrors.WithStack(err)
}
}
diff --git a/hessian_test.go b/hessian_test.go
index b68c780..e9d62c0 100644
--- a/hessian_test.go
+++ b/hessian_test.go
@@ -55,7 +55,7 @@
return resp, err
}
-func doTestResponse(t *testing.T, packageType PackageType, responseStatus byte, body interface{}, decodedObject interface{}, assertFunc func()) {
+func doTestResponse(t *testing.T, packageType PackageType, responseStatus byte, body interface{}, decodedResponse *Response, assertFunc func()) {
resp, err := doTestHessianEncodeHeader(t, packageType, responseStatus, body)
codecR := NewHessianCodec(bufio.NewReader(bytes.NewReader(resp)))
@@ -74,9 +74,9 @@
assert.Equal(t, int64(1), h.ID)
assert.Equal(t, responseStatus, h.ResponseStatus)
- err = codecR.ReadBody(decodedObject)
+ err = codecR.ReadBody(decodedResponse)
assert.Nil(t, err)
- t.Log(decodedObject)
+ t.Log(decodedResponse)
if assertFunc != nil {
assertFunc()
@@ -84,38 +84,46 @@
}
in, _ := EnsureInterface(UnpackPtrValue(EnsurePackValue(body)), nil)
- out, _ := EnsureInterface(UnpackPtrValue(EnsurePackValue(decodedObject)), nil)
+ out, _ := EnsureInterface(UnpackPtrValue(EnsurePackValue(decodedResponse.RspObj)), nil)
assert.Equal(t, in, out)
}
func TestResponse(t *testing.T) {
caseObj := Case{A: "a", B: 1}
+ decodedResponse := &Response{}
arr := []*Case{&caseObj}
var arrRes []interface{}
- doTestResponse(t, PackageResponse, Response_OK, arr, &arrRes, func() {
+ decodedResponse.RspObj = &arrRes
+ doTestResponse(t, PackageResponse, Response_OK, arr, decodedResponse, func() {
assert.Equal(t, 1, len(arrRes))
assert.Equal(t, &caseObj, arrRes[0])
})
- doTestResponse(t, PackageResponse, Response_OK, &Case{A: "a", B: 1}, &Case{}, nil)
+ decodedResponse.RspObj = &Case{}
+ doTestResponse(t, PackageResponse, Response_OK, &Case{A: "a", B: 1}, decodedResponse, nil)
s := "ok!!!!!"
strObj := ""
- doTestResponse(t, PackageResponse, Response_OK, s, &strObj, nil)
+ decodedResponse.RspObj = &strObj
+ doTestResponse(t, PackageResponse, Response_OK, s, decodedResponse, nil)
var intObj int64
- doTestResponse(t, PackageResponse, Response_OK, int64(3), &intObj, nil)
+ decodedResponse.RspObj = &intObj
+ doTestResponse(t, PackageResponse, Response_OK, int64(3), decodedResponse, nil)
boolObj := false
- doTestResponse(t, PackageResponse, Response_OK, true, &boolObj, nil)
+ decodedResponse.RspObj = &boolObj
+ doTestResponse(t, PackageResponse, Response_OK, true, decodedResponse, nil)
strObj = ""
- doTestResponse(t, PackageResponse, Response_SERVER_ERROR, "error!!!!!", &strObj, nil)
+ decodedResponse.RspObj = &strObj
+ doTestResponse(t, PackageResponse, Response_SERVER_ERROR, "error!!!!!", decodedResponse, nil)
mapObj := map[string][]*Case{"key": {&caseObj}}
mapRes := map[interface{}]interface{}{}
- doTestResponse(t, PackageResponse, Response_OK, mapObj, &mapRes, func() {
+ decodedResponse.RspObj = &mapRes
+ doTestResponse(t, PackageResponse, Response_OK, mapObj, decodedResponse, func() {
c, ok := mapRes["key"]
if !ok {
assert.FailNow(t, "no key in decoded response map")
diff --git a/response.go b/response.go
index 5e0b0d8..2eb4b20 100644
--- a/response.go
+++ b/response.go
@@ -26,6 +26,12 @@
perrors "github.com/pkg/errors"
)
+type Response struct {
+ RspObj interface{}
+ Exception error
+ //Attachments map[string]string
+}
+
// dubbo-remoting/dubbo-remoting-api/src/main/java/com/alibaba/dubbo/remoting/exchange/codec/ExchangeCodec.java
// v2.7.1 line 256 encodeResponse
// hessian encode response
@@ -120,7 +126,7 @@
// hessian decode response body
// todo: need to read attachments
-func unpackResponseBody(buf []byte, rspObj interface{}) error {
+func unpackResponseBody(buf []byte, response *Response) error {
// body
decoder := NewDecoder(buf[:])
rspType, err := decoder.Decode()
@@ -135,19 +141,21 @@
return perrors.WithStack(err)
}
if e, ok := expt.(error); ok {
- return e
+ response.Exception = e
+ return nil
}
- return perrors.Errorf("got exception: %+v", expt)
+ response.Exception = perrors.Errorf("got exception: %+v", expt)
+ return nil
case RESPONSE_VALUE, RESPONSE_VALUE_WITH_ATTACHMENTS:
rsp, err := decoder.Decode()
if err != nil {
return perrors.WithStack(err)
}
- return perrors.WithStack(ReflectResponse(rsp, rspObj))
+ return perrors.WithStack(ReflectResponse(rsp, response.RspObj))
case RESPONSE_NULL_VALUE, RESPONSE_NULL_VALUE_WITH_ATTACHMENTS:
- return perrors.New("Received null")
+ return nil
}
return nil