func()

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
}