github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/transport/http/server.go (about)

     1  package http
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"log"
     7  	"net"
     8  	"net/http"
     9  	"net/url"
    10  
    11  	"github.com/binbinly/pkg/transport"
    12  	"github.com/binbinly/pkg/util"
    13  )
    14  
    15  var (
    16  	_ transport.Server   = (*Server)(nil)
    17  	_ transport.Endpoint = (*Server)(nil)
    18  )
    19  
    20  // Server http server struct
    21  type Server struct {
    22  	*http.Server
    23  	lis      net.Listener
    24  	endpoint *url.URL
    25  
    26  	opts options
    27  }
    28  
    29  // NewServer create a server
    30  func NewServer(opts ...Option) *Server {
    31  	srv := &Server{
    32  		opts: newOptions(opts...),
    33  	}
    34  	// NOTE: must set server
    35  	srv.Server = &http.Server{
    36  		Handler: srv,
    37  	}
    38  	return srv
    39  }
    40  
    41  // ServeHTTP should write reply headers and data to the ResponseWriter and then return.
    42  func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
    43  	s.ServeHTTP(resp, req)
    44  }
    45  
    46  // Endpoint return a real address to registry endpoint.
    47  // examples: http://127.0.0.1:8080
    48  func (s *Server) Endpoint() (*url.URL, error) {
    49  	addr, err := util.Extract(s.opts.address, s.lis)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	s.endpoint = &url.URL{Scheme: "http", Host: addr}
    54  	return s.endpoint, nil
    55  }
    56  
    57  // Start start a server
    58  func (s *Server) Start(ctx context.Context) error {
    59  	lis, err := net.Listen(s.opts.network, s.opts.address)
    60  	if err != nil {
    61  		return err
    62  	}
    63  	s.lis = lis
    64  
    65  	if _, err = s.Endpoint(); err != nil {
    66  		return err
    67  	}
    68  	log.Printf("[HTTP] server is listening on: %s", lis.Addr().String())
    69  	if err = s.Serve(lis); !errors.Is(err, http.ErrServerClosed) {
    70  		return err
    71  	}
    72  	return nil
    73  }
    74  
    75  // Stop server
    76  func (s *Server) Stop(ctx context.Context) error {
    77  	log.Print("[HTTP] server is stopping")
    78  	return s.Shutdown(ctx)
    79  }