mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
net.http: add a close method to immediatly close the listener of a started http.Server, add more tests (#11248)
This commit is contained in:
@@ -7,12 +7,24 @@ import io
|
||||
import net
|
||||
import time
|
||||
|
||||
// ServerStatus is the current status of the server.
|
||||
// .running means that the server is active and serving.
|
||||
// .stopped means that the server is not active but still listening.
|
||||
// .closed means that the server is completely inactive.
|
||||
pub enum ServerStatus {
|
||||
running
|
||||
stopped
|
||||
closed
|
||||
}
|
||||
|
||||
interface Handler {
|
||||
handle(Request) Response
|
||||
}
|
||||
|
||||
pub struct Server {
|
||||
stop_signal chan bool = chan bool{cap: 1}
|
||||
mut:
|
||||
state ServerStatus = .closed
|
||||
listener net.TcpListener
|
||||
pub mut:
|
||||
port int = 8080
|
||||
handler Handler = DebugHandler{}
|
||||
@@ -21,22 +33,20 @@ pub mut:
|
||||
accept_timeout time.Duration = 30 * time.second
|
||||
}
|
||||
|
||||
pub fn (s &Server) listen_and_serve() ? {
|
||||
pub fn (mut s Server) listen_and_serve() ? {
|
||||
if s.handler is DebugHandler {
|
||||
eprintln('Server handler not set, using debug handler')
|
||||
}
|
||||
mut l := net.listen_tcp(.ip6, ':$s.port') ?
|
||||
l.set_accept_timeout(s.accept_timeout)
|
||||
s.listener = net.listen_tcp(.ip6, ':$s.port') ?
|
||||
s.listener.set_accept_timeout(s.accept_timeout)
|
||||
eprintln('Listening on :$s.port')
|
||||
s.state = .running
|
||||
for {
|
||||
// break if we have a stop signal (non-blocking check)
|
||||
select {
|
||||
_ := <-s.stop_signal {
|
||||
break
|
||||
}
|
||||
else {}
|
||||
// break if we have a stop signal
|
||||
if s.state != .running {
|
||||
break
|
||||
}
|
||||
mut conn := l.accept() or {
|
||||
mut conn := s.listener.accept() or {
|
||||
if err.msg != 'net: op timed out' {
|
||||
eprintln('accept() failed: $err; skipping')
|
||||
}
|
||||
@@ -47,10 +57,27 @@ pub fn (s &Server) listen_and_serve() ? {
|
||||
// TODO: make concurrent
|
||||
s.parse_and_respond(mut conn)
|
||||
}
|
||||
if s.state == .stopped {
|
||||
s.close()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (s Server) stop() {
|
||||
s.stop_signal <- true
|
||||
// stop signals the server that it should not respond anymore
|
||||
[inline]
|
||||
pub fn (mut s Server) stop() {
|
||||
s.state = .stopped
|
||||
}
|
||||
|
||||
// close immediatly closes the port and signals the server that it has been closed
|
||||
[inline]
|
||||
pub fn (mut s Server) close() {
|
||||
s.state = .closed
|
||||
s.listener.close() or { return }
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (s &Server) status() ServerStatus {
|
||||
return s.state
|
||||
}
|
||||
|
||||
fn (s &Server) parse_and_respond(mut conn net.TcpConn) {
|
||||
|
||||
Reference in New Issue
Block a user