예제 #1
0
파일: codec.go 프로젝트: rogpeppe/juju
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
}
예제 #2
0
파일: codec.go 프로젝트: bac/juju
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
}
예제 #3
0
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)
}
예제 #4
0
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
}
예제 #5
0
파일: codec.go 프로젝트: rogpeppe/juju
// 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
	}
}
예제 #6
0
파일: codec.go 프로젝트: bac/juju
// 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
}
예제 #7
0
파일: codec_test.go 프로젝트: rogpeppe/juju
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)
	}
}
예제 #8
0
파일: codec_test.go 프로젝트: bac/juju
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)
	}
}