func (c jsonClient) Call(ctx context.Context, reqMeta yarpc.CallReqMeta, reqBody interface{}, resBodyOut interface{}) (yarpc.CallResMeta, error) { treq := transport.Request{ Caller: c.ch.Caller(), Service: c.ch.Service(), Encoding: Encoding, } meta.ToTransportRequest(reqMeta, &treq) encoded, err := json.Marshal(reqBody) if err != nil { return nil, encoding.RequestBodyEncodeError(&treq, err) } treq.Body = bytes.NewReader(encoded) tres, err := c.ch.GetUnaryOutbound().Call(ctx, &treq) if err != nil { return nil, err } dec := json.NewDecoder(tres.Body) if err := dec.Decode(resBodyOut); err != nil { return nil, encoding.ResponseBodyDecodeError(&treq, err) } if err := tres.Body.Close(); err != nil { return nil, err } return meta.FromTransportResponse(tres), nil }
// ToTransportRequest fills the given transport request with information from // the given ReqMeta. func ToTransportRequest(reqMeta yarpc.CallReqMeta, req *transport.Request) { if reqMeta == nil { return } req.Procedure = reqMeta.GetProcedure() req.ShardKey = reqMeta.GetShardKey() req.RoutingKey = reqMeta.GetRoutingKey() req.RoutingDelegate = reqMeta.GetRoutingDelegate() req.Headers = transport.Headers(reqMeta.GetHeaders()) }
func (c thriftClient) buildTransportRequest( reqMeta yarpc.CallReqMeta, reqBody envelope.Enveloper, ) (*transport.Request, protocol.Protocol, error) { proto := c.p if !c.Enveloping { proto = disableEnvelopingProtocol{ Protocol: proto, Type: wire.Reply, // we only decode replies with this instance } } treq := transport.Request{ Caller: c.ch.Caller(), Service: c.ch.Service(), Encoding: Encoding, } meta.ToTransportRequest(reqMeta, &treq) // Always override the procedure name to the Thrift procedure name. treq.Procedure = procedureName(c.thriftService, reqBody.MethodName()) value, err := reqBody.ToWire() if err != nil { // ToWire validates the request. If it failed, we should return the error // as-is because it's not an encoding error. return nil, nil, err } reqEnvelopeType := reqBody.EnvelopeType() if reqEnvelopeType != wire.Call && reqEnvelopeType != wire.OneWay { return nil, nil, encoding.RequestBodyEncodeError( &treq, errUnexpectedEnvelopeType(reqEnvelopeType), ) } var buffer bytes.Buffer err = proto.EncodeEnveloped(wire.Envelope{ Name: reqBody.MethodName(), Type: reqEnvelopeType, SeqID: 1, // don't care Value: value, }, &buffer) if err != nil { return nil, nil, encoding.RequestBodyEncodeError(&treq, err) } treq.Body = &buffer return &treq, proto, nil }
func (c *cacheFilter) Call(ctx context.Context, request *transport.Request, out transport.UnaryOutbound) (*transport.Response, error) { data := *c // Read the entire request body to match against the cache body, err := ioutil.ReadAll(request.Body) if err != nil { return nil, err } request.Body = ioutil.NopCloser(bytes.NewReader(body)) if v, ok := data[string(body)]; ok { fmt.Println("cache hit") return &transport.Response{ Headers: v.Headers, Body: ioutil.NopCloser(bytes.NewReader(v.Body)), }, nil } fmt.Println("cache miss") res, err := out.Call(ctx, request) if err != nil { return nil, err } defer res.Body.Close() resBody, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } data[string(body)] = entry{Headers: res.Headers, Body: resBody} res.Body = ioutil.NopCloser(bytes.NewReader(resBody)) return res, nil }
func (c jsonClient) CallOneway(ctx context.Context, reqMeta yarpc.CallReqMeta, reqBody interface{}) (transport.Ack, error) { treq := transport.Request{ Caller: c.ch.Caller(), Service: c.ch.Service(), Encoding: Encoding, } meta.ToTransportRequest(reqMeta, &treq) var buff bytes.Buffer if err := json.NewEncoder(&buff).Encode(reqBody); err != nil { return nil, encoding.RequestBodyEncodeError(&treq, err) } treq.Body = &buff return c.ch.GetOnewayOutbound().CallOneway(ctx, &treq) }
// NewRequestMatcher constructs a new RequestMatcher from the given testing.T // and request. // // The request's contents are read in their entirety and replaced with a // bytes.Reader. func NewRequestMatcher(t *testing.T, r *transport.Request) RequestMatcher { body, err := ioutil.ReadAll(r.Body) if err != nil { t.Fatalf("failed to read request body: %v", err) } // restore a copy of the body so that the caller can still use the request // object r.Body = bytes.NewReader(body) return RequestMatcher{t: t, req: r, body: body} }
func (r *Recorder) requestToRequestRecord(request *transport.Request) requestRecord { requestBody, err := ioutil.ReadAll(request.Body) if err != nil { r.logger.Fatal(err) } request.Body = ioutil.NopCloser(bytes.NewReader(requestBody)) return requestRecord{ Caller: request.Caller, Service: request.Service, Procedure: request.Procedure, Encoding: string(request.Encoding), Headers: request.Headers.Items(), ShardKey: request.ShardKey, RoutingKey: request.RoutingKey, RoutingDelegate: request.RoutingDelegate, Body: requestBody, } }
func handleOnewayRequest( ctx context.Context, span opentracing.Span, treq *transport.Request, onewayHandler transport.OnewayHandler, ) error { // we will lose access to the body unless we read all the bytes before // returning from the request var buff bytes.Buffer if _, err := io.Copy(&buff, treq.Body); err != nil { return err } treq.Body = &buff go func() { // ensure the span lasts for length of the request in case of errors defer span.Finish() err := internal.SafelyCallOnewayHandler(ctx, onewayHandler, treq) updateSpanWithErr(span, err) }() return nil }