package httpproxy import ( "context" "net/http" "sync" "time" ) type Server struct { address string handler http.Handler logger infoErrorer internalWG *sync.WaitGroup readHeaderTimeout time.Duration readTimeout time.Duration } func New(ctx context.Context, address string, logger Logger, stealth, verbose bool, username, password string, readHeaderTimeout, readTimeout time.Duration, ) *Server { wg := &sync.WaitGroup{} return &Server{ address: address, handler: newHandler(ctx, wg, logger, stealth, verbose, username, password), logger: logger, internalWG: wg, readHeaderTimeout: readHeaderTimeout, readTimeout: readTimeout, } } func (s *Server) Run(ctx context.Context, errorCh chan<- error) { server := http.Server{ Addr: s.address, Handler: s.handler, ReadHeaderTimeout: s.readHeaderTimeout, ReadTimeout: s.readTimeout, } go func() { <-ctx.Done() const shutdownGraceDuration = 100 * time.Millisecond shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownGraceDuration) defer cancel() if err := server.Shutdown(shutdownCtx); err != nil { s.logger.Error("failed shutting down: " + err.Error()) } }() s.logger.Info("listening on " + s.address) err := server.ListenAndServe() s.internalWG.Wait() if err != nil && ctx.Err() == nil { errorCh <- err } else { errorCh <- nil } }