func (h handler) callHandler(ctx context.Context, call inboundCall, start time.Time) error { _, ok := ctx.Deadline() if !ok { return tchannel.ErrTimeoutRequired } treq := &transport.Request{ Caller: call.CallerName(), Service: call.ServiceName(), Encoding: transport.Encoding(call.Format()), Procedure: call.MethodString(), } ctx, headers, err := readRequestHeaders(ctx, call.Format(), call.Arg2Reader) if err != nil { return encoding.RequestHeadersDecodeError(treq, err) } treq.Headers = headers if tcall, ok := call.(tchannelCall); ok { tracer := h.deps.Tracer() ctx = tchannel.ExtractInboundSpan(ctx, tcall.InboundCall, headers.Items(), tracer) } body, err := call.Arg3Reader() if err != nil { return err } defer body.Close() treq.Body = body rw := newResponseWriter(treq, call) defer rw.Close() // TODO(abg): log if this errors treq, err = request.Validate(ctx, treq) if err != nil { return err } spec, err := h.Registry.GetHandlerSpec(treq.Service, treq.Procedure) if err != nil { return err } switch spec.Type() { case transport.Unary: treq, err = request.ValidateUnary(ctx, treq) if err == nil { err = internal.SafelyCallUnaryHandler(ctx, spec.Unary(), start, treq, rw) } default: err = errors.UnsupportedTypeError{Transport: "TChannel", Type: string(spec.Type())} } return err }
func (h handler) callHandler(w http.ResponseWriter, req *http.Request, start time.Time) error { treq := &transport.Request{ Caller: popHeader(req.Header, CallerHeader), Service: popHeader(req.Header, ServiceHeader), Procedure: popHeader(req.Header, ProcedureHeader), Encoding: transport.Encoding(popHeader(req.Header, EncodingHeader)), Headers: applicationHeaders.FromHTTPHeaders(req.Header, transport.Headers{}), Body: req.Body, } ctx := req.Context() v := request.Validator{Request: treq} ctx, cancel := v.ParseTTL(ctx, popHeader(req.Header, TTLMSHeader)) defer cancel() ctx, span := h.createSpan(ctx, req, treq, start) treq, err := v.Validate(ctx) if err != nil { return err } spec, err := h.Registry.GetHandlerSpec(treq.Service, treq.Procedure) if err != nil { return updateSpanWithErr(span, err) } switch spec.Type() { case transport.Unary: defer span.Finish() ctx, cancel := v.ParseTTL(ctx, popHeader(req.Header, TTLMSHeader)) defer cancel() treq, err = v.ValidateUnary(ctx) if err != nil { return err } err = internal.SafelyCallUnaryHandler(ctx, spec.Unary(), start, treq, newResponseWriter(w)) case transport.Oneway: treq, err = v.ValidateOneway(ctx) if err != nil { return err } err = handleOnewayRequest(ctx, span, treq, spec.Oneway()) default: err = errors.UnsupportedTypeError{Transport: "HTTP", Type: string(spec.Type())} } return updateSpanWithErr(span, err) }