🔥 Add network option

pull/1155/head
Kiyon 2021-02-07 13:55:13 +08:00
parent 3e2dd90be4
commit 0ec0f50cfd
5 changed files with 27 additions and 18 deletions

21
app.go
View File

@ -280,6 +280,12 @@ type Config struct {
// Allowing for flexibility in using another json library for encoding // Allowing for flexibility in using another json library for encoding
// Default: json.Marshal // Default: json.Marshal
JSONEncoder utils.JSONMarshal `json:"-"` 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. // Static defines configuration options when defining static assets.
@ -396,6 +402,9 @@ func New(config ...Config) *App {
if app.config.JSONEncoder == nil { if app.config.JSONEncoder == nil {
app.config.JSONEncoder = json.Marshal app.config.JSONEncoder = json.Marshal
} }
if app.config.Network == "" {
app.config.Network = "tcp4"
}
// Init app // Init app
app.init() app.init()
@ -553,8 +562,8 @@ func NewError(code int, message ...string) *Error {
func (app *App) Listener(ln net.Listener) error { func (app *App) Listener(ln net.Listener) error {
// Prefork is supported for custom listeners // Prefork is supported for custom listeners
if app.config.Prefork { if app.config.Prefork {
addr, tls := lnMetadata(ln) addr, tlsConfig := lnMetadata(app.config.Network, ln)
return app.prefork(addr, tls) return app.prefork(app.config.Network, addr, tlsConfig)
} }
// prepare the server for the start // prepare the server for the start
app.startupProcess() app.startupProcess()
@ -573,10 +582,10 @@ func (app *App) Listener(ln net.Listener) error {
func (app *App) Listen(addr string) error { func (app *App) Listen(addr string) error {
// Start prefork // Start prefork
if app.config.Prefork { if app.config.Prefork {
return app.prefork(addr, nil) return app.prefork(app.config.Network, addr, nil)
} }
// Setup listener // Setup listener
ln, err := net.Listen("tcp4", addr) ln, err := net.Listen(app.config.Network, addr)
if err != nil { if err != nil {
return err return err
} }
@ -613,10 +622,10 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error {
cert, cert,
}, },
} }
return app.prefork(addr, config) return app.prefork(app.config.Network, addr, config)
} }
// Setup listener // Setup listener
ln, err := net.Listen("tcp4", addr) ln, err := net.Listen(app.config.Network, addr)
if err != nil { if err != nil {
return err return err
} }

View File

@ -25,7 +25,7 @@ import (
/* #nosec */ /* #nosec */
// lnMetadata will close the listener and return the addr and tls config // 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 // Get addr
addr = ln.Addr().String() 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 // Wait for the listener to be closed
var closed bool var closed bool
for i := 0; i < 10; i++ { 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 { if err != nil || conn == nil {
closed = true closed = true
break break

View File

@ -267,7 +267,7 @@ func Test_Utils_lnMetadata(t *testing.T) {
utils.AssertEqual(t, nil, ln.Close()) 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, ln.Addr().String(), addr)
utils.AssertEqual(t, true, config == nil) utils.AssertEqual(t, true, config == nil)
@ -278,7 +278,7 @@ func Test_Utils_lnMetadata(t *testing.T) {
utils.AssertEqual(t, nil, err) utils.AssertEqual(t, nil, err)
addr, config := lnMetadata(ln) addr, config := lnMetadata("tcp4", ln)
utils.AssertEqual(t, ln.Addr().String(), addr) utils.AssertEqual(t, ln.Addr().String(), addr)
utils.AssertEqual(t, true, config == nil) utils.AssertEqual(t, true, config == nil)
@ -295,7 +295,7 @@ func Test_Utils_lnMetadata(t *testing.T) {
ln = tls.NewListener(ln, config) ln = tls.NewListener(ln, config)
addr, config := lnMetadata(ln) addr, config := lnMetadata("tcp4", ln)
utils.AssertEqual(t, ln.Addr().String(), addr) utils.AssertEqual(t, ln.Addr().String(), addr)
utils.AssertEqual(t, true, config != nil) utils.AssertEqual(t, true, config != nil)

View File

@ -29,7 +29,7 @@ func IsChild() bool {
} }
// prefork manages child processes to make use of the OS REUSEPORT or REUSEADDR feature // 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 👶 // 👶 child process 👶
if IsChild() { if IsChild() {
// use 1 cpu core per child process // 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 var ln net.Listener
// Linux will use SO_REUSEPORT and Windows falls back to SO_REUSEADDR // Linux will use SO_REUSEPORT and Windows falls back to SO_REUSEADDR
// Only tcp4 or tcp6 is supported when preforking, both are not supported // 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 { if !app.config.DisableStartupMessage {
time.Sleep(100 * time.Millisecond) // avoid colliding with startup message time.Sleep(100 * time.Millisecond) // avoid colliding with startup message
} }

View File

@ -23,7 +23,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) {
app := New() app := New()
err := app.prefork("invalid", nil) err := app.prefork("tcp4", "invalid", nil)
utils.AssertEqual(t, false, err == nil) utils.AssertEqual(t, false, err == nil)
go func() { 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.Shutdown())
}() }()
utils.AssertEqual(t, nil, app.prefork("[::]:", nil)) utils.AssertEqual(t, nil, app.prefork("tcp6", "[::]:", nil))
// Create tls certificate // Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") 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.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) { 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.Shutdown())
}() }()
utils.AssertEqual(t, nil, app.prefork(":3000", nil)) utils.AssertEqual(t, nil, app.prefork("tcp4", ":3000", nil))
dummyChildCmd = "invalid" 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) utils.AssertEqual(t, false, err == nil)
} }