From 0ec0f50cfd1644560ca6fcf1e5d9bd57aefd328f Mon Sep 17 00:00:00 2001 From: Kiyon Date: Sun, 7 Feb 2021 13:55:13 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Add=20network=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.go | 21 +++++++++++++++------ helpers.go | 4 ++-- helpers_test.go | 6 +++--- prefork.go | 4 ++-- prefork_test.go | 10 +++++----- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/app.go b/app.go index a1dbb88c..3d6cb836 100644 --- a/app.go +++ b/app.go @@ -280,6 +280,12 @@ type Config struct { // Allowing for flexibility in using another json library for encoding // Default: json.Marshal JSONEncoder utils.JSONMarshal `json:"-"` + + // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only) + // WARNING: When prefork is set to true, only "tcp4" and "tcp6" can be chose. + // + // Default: "tcp4" + Network string } // Static defines configuration options when defining static assets. @@ -396,6 +402,9 @@ func New(config ...Config) *App { if app.config.JSONEncoder == nil { app.config.JSONEncoder = json.Marshal } + if app.config.Network == "" { + app.config.Network = "tcp4" + } // Init app app.init() @@ -553,8 +562,8 @@ func NewError(code int, message ...string) *Error { func (app *App) Listener(ln net.Listener) error { // Prefork is supported for custom listeners if app.config.Prefork { - addr, tls := lnMetadata(ln) - return app.prefork(addr, tls) + addr, tlsConfig := lnMetadata(app.config.Network, ln) + return app.prefork(app.config.Network, addr, tlsConfig) } // prepare the server for the start app.startupProcess() @@ -573,10 +582,10 @@ func (app *App) Listener(ln net.Listener) error { func (app *App) Listen(addr string) error { // Start prefork if app.config.Prefork { - return app.prefork(addr, nil) + return app.prefork(app.config.Network, addr, nil) } // Setup listener - ln, err := net.Listen("tcp4", addr) + ln, err := net.Listen(app.config.Network, addr) if err != nil { return err } @@ -613,10 +622,10 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error { cert, }, } - return app.prefork(addr, config) + return app.prefork(app.config.Network, addr, config) } // Setup listener - ln, err := net.Listen("tcp4", addr) + ln, err := net.Listen(app.config.Network, addr) if err != nil { return err } diff --git a/helpers.go b/helpers.go index 392f9e6b..d075d793 100644 --- a/helpers.go +++ b/helpers.go @@ -25,7 +25,7 @@ import ( /* #nosec */ // lnMetadata will close the listener and return the addr and tls config -func lnMetadata(ln net.Listener) (addr string, cfg *tls.Config) { +func lnMetadata(network string, ln net.Listener) (addr string, cfg *tls.Config) { // Get addr addr = ln.Addr().String() @@ -37,7 +37,7 @@ func lnMetadata(ln net.Listener) (addr string, cfg *tls.Config) { // Wait for the listener to be closed var closed bool for i := 0; i < 10; i++ { - conn, err := net.DialTimeout("tcp4", addr, 3*time.Second) + conn, err := net.DialTimeout(network, addr, 3*time.Second) if err != nil || conn == nil { closed = true break diff --git a/helpers_test.go b/helpers_test.go index d3c62e64..ff1b27ad 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -267,7 +267,7 @@ func Test_Utils_lnMetadata(t *testing.T) { utils.AssertEqual(t, nil, ln.Close()) - addr, config := lnMetadata(ln) + addr, config := lnMetadata("tcp", ln) utils.AssertEqual(t, ln.Addr().String(), addr) utils.AssertEqual(t, true, config == nil) @@ -278,7 +278,7 @@ func Test_Utils_lnMetadata(t *testing.T) { utils.AssertEqual(t, nil, err) - addr, config := lnMetadata(ln) + addr, config := lnMetadata("tcp4", ln) utils.AssertEqual(t, ln.Addr().String(), addr) utils.AssertEqual(t, true, config == nil) @@ -295,7 +295,7 @@ func Test_Utils_lnMetadata(t *testing.T) { ln = tls.NewListener(ln, config) - addr, config := lnMetadata(ln) + addr, config := lnMetadata("tcp4", ln) utils.AssertEqual(t, ln.Addr().String(), addr) utils.AssertEqual(t, true, config != nil) diff --git a/prefork.go b/prefork.go index 4dc270b5..b2bf382c 100644 --- a/prefork.go +++ b/prefork.go @@ -29,7 +29,7 @@ func IsChild() bool { } // prefork manages child processes to make use of the OS REUSEPORT or REUSEADDR feature -func (app *App) prefork(addr string, tlsConfig *tls.Config) (err error) { +func (app *App) prefork(network, addr string, tlsConfig *tls.Config) (err error) { // 👶 child process 👶 if IsChild() { // use 1 cpu core per child process @@ -37,7 +37,7 @@ func (app *App) prefork(addr string, tlsConfig *tls.Config) (err error) { var ln net.Listener // Linux will use SO_REUSEPORT and Windows falls back to SO_REUSEADDR // Only tcp4 or tcp6 is supported when preforking, both are not supported - if ln, err = reuseport.Listen("tcp4", addr); err != nil { + if ln, err = reuseport.Listen(network, addr); err != nil { if !app.config.DisableStartupMessage { time.Sleep(100 * time.Millisecond) // avoid colliding with startup message } diff --git a/prefork_test.go b/prefork_test.go index 0a6723a9..76dadfb0 100644 --- a/prefork_test.go +++ b/prefork_test.go @@ -23,7 +23,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) { app := New() - err := app.prefork("invalid", nil) + err := app.prefork("tcp4", "invalid", nil) utils.AssertEqual(t, false, err == nil) go func() { @@ -31,7 +31,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) { utils.AssertEqual(t, nil, app.Shutdown()) }() - utils.AssertEqual(t, nil, app.prefork("[::]:", nil)) + utils.AssertEqual(t, nil, app.prefork("tcp6", "[::]:", nil)) // Create tls certificate cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") @@ -45,7 +45,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) { utils.AssertEqual(t, nil, app.Shutdown()) }() - utils.AssertEqual(t, nil, app.prefork("127.0.0.1:", config)) + utils.AssertEqual(t, nil, app.prefork("tcp4", "127.0.0.1:", config)) } func Test_App_Prefork_Master_Process(t *testing.T) { @@ -59,11 +59,11 @@ func Test_App_Prefork_Master_Process(t *testing.T) { utils.AssertEqual(t, nil, app.Shutdown()) }() - utils.AssertEqual(t, nil, app.prefork(":3000", nil)) + utils.AssertEqual(t, nil, app.prefork("tcp4", ":3000", nil)) dummyChildCmd = "invalid" - err := app.prefork("127.0.0.1:", nil) + err := app.prefork("tcp4", "127.0.0.1:", nil) utils.AssertEqual(t, false, err == nil) }