Skip to content

Commit

Permalink
Start server with fixed port when --port argument is provided
Browse files Browse the repository at this point in the history
It should immediately error when the port is occupied, instead of automatically finding the next port.
  • Loading branch information
ruudk committed Feb 23, 2022
1 parent 503c5ef commit 3bf0894
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
3 changes: 2 additions & 1 deletion local/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type ServerCallback func(w http.ResponseWriter, r *http.Request, env map[string]
type Server struct {
DocumentRoot string
Callback ServerCallback
Port int
PreferredPort int
PKCS12 string
AllowHTTP bool
Expand All @@ -59,7 +60,7 @@ type Server struct {

// Start starts the server
func (s *Server) Start(errChan chan error) (int, error) {
ln, port, err := process.CreateListener(s.PreferredPort)
ln, port, err := process.CreateListener(s.Port, s.PreferredPort)
if err != nil {
return port, errors.WithStack(err)
}
Expand Down
25 changes: 16 additions & 9 deletions local/process/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,40 @@ import (
// CreateListener creates a listener on a port
// Pass a preferred port (will increment by 1 if port is not available)
// or pass 0 to auto-find any available port
func CreateListener(preferredPort int) (net.Listener, int, error) {
func CreateListener(port, preferredPort int) (net.Listener, int, error) {
var ln net.Listener
var err error
port := preferredPort
tryPort := preferredPort
max := 50
if port > 0 {
tryPort = port
max = 1
}
for {
// we really want to test availability on 127.0.0.1
ln, err = net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(port))
ln, err = net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(tryPort))
if err == nil {
ln.Close()
// but then, we want to listen to as many local IP's as possible
ln, err = net.Listen("tcp", ":"+strconv.Itoa(port))
ln, err = net.Listen("tcp", ":"+strconv.Itoa(tryPort))
if err == nil {
break
}
}
if port > 0 {
return nil, 0, errors.Wrapf(err, "unable to listen on port %d", port)
}
if preferredPort == 0 {
return nil, 0, errors.Wrap(err, "unable to find an available port")
}
max--
if max == 0 {
return nil, 0, errors.Wrapf(err, "unable to find an available port (from %d to %d)", preferredPort, port)
return nil, 0, errors.Wrapf(err, "unable to find an available port (from %d to %d)", preferredPort, tryPort)
}
port++
tryPort++
}
if preferredPort == 0 {
port = ln.Addr().(*net.TCPAddr).Port
if port == 0 && preferredPort == 0 {
tryPort = ln.Addr().(*net.TCPAddr).Port
}
return ln, port, nil
return ln, tryPort, nil
}
5 changes: 3 additions & 2 deletions local/project/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Config struct {
ProjectDir string
DocumentRoot string `yaml:"document_root"`
Passthru string `yaml:"passthru"`
Port int `yaml:"port"`
PreferredPort int `yaml:"preferred_port"`
PKCS12 string `yaml:"p12"`
Logger zerolog.Logger
Expand Down Expand Up @@ -85,9 +86,9 @@ func NewConfigFromContext(c *console.Context, projectDir string) (*Config, *File
config.Passthru = c.String("passthru")
}
if c.IsSet("port") {
config.PreferredPort = c.Int("port")
config.Port = c.Int("port")
}
if config.PreferredPort == 0 {
if config.Port == 0 {
config.PreferredPort = 8000
}
if c.IsSet("allow-http") {
Expand Down
1 change: 1 addition & 0 deletions local/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func New(c *Config) (*Project, error) {
projectDir: c.ProjectDir,
HTTP: &lhttp.Server{
DocumentRoot: documentRoot,
Port: c.Port,
PreferredPort: c.PreferredPort,
Logger: c.Logger,
PKCS12: c.PKCS12,
Expand Down

0 comments on commit 3bf0894

Please sign in to comment.