Skip to content

Commit

Permalink
feat: allow to get the network address server is listening on (open-t…
Browse files Browse the repository at this point in the history
…elemetry#217)

Add an Addr() method to fetch the network address Server is listening on. I think this may be useful for the supervisor to start a server with 0 port to allocate an ephemeral port and get the allocated port for rendering an agent config.
  • Loading branch information
haoqixu authored Dec 14, 2023
1 parent fc9dfe6 commit ca0e1e6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
5 changes: 5 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,9 @@ type OpAMPServer interface {
// Stop accepting new connections and close all current connections. This should
// block until all connections are closed.
Stop(ctx context.Context) error

// Addr returns the network address Server is listening on. Nil if not started.
// Typically used to fetch the port when ListenEndpoint's port is specified as 0 to
// allocate an ephemeral port.
Addr() net.Addr
}
8 changes: 8 additions & 0 deletions server/serverimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type server struct {
// The listening HTTP Server after successful Start() call. Nil if Start()
// is not called or was not successful.
httpServer *http.Server

// The network address Server is listening on. Nil if not started.
addr net.Addr
}

var _ OpAMPServer = (*server)(nil)
Expand Down Expand Up @@ -118,6 +121,7 @@ func (s *server) startHttpServer(listenAddr string, serveFunc func(l net.Listene
if err != nil {
return err
}
s.addr = ln.Addr()

// Begin serving connections in the background.
go func() {
Expand All @@ -143,6 +147,10 @@ func (s *server) Stop(ctx context.Context) error {
return nil
}

func (s *server) Addr() net.Addr {
return s.addr
}

func (s *server) httpHandler(w http.ResponseWriter, req *http.Request) {
var connectionCallbacks serverTypes.ConnectionCallbacks
if s.settings.Callbacks != nil {
Expand Down
42 changes: 42 additions & 0 deletions server/serverimpl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,48 @@ func TestServerStartStop(t *testing.T) {
assert.NoError(t, err)
}

func TestServerAddrWithNonZeroPort(t *testing.T) {
srv := New(&sharedinternal.NopLogger{})
require.NotNil(t, srv)

// Nil if not started
assert.Nil(t, srv.Addr())

addr := testhelpers.GetAvailableLocalAddress()

err := srv.Start(StartSettings{
ListenEndpoint: addr,
ListenPath: "/",
})
assert.NoError(t, err)

assert.Equal(t, addr, srv.Addr().String())

err = srv.Stop(context.Background())
assert.NoError(t, err)
}

func TestServerAddrWithZeroPort(t *testing.T) {
srv := New(&sharedinternal.NopLogger{})
require.NotNil(t, srv)

// Nil if not started
assert.Nil(t, srv.Addr())

err := srv.Start(StartSettings{
ListenEndpoint: "127.0.0.1:0",
ListenPath: "/",
})
assert.NoError(t, err)

// should be listening on an non-zero ephemeral port
assert.NotEqual(t, "127.0.0.1:0", srv.Addr().String())
assert.Regexp(t, `^127.0.0.1:\d+`, srv.Addr().String())

err = srv.Stop(context.Background())
assert.NoError(t, err)
}

func TestServerStartRejectConnection(t *testing.T) {
callbacks := CallbacksStruct{
OnConnectingFunc: func(request *http.Request) types.ConnectionResponse {
Expand Down

0 comments on commit ca0e1e6

Please sign in to comment.