Skip to content

Commit 7bcbf19

Browse files
authored
fix: print correct listen adress in coder server (coder#5634)
1 parent 68324c7 commit 7bcbf19

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

cli/server.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,20 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
226226
}
227227
defer httpListener.Close()
228228

229+
listenAddrStr := httpListener.Addr().String()
230+
// For some reason if 0.0.0.0:x is provided as the http address,
231+
// httpListener.Addr().String() likes to return it as an ipv6
232+
// address (i.e. [::]:x). If the input ip is 0.0.0.0, try to
233+
// coerce the output back to ipv4 to make it less confusing.
234+
if strings.Contains(cfg.HTTPAddress.Value, "0.0.0.0") {
235+
listenAddrStr = strings.ReplaceAll(listenAddrStr, "[::]", "0.0.0.0")
236+
}
237+
238+
// We want to print out the address the user supplied, not the
239+
// loopback device.
240+
cmd.Println("Started HTTP listener at", (&url.URL{Scheme: "http", Host: listenAddrStr}).String())
241+
242+
// Set the http URL we want to use when connecting to ourselves.
229243
tcpAddr, tcpAddrValid := httpListener.Addr().(*net.TCPAddr)
230244
if !tcpAddrValid {
231245
return xerrors.Errorf("invalid TCP address type %T", httpListener.Addr())
@@ -237,7 +251,6 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
237251
Scheme: "http",
238252
Host: tcpAddr.String(),
239253
}
240-
cmd.Println("Started HTTP listener at " + httpURL.String())
241254
}
242255

243256
var (
@@ -269,6 +282,22 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
269282
httpsListener = tls.NewListener(httpsListenerInner, tlsConfig)
270283
defer httpsListener.Close()
271284

285+
listenAddrStr := httpsListener.Addr().String()
286+
// For some reason if 0.0.0.0:x is provided as the https
287+
// address, httpsListener.Addr().String() likes to return it as
288+
// an ipv6 address (i.e. [::]:x). If the input ip is 0.0.0.0,
289+
// try to coerce the output back to ipv4 to make it less
290+
// confusing.
291+
if strings.Contains(cfg.HTTPAddress.Value, "0.0.0.0") {
292+
listenAddrStr = strings.ReplaceAll(listenAddrStr, "[::]", "0.0.0.0")
293+
}
294+
295+
// We want to print out the address the user supplied, not the
296+
// loopback device.
297+
cmd.Println("Started TLS/HTTPS listener at", (&url.URL{Scheme: "https", Host: listenAddrStr}).String())
298+
299+
// Set the https URL we want to use when connecting to
300+
// ourselves.
272301
tcpAddr, tcpAddrValid := httpsListener.Addr().(*net.TCPAddr)
273302
if !tcpAddrValid {
274303
return xerrors.Errorf("invalid TCP address type %T", httpsListener.Addr())
@@ -280,7 +309,6 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
280309
Scheme: "https",
281310
Host: tcpAddr.String(),
282311
}
283-
cmd.Println("Started TLS/HTTPS listener at " + httpsURL.String())
284312
}
285313

286314
// Sanity check that at least one listener was started.

cli/server_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,58 @@ func TestServer(t *testing.T) {
674674
}
675675
})
676676

677+
t.Run("CanListenUnspecifiedv4", func(t *testing.T) {
678+
t.Parallel()
679+
ctx, cancelFunc := context.WithCancel(context.Background())
680+
defer cancelFunc()
681+
682+
root, _ := clitest.New(t,
683+
"server",
684+
"--in-memory",
685+
"--http-address", "0.0.0.0:0",
686+
"--access-url", "http://example.com",
687+
)
688+
689+
pty := ptytest.New(t)
690+
root.SetOutput(pty.Output())
691+
root.SetErr(pty.Output())
692+
errC := make(chan error, 1)
693+
go func() {
694+
errC <- root.ExecuteContext(ctx)
695+
}()
696+
697+
pty.ExpectMatch("Started HTTP listener at http://0.0.0.0:")
698+
699+
cancelFunc()
700+
require.NoError(t, <-errC)
701+
})
702+
703+
t.Run("CanListenUnspecifiedv6", func(t *testing.T) {
704+
t.Parallel()
705+
ctx, cancelFunc := context.WithCancel(context.Background())
706+
defer cancelFunc()
707+
708+
root, _ := clitest.New(t,
709+
"server",
710+
"--in-memory",
711+
"--http-address", "[::]:0",
712+
"--access-url", "http://example.com",
713+
)
714+
715+
pty := ptytest.New(t)
716+
root.SetOutput(pty.Output())
717+
root.SetErr(pty.Output())
718+
errC := make(chan error, 1)
719+
go func() {
720+
errC <- root.ExecuteContext(ctx)
721+
}()
722+
723+
pty.ExpectMatch("Started HTTP listener at http://[::]:")
724+
725+
cancelFunc()
726+
require.NoError(t, <-errC)
727+
})
728+
677729
t.Run("NoAddress", func(t *testing.T) {
678730
t.Parallel()
679731
ctx, cancelFunc := context.WithCancel(context.Background())

0 commit comments

Comments
 (0)