Skip to content

Commit

Permalink
Merge pull request #19 from ninedraft/fix-server-listen-cancelation
Browse files Browse the repository at this point in the history
  • Loading branch information
ninedraft committed Apr 3, 2021
2 parents 577f10c + 9e368ed commit 72bf34f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
27 changes: 27 additions & 0 deletions gemax/internal/testaddr/testaddr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Package testaddr selects free port for testing purposes.
package testaddr

import (
"fmt"
"net"
)

const localAddr = "localhost:0"

// Addr returns free address in form of "localhost:$FREE_PORT",
// which can be used for test servers.
func Addr() string {
var listener, errListener = net.Listen("tcp", localAddr)
if errListener != nil {
var msg = fmt.Sprintf("resolving address %q: %v", localAddr, errListener)
panic(msg)
}
var addr = listener.Addr()
_ = listener.Close()
var _, port, errSplit = net.SplitHostPort(addr.String())
if errSplit != nil {
var msg = fmt.Sprintf("parsing address %q: %v", addr, errSplit)
panic(msg)
}
return "localhost:" + port
}
10 changes: 9 additions & 1 deletion gemax/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,18 @@ func (server *Server) init() {
// ListenAndServe starts a TLS gemini server at specified server.
func (server *Server) ListenAndServe(ctx context.Context, tlsCfg *tls.Config) error {
server.init()
var listener, errListener = tls.Listen("tcp", server.Addr, tlsCfg)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
var lc = net.ListenConfig{}
var tcpListener, errListener = lc.Listen(ctx, "tcp", server.Addr)
if errListener != nil {
return fmt.Errorf("creating listener: %w", errListener)
}
var listener = tls.NewListener(tcpListener, tlsCfg)
go func() {
<-ctx.Done()
_ = listener.Close()
}()
server.addListener(listener)
defer ignoreErr(listener.Close)
return server.Serve(ctx, listener)
Expand Down
30 changes: 30 additions & 0 deletions gemax/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/ninedraft/gemax/gemax"
"github.com/ninedraft/gemax/gemax/internal/testaddr"
"github.com/ninedraft/gemax/gemax/status"
)

Expand Down Expand Up @@ -68,6 +69,35 @@ func TestServerInvalidHost(test *testing.T) {
expectResponse(test, resp, "50 host not found\r\n")
}

func TestServerCancelListen(test *testing.T) {
var server = &gemax.Server{
Addr: testaddr.Addr(),
Logf: test.Logf,
Handler: func(ctx context.Context, rw gemax.ResponseWriter, req gemax.IncomingRequest) {
_, _ = io.WriteString(rw, "example text")
},
}
test.Logf("loading test certs")
var cert, errCert = tls.LoadX509KeyPair("testdata/cert.pem", "testdata/key.pem")
if errCert != nil {
test.Fatal(errCert)
}
var cfg = &tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{cert},
}
var ctx, cancel = context.WithCancel(context.Background())
test.Cleanup(cancel)
test.Logf("starting test server")
test.Logf("test server: listening on %q", server.Addr)

time.AfterFunc(100*time.Millisecond, cancel)
var err = server.ListenAndServe(ctx, cfg)
if !errors.Is(err, net.ErrClosed) {
test.Errorf("unexpected error %v, while %q is expected", err, net.ErrClosed)
}
}

func TestListenAndServe(test *testing.T) {
var server = &gemax.Server{
Addr: "localhost:40423",
Expand Down

0 comments on commit 72bf34f

Please sign in to comment.