// WriteResponse encodes and sends a net/rpc response header r with body x. func (c *serverCodec) WriteResponse(r *rpc.Response, x interface{}) error { // This is similar to WriteRequest(), above. var encodeErr error var hdr ProtoRPCResponseHeader hdr.Op = proto.String(r.ServiceMethod) hdr.Seq = proto.Uint64(r.Seq) var body proto.Message var ok bool if r.Error != "" { // Error responses have empty body. In this case, x can be an empty struct // from net/rpc.Server, and net/rpc.Client will discard the body in any // case, so leave body == nil. hdr.Error = proto.String(r.Error) } else if body, ok = x.(proto.Message); !ok || body == nil { // If x isn't a protobuf, or is a nil protobuf, turn reply into an error and // leave body == nil. encodeErr = ErrBadResponseType msg := encodeErr.Error() hdr.Error = &msg } c.sending.Lock() _, err := c.m.WriteMessage(&hdr) // writes htonl(length), marshal(hdr) if err == nil { _, err = c.m.WriteMessage(body) // writes htonl(length), marshal(body) } c.sending.Unlock() if encodeErr != nil { err = encodeErr } return util.Logged(err) }
// ReadResponseBody receives and decodes a net/rpc response body x. func (c *clientCodec) ReadResponseBody(x interface{}) error { if x == nil { // rpc.Client is telling us to read and discard the response, perhaps // because response header contains an error (in which case the server would // have encoded a blank message body). _, err := c.m.ReadString() return util.Logged(err) } body, ok := x.(proto.Message) if !ok || body == nil { // TODO(kwalsh) Not clear if this is legal, but I think not. // Read and discard the response body. c.m.ReadString() return util.Logged(ErrBadResponseType) } return util.Logged(c.m.ReadMessage(body)) }
// WriteRequest encodes and sends a net/rpc request header r with body x. func (c *clientCodec) WriteRequest(r *rpc.Request, x interface{}) error { body, ok := x.(proto.Message) if !ok || body == nil { // TODO(kwalsh) Not clear if this is legal, but I think not. // Don't send anything. return util.Logged(ErrBadRequestType) } var hdr ProtoRPCRequestHeader hdr.Op = proto.String(r.ServiceMethod) hdr.Seq = proto.Uint64(r.Seq) c.sending.Lock() _, err := c.m.WriteMessage(&hdr) // writes htonl(length), marshal(hdr) if err == nil { _, err = c.m.WriteMessage(body) // writes htonl(length), marshal(body) } c.sending.Unlock() return util.Logged(err) }
// ReadRequestBody receives and decodes a net/rpc request body x. func (c *serverCodec) ReadRequestBody(x interface{}) error { // This is almost identical to ReadResponseBody(), above. if x == nil { // rpc.Server is telling us to read and discard the request, perhaps because // response header was read successfully but contained an unexpected service // method string. The client would have encoded an actual message body. _, err := c.m.ReadString() return util.Logged(err) } body, ok := x.(proto.Message) if !ok || body == nil { // TODO(kwalsh) Not clear if this is legal, but I think not. // Read and discard the request body. c.m.ReadString() return util.Logged(ErrBadRequestType) } return util.Logged(c.m.ReadMessage(body)) }
// ReadResponseHeader receives and decodes a net/rpc response header r. func (c *clientCodec) ReadResponseHeader(r *rpc.Response) error { var err error var hdr ProtoRPCResponseHeader if err = c.m.ReadMessage(&hdr); err != nil { return util.Logged(err) } r.Seq = *hdr.Seq r.ServiceMethod = *hdr.Op if hdr.Error != nil { r.Error = *hdr.Error } return nil }
// RetractRule removes a rule previously added via AddRule() or the // equivalent Authorize() call. func (t TrivialGuard) RetractRule(rule string) error { if t != ConservativeGuard { return util.Logged(errTrivialGuard) } return nil }
// AddRule adds a policy rule. Subclasses should support at least rules // of the form: Authorized(P, op, args...). This is equivalent to // calling Authorize(P, op, args...) with each of the arguments // converted to either a string or integer. func (t TrivialGuard) AddRule(rule string) error { if t != LiberalGuard { return util.Logged(errTrivialGuard) } return nil }
// Retract removes an authorization for a principal to perform an // operation, essentially reversing the effect of an Authorize() call // with identical name, op, and args. Note: this reverses the effect of // an Authorize() call with identical parameters of the equivalent // AddRule() call. However, particularly when expressive policies are // supported (e.g., an "authorize all" rule), other rules may still be // in place authorizing the principal to perform the operation. func (t TrivialGuard) Retract(name auth.Prin, op string, args []string) error { if t != ConservativeGuard { return util.Logged(errTrivialGuard) } return nil }
// Authorize adds an authorization for a principal to perform an // operation. func (t TrivialGuard) Authorize(name auth.Prin, op string, args []string) error { if t != LiberalGuard { return util.Logged(errTrivialGuard) } return nil }
// newError formats an error, logs it to glog, then returs it. func newError(msg string, args ...interface{}) error { return util.Logged(fmt.Errorf(msg, args...)) }