func (c *Codec) ReadHeader(hdr *rpc.Header) error { c.msg = inMsg{} // avoid any potential cross-message contamination. var err error if c.isLogging() { var m json.RawMessage err = c.conn.Receive(&m) if err == nil { logger.Tracef("<- %s", m) err = json.Unmarshal(m, &c.msg) } else { logger.Tracef("<- error: %v (closing %v)", err, c.isClosing()) } } else { err = c.conn.Receive(&c.msg) } if err != nil { // If we've closed the connection, we may get a spurious error, // so ignore it. if c.isClosing() || err == io.EOF { return io.EOF } return fmt.Errorf("error receiving message: %v", err) } hdr.RequestId = c.msg.RequestId hdr.Request = rpc.Request{ Type: c.msg.Type, Id: c.msg.Id, Action: c.msg.Request, } hdr.Error = c.msg.Error hdr.ErrorCode = c.msg.ErrorCode return nil }
func (c *Codec) ReadHeader(hdr *rpc.Header) error { var m json.RawMessage var version int err := c.conn.Receive(&m) if err == nil { logger.Tracef("<- %s", m) c.msg, version, err = c.readMessage(m) } else { logger.Tracef("<- error: %v (closing %v)", err, c.isClosing()) } if err != nil { // If we've closed the connection, we may get a spurious error, // so ignore it. if c.isClosing() || err == io.EOF { return io.EOF } return errors.Annotate(err, "error receiving message") } hdr.RequestId = c.msg.RequestId hdr.Request = rpc.Request{ Type: c.msg.Type, Version: c.msg.Version, Id: c.msg.Id, Action: c.msg.Request, } hdr.Error = c.msg.Error hdr.ErrorCode = c.msg.ErrorCode hdr.Version = version return nil }
func (c *testCodec) WriteMessage(hdr *rpc.Header, x interface{}) error { if reflect.ValueOf(x).Kind() != reflect.Struct { panic(fmt.Errorf("WriteRequest bad param; want struct got %T (%#v)", x, x)) } if c.role != roleBoth && hdr.IsRequest() != (c.role == roleClient) { panic(fmt.Errorf("codec role %v; header wrong type %#v", c.role, hdr)) } logger.Infof("send header: %#v; body: %#v", hdr, x) return c.Codec.WriteMessage(hdr, x) }
func (c *testCodec) ReadHeader(hdr *rpc.Header) error { err := c.Codec.ReadHeader(hdr) if err != nil { return err } logger.Infof("got header %#v", hdr) if c.role != roleBoth && hdr.IsRequest() == (c.role == roleClient) { panic(fmt.Errorf("codec role %v; read wrong type %#v", c.role, hdr)) } return nil }
// init fills out the receiving outMsg with information from the given // header and body. func (m *outMsg) init(hdr *rpc.Header, body interface{}) { m.RequestId = hdr.RequestId m.Type = hdr.Request.Type m.Id = hdr.Request.Id m.Request = hdr.Request.Action m.Error = hdr.Error m.ErrorCode = hdr.ErrorCode if hdr.IsRequest() { m.Params = body } else { m.Response = body } }
// newOutMsgV1 fills out a outMsgV1 with information from the given header and // body. This might look a lot like the v0 method, and that is because it is. // However, since Go determins structs to be sufficiently different if the // tags are different, we can't use the same code. Theoretically we could use // reflect, but no. func newOutMsgV1(hdr *rpc.Header, body interface{}) outMsgV1 { result := outMsgV1{ RequestId: hdr.RequestId, Type: hdr.Request.Type, Version: hdr.Request.Version, Id: hdr.Request.Id, Request: hdr.Request.Action, Error: hdr.Error, ErrorCode: hdr.ErrorCode, } if hdr.IsRequest() { result.Params = body } else { result.Response = body } return result }
func (*suite) TestRead(c *gc.C) { for i, test := range readTests { c.Logf("test %d", i) codec := jsoncodec.New(&testConn{ readMsgs: []string{test.msg}, }) var hdr rpc.Header err := codec.ReadHeader(&hdr) c.Assert(err, gc.IsNil) c.Assert(hdr, gc.DeepEquals, test.expectHdr) c.Assert(hdr.IsRequest(), gc.Equals, test.expectHdr.IsRequest()) body := reflect.New(reflect.ValueOf(test.expectBody).Type().Elem()).Interface() err = codec.ReadBody(body, test.expectHdr.IsRequest()) c.Assert(err, gc.IsNil) c.Assert(body, gc.DeepEquals, test.expectBody) err = codec.ReadHeader(&hdr) c.Assert(err, gc.Equals, io.EOF) } }
func (*suite) TestRead(c *gc.C) { for i, test := range []struct { msg string expectHdr rpc.Header expectBody interface{} }{{ msg: `{"RequestId": 1, "Type": "foo", "Id": "id", "Request": "frob", "Params": {"X": "param"}}`, expectHdr: rpc.Header{ RequestId: 1, Request: rpc.Request{ Type: "foo", Id: "id", Action: "frob", }, }, expectBody: &value{X: "param"}, }, { msg: `{"RequestId": 2, "Error": "an error", "ErrorCode": "a code"}`, expectHdr: rpc.Header{ RequestId: 2, Error: "an error", ErrorCode: "a code", }, expectBody: new(map[string]interface{}), }, { msg: `{"RequestId": 3, "Response": {"X": "result"}}`, expectHdr: rpc.Header{ RequestId: 3, }, expectBody: &value{X: "result"}, }, { msg: `{"RequestId": 4, "Type": "foo", "Version": 2, "Id": "id", "Request": "frob", "Params": {"X": "param"}}`, expectHdr: rpc.Header{ RequestId: 4, Request: rpc.Request{ Type: "foo", Version: 2, Id: "id", Action: "frob", }, }, expectBody: &value{X: "param"}, }, { msg: `{"request-id": 1, "type": "foo", "id": "id", "request": "frob", "params": {"X": "param"}}`, expectHdr: rpc.Header{ RequestId: 1, Request: rpc.Request{ Type: "foo", Id: "id", Action: "frob", }, Version: 1, }, expectBody: &value{X: "param"}, }, { msg: `{"request-id": 2, "error": "an error", "error-code": "a code"}`, expectHdr: rpc.Header{ RequestId: 2, Error: "an error", ErrorCode: "a code", Version: 1, }, expectBody: new(map[string]interface{}), }, { msg: `{"request-id": 3, "response": {"X": "result"}}`, expectHdr: rpc.Header{ RequestId: 3, Version: 1, }, expectBody: &value{X: "result"}, }, { msg: `{"request-id": 4, "type": "foo", "version": 2, "id": "id", "request": "frob", "params": {"X": "param"}}`, expectHdr: rpc.Header{ RequestId: 4, Request: rpc.Request{ Type: "foo", Version: 2, Id: "id", Action: "frob", }, Version: 1, }, expectBody: &value{X: "param"}, }} { c.Logf("test %d", i) codec := jsoncodec.New(&testConn{ readMsgs: []string{test.msg}, }) var hdr rpc.Header err := codec.ReadHeader(&hdr) c.Assert(err, jc.ErrorIsNil) c.Assert(hdr, gc.DeepEquals, test.expectHdr) c.Assert(hdr.IsRequest(), gc.Equals, test.expectHdr.IsRequest()) body := reflect.New(reflect.ValueOf(test.expectBody).Type().Elem()).Interface() err = codec.ReadBody(body, test.expectHdr.IsRequest()) c.Assert(err, jc.ErrorIsNil) c.Assert(body, gc.DeepEquals, test.expectBody) err = codec.ReadHeader(&hdr) c.Assert(err, gc.Equals, io.EOF) } }