func makeHTTPServerWithHeaderLimit(s *http.Server, group []*SiteConfig) *http.Server {
	var min int64
	for _, cfg := range group {
		limit := cfg.Limits.MaxRequestHeaderSize
		if limit == 0 {
			continue
		}
		if min == 0 {
			min = limit
		}
		if limit < min {
			min = limit
		}
	}
	if min > 0 {
		s.MaxHeaderBytes = int(min)
	}
	return s
}
makeHTTPServerWithHeaderLimit apply minimum header limit within a group to given http.Server
package httpserver
import (
	"context"
	"crypto/tls"
	"errors"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"time"
	"github.com/lucas-clemente/quic-go/http3"
	"github.com/tmpim/casket"
	"github.com/tmpim/casket/caskethttp/staticfiles"
	"github.com/tmpim/casket/caskettls"
	"github.com/tmpim/casket/telemetry"
)
type Server struct {
	Server      *http.Server
	quicServer  *http3.Server
	sites       []*SiteConfig
	connTimeout time.Duration  
	tlsGovChan  chan struct{}  
	vhosts      *vhostTrie
}
var _ casket.GracefulServer = new(Server)
var defaultALPN = []string{"h2", "http/1.1"}
func makeTLSConfig(group []*SiteConfig) (*tls.Config, error) {
	var tlsConfigs []*caskettls.Config
	for i := range group {
		if HTTP2 && len(group[i].TLS.ALPN) == 0 {
			group[i].TLS.ALPN = defaultALPN
		}
		tlsConfigs = append(tlsConfigs, group[i].TLS)
	}
	return caskettls.MakeTLSConfig(tlsConfigs)
}
func getFallbacks(sites []*SiteConfig) []string {
	fallbacks := []string{}
	for _, sc := range sites {
		if sc.FallbackSite {
			fallbacks = append(fallbacks, sc.Addr.Host)
		}
	}
	return fallbacks
}
func NewServer(addr string, group []*SiteConfig) (*Server, error) {
	s := &Server{
		Server:      makeHTTPServerWithTimeouts(addr, group),
		vhosts:      newVHostTrie(),
		sites:       group,
		connTimeout: GracefulTimeout,
	}
	s.vhosts.fallbackHosts = append(s.vhosts.fallbackHosts, getFallbacks(group)...)
	s.Server = makeHTTPServerWithHeaderLimit(s.Server, group)
	s.Server.Handler = s  
	tlsConfig, err := makeTLSConfig(group)
	if err != nil {
		return nil, err
	}
	s.Server.TLSConfig = tlsConfig
	if s.Server.TLSConfig != nil {
		if HTTP2 && QUIC {
			s.quicServer = &http3.Server{Server: s.Server}
			s.Server.Handler = s.wrapWithSvcHeaders(s.Server.Handler)
		}
		tlsh := &tlsHandler{next: s.Server.Handler}
		s.Server.Handler = tlsh  
		s.Server.ConnState = func(c net.Conn, cs http.ConnState) {
			if tlsh.listener != nil {
				if cs == http.StateHijacked || cs == http.StateClosed {
					tlsh.listener.helloInfosMu.Lock()
					delete(tlsh.listener.helloInfos, c.RemoteAddr().String())
					tlsh.listener.helloInfosMu.Unlock()
				}
			}
		}
		if HTTP2 && len(s.Server.TLSConfig.NextProtos) == 0 {
			s.Server.TLSConfig.NextProtos = defaultALPN
		}
	}
	for _, site := range group {
		stack := Handler(staticfiles.FileServer{Root: http.Dir(site.Root), Hide: site.HiddenFiles, IndexPages: site.IndexPages})
		for i := len(site.middleware) - 1; i >= 0; i-- {
			stack = site.middleware[i](stack)
		}
		site.middlewareChain = stack
		s.vhosts.Insert(site.Addr.VHost(), site)
	}
	return s, nil
}