diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go index 0961cba70..198c27891 100644 --- a/net/ghttp/ghttp_server.go +++ b/net/ghttp/ghttp_server.go @@ -10,6 +10,7 @@ import ( "bytes" "context" "fmt" + "net" "net/http" "os" "runtime" @@ -262,6 +263,12 @@ func (s *Server) getListenAddress() string { } else { port = gconv.Int(array[0]) } + if s.config.Listeners != nil { + for _, v := range s.config.Listeners { + portArray := gstr.SplitAndTrim(v.Addr().String(), ":") + port = gconv.Int(portArray[len(portArray)-1]) + } + } return fmt.Sprintf(`http://%s:%d`, host, port) } @@ -496,10 +503,14 @@ func (s *Server) startServer(fdMap listenerFdMap) { fd = gconv.Int(addrAndFd[1]) } } + var ln net.Listener + if s.config.Listeners != nil { + ln = s.config.Listeners[v] + } if fd > 0 { - s.servers = append(s.servers, s.newGracefulServer(itemFunc, fd)) + s.servers = append(s.servers, s.newGracefulServer(itemFunc, ln, fd)) } else { - s.servers = append(s.servers, s.newGracefulServer(itemFunc)) + s.servers = append(s.servers, s.newGracefulServer(itemFunc, ln)) } s.servers[len(s.servers)-1].isHttps = true } @@ -531,10 +542,14 @@ func (s *Server) startServer(fdMap listenerFdMap) { fd = gconv.Int(addrAndFd[1]) } } + var ln net.Listener + if s.config.Listeners != nil { + ln = s.config.Listeners[v] + } if fd > 0 { - s.servers = append(s.servers, s.newGracefulServer(itemFunc, fd)) + s.servers = append(s.servers, s.newGracefulServer(itemFunc, ln, fd)) } else { - s.servers = append(s.servers, s.newGracefulServer(itemFunc)) + s.servers = append(s.servers, s.newGracefulServer(itemFunc, ln)) } } // Start listening asynchronously. diff --git a/net/ghttp/ghttp_server_config.go b/net/ghttp/ghttp_server_config.go index 1aa63a744..7f0da8521 100644 --- a/net/ghttp/ghttp_server_config.go +++ b/net/ghttp/ghttp_server_config.go @@ -9,6 +9,7 @@ package ghttp import ( "context" "crypto/tls" + "net" "net/http" "strconv" "time" @@ -50,6 +51,9 @@ type ServerConfig struct { // HTTPSAddr specifies the HTTPS addresses, multiple addresses joined using char ','. HTTPSAddr string `json:"httpsAddr"` + // Listeners specifies custom listeners, size should match address provided + Listeners map[string]net.Listener `json:"listeners"` + // HTTPSCertPath specifies certification file path for HTTPS service. HTTPSCertPath string `json:"httpsCertPath"` @@ -408,6 +412,10 @@ func (s *Server) SetHTTPSPort(port ...int) { } } +func (s *Server) SetListener(ln map[string]net.Listener) { + s.config.Listeners = ln +} + // EnableHTTPS enables HTTPS with given certification and key files for the server. // The optional parameter `tlsConfig` specifies custom TLS configuration. func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config) { diff --git a/net/ghttp/ghttp_server_graceful.go b/net/ghttp/ghttp_server_graceful.go index 1eaad5321..6a2be8caf 100644 --- a/net/ghttp/ghttp_server_graceful.go +++ b/net/ghttp/ghttp_server_graceful.go @@ -36,15 +36,16 @@ type gracefulServer struct { // newGracefulServer creates and returns a graceful http server with given address. // The optional parameter `fd` specifies the file descriptor which is passed from parent server. -func (s *Server) newGracefulServer(address string, fd ...int) *gracefulServer { +func (s *Server) newGracefulServer(address string, ln net.Listener, fd ...int) *gracefulServer { // Change port to address like: 80 -> :80 if gstr.IsNumeric(address) { address = ":" + address } gs := &gracefulServer{ - server: s, - address: address, - httpServer: s.newHttpServer(address), + server: s, + address: address, + httpServer: s.newHttpServer(address), + rawListener: ln, } if len(fd) > 0 && fd[0] > 0 { gs.fd = uintptr(fd[0]) @@ -175,6 +176,9 @@ func (s *gracefulServer) doServe(ctx context.Context) error { // getNetListener retrieves and returns the wrapped net.Listener. func (s *gracefulServer) getNetListener() (net.Listener, error) { + if s.rawListener != nil { + return s.rawListener, nil + } var ( ln net.Listener err error