package server import ( "log" "log/slog" "net/http" "github.com/quic-go/quic-go/http3" "github.com/rs/zerolog" slogzerolog "github.com/samber/slog-zerolog/v2" "github.com/yusing/go-proxy/internal/common" "github.com/yusing/go-proxy/internal/net/gphttp" ) func advertiseHTTP3(handler http.Handler, h3 *http3.Server) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.ProtoMajor < 3 { err := h3.SetQUICHeaders(w.Header()) if err != nil { gphttp.ServerError(w, r, err) return } } handler.ServeHTTP(w, r) }) } func proto[Server httpServer](srv Server) string { var proto string switch src := any(srv).(type) { case *http.Server: if src.TLSConfig == nil { proto = "http" } else { proto = "https" } case *http3.Server: proto = "h3" } return proto } func addr[Server httpServer](srv Server) string { var addr string switch src := any(srv).(type) { case *http.Server: addr = src.Addr case *http3.Server: addr = src.Addr } return addr } func getServeFunc[listener any](l listener, serve func(listener) error) func() error { return func() error { return serve(l) } } func setDebugLogger[Server httpServer](srv Server, logger *zerolog.Logger) { if !common.IsDebug { return } switch srv := any(srv).(type) { case *http.Server: srv.ErrorLog = log.New(logger, "", 0) case *http3.Server: logOpts := slogzerolog.Option{Level: slog.LevelDebug, Logger: logger} srv.Logger = slog.New(logOpts.NewZerologHandler()) } } func logStarted[Server httpServer](srv Server, logger *zerolog.Logger) { logger.Info().Str("proto", proto(srv)).Str("addr", addr(srv)).Msg("server started") }