| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -15,51 +15,73 @@ const (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				type Option interface {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					apply(server *http.Server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					apply(cfg *config)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func WithPort(port int) Option {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(server *http.Server) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						server.Addr = net.JoinHostPort("", strconv.Itoa(port))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(cfg *config) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						cfg.server.Addr = net.JoinHostPort("", strconv.Itoa(port))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					})
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func WithHandler(handler http.Handler) Option {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(server *http.Server) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						server.Handler = handler
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(cfg *config) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						cfg.server.Handler = handler
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					})
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func WithServer(server *http.Server) Option {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(cfg *config) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						cfg.server = server
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					})
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func WithStartFn(fn func(server *http.Server) error) Option {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(cfg *config) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						cfg.startFn = fn
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					})
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// WithServerOption 使用 fn 配置 [http.Server];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func WithServerOption(fn func(server *http.Server)) Option {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(fn)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return optionFunc(func(cfg *config) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						fn(cfg.server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					})
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				type optionFunc func(server *http.Server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				type config struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					server  *http.Server
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					startFn func(server *http.Server) error
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func (fn optionFunc) apply(server *http.Server) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fn(server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func newDefaultConfig() *config {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return &config{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						server: &http.Server{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							Addr:              DefaultAddr,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							ReadHeaderTimeout: DefaultReadHeaderTimeout,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						startFn: func(server *http.Server) error {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return server.ListenAndServe()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				type optionFunc func(cfg *config)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func (fn optionFunc) apply(cfg *config) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fn(cfg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// HTTPListenAndServe 创建 [http.Server] 并提供启动和停止函数;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// opts 按照顺序应用到 [http.Server] 上.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func HTTPListenAndServe(opts ...Option) (func(ctx context.Context) error, func(ctx context.Context)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					server := &http.Server{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						Addr:              DefaultAddr,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						ReadHeaderTimeout: DefaultReadHeaderTimeout,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					cfg := newDefaultConfig()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for _, opt := range opts {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						opt.apply(server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						opt.apply(cfg)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return HTTPServer(server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// HTTPServer 提供 [http.Server] 的启动和停止函数;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func HTTPServer(server *http.Server) (func(ctx context.Context) error, func(ctx context.Context)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					inShutdown := &atomic.Bool{}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					c := make(chan error, 1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					goFunc := func(_ context.Context) error {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						err := server.ListenAndServe()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						err := cfg.startFn(cfg.server)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if inShutdown.Load() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							err = <-c
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -67,7 +89,7 @@ func HTTPServer(server *http.Server) (func(ctx context.Context) error, func(ctx
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					stopFunc := func(ctx context.Context) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						inShutdown.Store(true)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						c <- server.Shutdown(ctx)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						c <- cfg.server.Shutdown(ctx)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return goFunc, stopFunc
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |