in pkg/hostmgr/mesos/yarpc/transport/mhttp/outbound.go [150:245]
func (o *outbound) Call(
ctx context.Context,
req *transport.Request) (*transport.Response, error) {
if !o.started.Load() {
// panic because there's no recovery from this
panic(errOutboundNotStarted)
}
start := time.Now()
deadline, _ := ctx.Deadline()
ttl := deadline.Sub(start)
hostPort := o.detector.HostPort()
if len(hostPort) == 0 {
return nil, errNoLeader
}
actualURL := o.urlTemplate
actualURL.Host = hostPort
request, err := http.NewRequest("POST", actualURL.String(), req.Body)
if err != nil {
return nil, err
}
request.Header = http.Header{}
for k, v := range o.defaultHeaders {
for _, vv := range v {
request.Header.Set(k, vv)
}
}
for k, v := range req.Headers.Items() {
request.Header.Set(k, v)
}
request.Header.Set(CallerHeader, req.Caller)
request.Header.Set(ServiceHeader, req.Service)
request.Header.Set(ProcedureHeader, req.Procedure)
request.Header.Set(TTLMSHeader, fmt.Sprintf("%d", ttl/time.Millisecond))
encoding := string(req.Encoding)
if encoding != "" {
request.Header.Set(EncodingHeader, encoding)
}
response, err := ctxhttp.Do(ctx, o.Client, request)
if err != nil {
o.scope.Counter(outboundError).Inc(1)
if err == context.DeadlineExceeded {
return nil, yarpcerrors.DeadlineExceededErrorf(
"Outbound service timeout: service: %s, procedure: %s, timeout: %v",
req.Service,
req.Procedure,
deadline.Sub(start))
}
return nil, err
}
if response.StatusCode >= 200 && response.StatusCode < 300 {
return &transport.Response{
Headers: transport.NewHeaders(),
Body: response.Body,
}, nil
}
// TODO Behavior for 300-range status codes is undefined
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
if err := response.Body.Close(); err != nil {
return nil, err
}
// Trim the trailing newline from HTTP error messages
message := fmt.Sprintf(
"{\"status_code\": %d, \"contents\": \"%s\"}",
response.StatusCode,
strings.TrimSuffix(string(contents), "\n"))
if response.StatusCode == 401 {
return nil, yarpcerrors.UnauthenticatedErrorf(message)
}
if response.StatusCode >= 400 && response.StatusCode < 500 {
return nil, yarpcerrors.InternalErrorf(message)
}
if response.StatusCode == http.StatusGatewayTimeout {
return nil, yarpcerrors.DeadlineExceededErrorf(message)
}
return nil, yarpcerrors.UnknownErrorf(message)
}