Repository: caddyserver/caddy
File: modules/caddyhttp/server.go (Go)

Code before:
	if wrec.Status() >= 400 {
		log = logger.Error
	}

	userID, _ := repl.GetString("http.auth.user.id")

	reqBodyLength := 0
	if bodyReader != nil {
		reqBodyLength = bodyReader.Length
	}

	// preallocate fields with a capacity of 7 in case traceID is set
	fields := make([]zapcore.Field, 0, 7)
	fields = append(fields, zap.Int("bytes_read", reqBodyLength))
	fields = append(fields, zap.String("user_id", userID))
	fields = append(fields, zap.Duration("duration", *duration))
	fields = append(fields, zap.Int("size", wrec.Size()))
	fields = append(fields, zap.Int("status", wrec.Status()))
	fields = append(fields, zap.Object("resp_headers", LoggableHTTPHeader{
		Header:               wrec.Header(),
		ShouldLogCredentials: shouldLogCredentials,
	}))

	traceID, _ := GetVar(r.Context(), "traceID").(string)
	if traceID != "" {
		fields = append(fields, zap.String("traceID", traceID))
	}

	log("handled request", fields...)
}

// wrapPrimaryRoute wraps stack (a compiled middleware handler chain)
// in s.enforcementHandler which performs crucial security checks, etc.
func (s *Server) wrapPrimaryRoute(stack Handler) Handler {
	return HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
		return s.enforcementHandler(w, r, stack)
	})
}

// enforcementHandler is an implicit middleware which performs
// standard checks before executing the HTTP middleware chain.
func (s *Server) enforcementHandler(w http.ResponseWriter, r *http.Request, next Handler) error {
	// enforce strict host matching, which ensures that the SNI
	// value (if any), matches the Host header; essential for
	// servers that rely on TLS ClientAuth sharing a listener
	// with servers that do not; if not enforced, client could
	// bypass by sending benign SNI then restricted Host header
	if s.StrictSNIHost != nil && *s.StrictSNIHost && r.TLS != nil {
		hostname, _, err := net.SplitHostPort(r.Host)
		if err != nil {
			hostname = r.Host // OK; probably lacked port

Review comment (suggestion):
All our log fields are snake_case, should be consistent

```suggestion
		fields = append(fields, zap.String("trace_id", traceID))
```

Code after:
		}
		if !strings.EqualFold(r.TLS.ServerName, hostname) {
			err := fmt.Errorf("strict host matching: TLS ServerName (%s) and HTTP Host (%s) values differ",
				r.TLS.ServerName, hostname)
			r.Close = true
			return Error(http.StatusMisdirectedRequest, err)
		}
	}
	return next.ServeHTTP(w, r)
}

// listenersUseAnyPortOtherThan returns true if there are any
// listeners in s that use a port which is not otherPort.
func (s *Server) listenersUseAnyPortOtherThan(otherPort int) bool {
	for _, lnAddr := range s.Listen {
		laddrs, err := caddy.ParseNetworkAddress(lnAddr)
		if err != nil {
			continue
		}
		if uint(otherPort) > laddrs.EndPort || uint(otherPort) < laddrs.StartPort {
			return true
		}
	}
	return false
}

// hasListenerAddress returns true if s has a listener
// at the given address fullAddr. Currently, fullAddr
// must represent exactly one socket address (port
// ranges are not supported)
func (s *Server) hasListenerAddress(fullAddr string) bool {
	laddrs, err := caddy.ParseNetworkAddress(fullAddr)
	if err != nil {
		return false
	}
	if laddrs.PortRangeSize() != 1 {
		return false // TODO: support port ranges
	}

	for _, lnAddr := range s.Listen {
		thisAddrs, err := caddy.ParseNetworkAddress(lnAddr)
		if err != nil {
			continue
		}
		if thisAddrs.Network != laddrs.Network {
			continue
		}

		// Apparently, Linux requires all bound ports to be distinct
		// *regardless of host interface* even if the addresses are
		// in fact different; binding "192.168.0.1:9000" and then