in src/go/configinfo/service_info.go [613:680]
func (s *ServiceInfo) ruleToBackendInfo(r *confpb.BackendRule, scheme string, hostname string, path string, backendClusterName string, port uint32) (*backendInfo, error) {
method := s.Methods[r.GetSelector()]
if method == nil {
return nil, nil
}
// For CONSTANT_ADDRESS, an empty uri will generate an empty path header.
// It is an invalid Http header if path is empty.
if path == "" && r.PathTranslation == confpb.BackendRule_CONSTANT_ADDRESS {
path = "/"
}
var deadline time.Duration
if r.Deadline == 0 {
// If no deadline specified by the user, explicitly use default.
deadline = util.DefaultResponseDeadline
} else if r.Deadline < 0 {
glog.Warningf("Negative deadline of %v specified for method %v. "+
"Using default deadline %v instead.", r.Deadline, r.Selector, util.DefaultResponseDeadline)
deadline = util.DefaultResponseDeadline
} else {
// The backend deadline from the BackendRule is a float64 that represents seconds.
// But float64 has a large precision, so we must explicitly lower the precision.
// For the purposes of a network proxy, round the deadline to the nearest millisecond.
deadlineMs := int64(math.Round(r.Deadline * 1000))
deadline = time.Duration(deadlineMs) * time.Millisecond
}
// Response timeouts are not compatible with streaming methods (documented in Envoy).
// This applies to methods with a streaming upstream OR downstream.
var idleTimeout time.Duration
if method.IsStreaming {
if r.Deadline <= 0 {
// When the backend deadline is unspecified , calculate the streamIdleTimeout based on max{defaultTimeout, globalStreamIdleTimeout} .
idleTimeout = calculateStreamIdleTimeout(util.DefaultResponseDeadline, s.Options)
} else {
// User configured deadline serves as the stream idle timeout.
idleTimeout = deadline
}
deadline = 0 * time.Second
} else {
// Allow per-route response deadlines to override the global stream idle timeout.
idleTimeout = calculateStreamIdleTimeout(deadline, s.Options)
}
bi := &backendInfo{
ClusterName: backendClusterName,
Path: path,
Hostname: hostname,
TranslationType: r.PathTranslation,
Deadline: deadline,
IdleTimeout: idleTimeout,
Port: port,
}
jwtAud := s.determineBackendAuthJwtAud(r, scheme, hostname)
if jwtAud != "" && s.Options.CommonOptions.NonGCP {
glog.Warningf("Backend authentication is enabled for method %v, "+
"but ESPv2 is running on non-GCP. To prevent contacting GCP services, "+
"backend authentication is automatically being disabled for this method.",
r.Selector)
jwtAud = ""
}
bi.JwtAudience = jwtAud
return bi, nil
}