start starts handler with HTTP(s) server.
(ctx stdContext.Context, h http.Handler)
| 98 | |
| 99 | // start starts handler with HTTP(s) server. |
| 100 | func (sc StartConfig) start(ctx stdContext.Context, h http.Handler) error { |
| 101 | var logger *slog.Logger |
| 102 | if e, ok := h.(*Echo); ok { |
| 103 | logger = e.Logger |
| 104 | } else { |
| 105 | logger = slog.New(slog.NewJSONHandler(os.Stdout, nil)) |
| 106 | } |
| 107 | |
| 108 | server := http.Server{ |
| 109 | Handler: h, |
| 110 | ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError), |
| 111 | // defaults for GoSec rule G112 // https://github.com/securego/gosec |
| 112 | // G112 (CWE-400): Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server |
| 113 | ReadTimeout: 30 * time.Second, |
| 114 | // WriteTimeout is a max time allowed to write the response |
| 115 | // IMPORTANT: set this to 0 when using Server-Sent-Events (SSE) or some larger duration when serving static files |
| 116 | // WriteTimeout: 30 * time.Second, |
| 117 | } |
| 118 | |
| 119 | listener := sc.Listener |
| 120 | if listener == nil { |
| 121 | listenerNetwork := cmp.Or(sc.ListenerNetwork, "tcp") |
| 122 | |
| 123 | ln, err := (&net.ListenConfig{}).Listen(ctx, listenerNetwork, sc.Address) |
| 124 | if err != nil { |
| 125 | return err |
| 126 | } |
| 127 | listener = ln |
| 128 | |
| 129 | if sc.TLSConfig != nil { |
| 130 | listener = tls.NewListener(listener, sc.TLSConfig) |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | if sc.ListenerAddrFunc != nil { |
| 135 | sc.ListenerAddrFunc(listener.Addr()) |
| 136 | } |
| 137 | |
| 138 | if sc.BeforeServeFunc != nil { |
| 139 | if err := sc.BeforeServeFunc(&server); err != nil { |
| 140 | _ = listener.Close() |
| 141 | return err |
| 142 | } |
| 143 | } |
| 144 | if !sc.HideBanner { |
| 145 | bannerText := fmt.Sprintf(banner, Version) |
| 146 | logger.Info(bannerText, "version", Version) |
| 147 | } |
| 148 | if !sc.HidePort { |
| 149 | logger.Info("http(s) server started", "address", listener.Addr().String()) |
| 150 | } |
| 151 | |
| 152 | wg := sync.WaitGroup{} |
| 153 | defer wg.Wait() // wait for graceful shutdown goroutine to finish |
| 154 | |
| 155 | gCtx, cancel := stdContext.WithCancel(ctx) // end graceful goroutine when Serve returns early |
| 156 | defer cancel() |
| 157 |
no test coverage detected