diff --git a/vlib/net/http/server.v b/vlib/net/http/server.v index d115cc13d2..48d32d6a55 100644 --- a/vlib/net/http/server.v +++ b/vlib/net/http/server.v @@ -25,16 +25,17 @@ mut: pub struct Server { mut: - state ServerStatus = .closed - listener net.TcpListener + state ServerStatus = .closed pub mut: - port int = 8080 + addr string = ':8080' // change to ':8080' when port is removed + port int [deprecated: 'use addr'] = 8080 handler Handler = DebugHandler{} read_timeout time.Duration = 30 * time.second write_timeout time.Duration = 30 * time.second accept_timeout time.Duration = 30 * time.second pool_channel_slots int = 1024 worker_num int = runtime.nr_jobs() + listener net.TcpListener } // listen_and_serve listens on the server port `s.port` over TCP network and @@ -43,10 +44,28 @@ pub fn (mut s Server) listen_and_serve() { if s.handler is DebugHandler { eprintln('Server handler not set, using debug handler') } - s.listener = net.listen_tcp(.ip6, ':${s.port}') or { - eprintln('Listening on :${s.port} failed') + + // remove when s.port is removed + addr := s.addr.split(':') + if addr.len > 1 && s.port != 8080 { + s.addr = '${addr[0]}:${s.port}' + } + + mut l := s.listener.addr() or { + eprintln('Failed getting listener address') return } + if l.family() == net.AddrFamily.unspec { + s.listener = net.listen_tcp(.ip6, '${s.addr}') or { + eprintln('Listening on ${s.addr} failed') + return + } + l = s.listener.addr() or { + eprintln('Failed getting listener address') + return + } + } + s.addr = l.str() s.listener.set_accept_timeout(s.accept_timeout) // Create tcp connection channel @@ -58,7 +77,7 @@ pub fn (mut s Server) listen_and_serve() { ws << new_handler_worker(wid, ch, s.handler) } - eprintln('Listening on :${s.port}') + eprintln('Listening on ${s.addr}') s.state = .running for { // break if we have a stop signal diff --git a/vlib/net/http/server_test.v b/vlib/net/http/server_test.v index a151f61eef..74f6dd8a95 100644 --- a/vlib/net/http/server_test.v +++ b/vlib/net/http/server_test.v @@ -1,3 +1,4 @@ +import net import net.http import time @@ -30,6 +31,22 @@ fn test_server_close() { assert watch.elapsed() < 999 * time.millisecond } +fn test_server_custom_listener() { + listener := net.listen_tcp(.ip6, ':8081')! + mut server := &http.Server{ + accept_timeout: 1 * time.second + listener: listener + } + t := spawn server.listen_and_serve() + time.sleep(250 * time.millisecond) + mut watch := time.new_stopwatch() + server.close() + assert server.status() == .closed + assert watch.elapsed() < 100 * time.millisecond + t.wait() + assert watch.elapsed() < 999 * time.millisecond +} + struct MyHttpHandler { mut: counter int