fiber icon indicating copy to clipboard operation
fiber copied to clipboard

🐛 Prefork bails out with panic message "listen tcp bind: address already in use"

Open softexpert opened this issue 3 years ago • 2 comments

Fiber version 2.7.1

Issue description On my Linux laptop and also on another Linux VM server, if I enable the Prefork flag, I get the following panic message panic: listen tcp :7777: bind: address already in use

Here is the code to reproduce the issue:

Code snippet

package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"time"

	"github.com/gofiber/fiber/v2"
	"golang.org/x/crypto/acme/autocert"
)


func main() {
	var isProd bool = true

	app := fiber.New(fiber.Config{Prefork: isProd})

	app.Get("/test", func(c *fiber.Ctx) error {
		fmt.Printf("ProcessId: %v, %v, isChild: %v\t", os.Getpid(), os.Getppid(), fiber.IsChild())
		rand.Seed(time.Now().UnixNano())
		n := rand.Intn(10) // n will be between 0 and 10
		//fmt.Printf("Sleeping %d seconds...\n", n)
		time.Sleep(time.Duration(n) * time.Second)

		return c.SendStatus(200)
	})

	// Certificate manager
	m := &autocert.Manager{
		Prompt: autocert.AcceptTOS,
		// Replace with your domain
		HostPolicy: autocert.HostWhitelist("mydomain"), // <-- please change for your domain
		// Folder to store the certificates
		Cache: autocert.DirCache(makeAbsPath("./certs")),
	}

	// TLS Config
	tlsCfg := &tls.Config{
		// Get Certificate from Let's Encrypt
		GetCertificate: m.GetCertificate,
		// By default NextProtos contains the "h2"
		// This has to be removed since Fasthttp does not support HTTP/2
		// Or it will cause a flood of PRI method logs
		// http://webconcepts.info/concepts/http-method/PRI
		NextProtos: []string{
			"http/1.1", "acme-tls/1",
		},
	}

	// Create custom listener
	ln, err := tls.Listen("tcp", ":7777", tlsCfg)
	if err != nil {
		// sentry.CaptureException(err)
		panic(err)
	}

	if err = app.Listener(ln); err != nil {
		log.Fatal(err)
	}

}

// makeAbsPath transforms a relative path in an absolute path
func makeAbsPath(fp string) string {
	var rp string
	var err error

	if filepath.IsAbs(fp) {
		return fp
	}

	if rp, err = filepath.Abs(fp); err != nil {
		return rp
	}

	return rp
}

softexpert avatar Mar 31 '21 20:03 softexpert

Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

welcome[bot] avatar Mar 31 '21 20:03 welcome[bot]

Replacing

	// Create custom listener
	ln, err := tls.Listen("tcp", ":7777", tlsCfg)
	if err != nil {
		// sentry.CaptureException(err)
		panic(err)
	}

	if err = app.Listener(ln); err != nil {
		log.Fatal(err)
	}

with

       var ln net.Listener
	var err error

	if ln, err = reuseport.Listen("tcp4", ":7777"); err != nil {
		log.Fatal(err)
	}
	// wrap a tls config around the listener if provided
	if tlsCfg != nil {
		ln = tls.NewListener(ln, tlsCfg)
	}

The error messages become a little richer : panic: panic: listener: 0.0.0.0:7777: Only one usage of each socket address (protocol/network address/port) is normally permitted.listener: 0.0.0.0:7777: Only one usage of each socket address (protocol/network address/port) is normally permitted.

softexpert avatar Mar 31 '21 20:03 softexpert

I think this is a bug that's related to https://github.com/gofiber/fiber/blob/master/helpers.go#L29.

efectn avatar Aug 26 '22 19:08 efectn