@@ -57,12 +57,16 @@ func TestServer(t *testing.T) {
5757 })
5858
5959 http2Cfg := & http.HTTP2Config {}
60+ customListenConfig := & net.ListenConfig {
61+ KeepAlive : 1 * time .Minute ,
62+ }
6063 s , err := New (Options {
6164 MaxHeaderBytes : 123 ,
6265 ConnState : func (_ net.Conn , _ http.ConnState ) {},
6366 BaseContext : func (_ net.Listener ) context.Context { return context .Background () },
6467 ConnContext : func (ctx context.Context , _ net.Conn ) context.Context { return ctx },
6568 HTTP2 : http2Cfg ,
69+ ListenConfig : customListenConfig ,
6670 })
6771 require .NoError (t , err )
6872
@@ -85,6 +89,7 @@ func TestServer(t *testing.T) {
8589 assert .NotNil (t , s .baseContext )
8690 assert .NotNil (t , s .server .BaseContext )
8791 assert .Same (t , http2Cfg , s .server .HTTP2 )
92+ assert .Same (t , customListenConfig , s .listenConfig )
8893 assert .Equal (t , "http://127.0.0.1:8080" , s .BaseURL ())
8994 assert .Equal (t , "http://127.0.0.1:8080" , s .ProxyBaseURL ())
9095 assert .NoError (t , s .CloseDB ())
@@ -696,6 +701,83 @@ func TestServer(t *testing.T) {
696701 assert .Equal (t , "cannot start the server, context is canceled" , err .Error ())
697702 }
698703 })
704+
705+ t .Run ("StartWithCustomListenConfig" , func (t * testing.T ) {
706+ cfg := config .LoadDefault ()
707+ cfg .Set ("server.port" , 0 )
708+
709+ customListenConfig := & net.ListenConfig {
710+ KeepAlive : 1 * time .Minute ,
711+ }
712+
713+ server , err := New (Options {
714+ Config : cfg ,
715+ ListenConfig : customListenConfig ,
716+ })
717+ require .NoError (t , err )
718+
719+ wg := sync.WaitGroup {}
720+ wg .Add (2 )
721+
722+ server .RegisterStartupHook (func (s * Server ) {
723+ assert .True (t , server .IsReady ())
724+ assert .NotEqual (t , 0 , s .Port ())
725+
726+ res , err := http .Get (s .BaseURL ())
727+ defer func () {
728+ assert .NoError (t , res .Body .Close ())
729+ }()
730+ assert .NoError (t , err )
731+ respBody , err := io .ReadAll (res .Body )
732+ assert .NoError (t , err )
733+ assert .Equal (t , []byte ("hello world" ), respBody )
734+
735+ server .Stop ()
736+ wg .Done ()
737+ })
738+
739+ server .RegisterRoutes (func (_ * Server , router * Router ) {
740+ router .Get ("/" , func (r * Response , _ * Request ) {
741+ r .String (http .StatusOK , "hello world" )
742+ }).Name ("base" )
743+ })
744+
745+ go func () {
746+ err := server .Start ()
747+ assert .NoError (t , err )
748+ wg .Done ()
749+ }()
750+
751+ wg .Wait ()
752+ assert .False (t , server .IsReady ())
753+ assert .Equal (t , uint32 (3 ), server .state .Load ())
754+ })
755+
756+ t .Run ("StartWithCustomListenConfigControlError" , func (t * testing.T ) {
757+ cfg := config .LoadDefault ()
758+ cfg .Set ("server.port" , 0 )
759+
760+ // Create a custom ListenConfig with a Control function that always returns an error
761+ // to ensure that the custom config is correctly used if provided.
762+ // The StartWithCustomListenConfig test only checks that the server still works and is able
763+ // to process requests with the custom config.
764+ expectedErr := fmt .Errorf ("test control error" )
765+ customListenConfig := & net.ListenConfig {
766+ Control : func (_ , _ string , _ syscall.RawConn ) error {
767+ return expectedErr
768+ },
769+ }
770+
771+ server , err := New (Options {
772+ Config : cfg ,
773+ ListenConfig : customListenConfig ,
774+ })
775+ require .NoError (t , err )
776+
777+ // Attempt to start the server - it should fail with the error from Control
778+ err = server .Start ()
779+ assert .ErrorIs (t , err , expectedErr )
780+ })
699781}
700782
701783func TestNoServerFromContext (t * testing.T ) {
0 commit comments