/
server.cr
64 lines (57 loc) · 1.88 KB
/
server.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
require "http/server"
# The Onyx REST server. Basically it is just a wrapper around default `HTTP::Server`,
# which logs server start and stop events.
#
# ```
# server = Onyx::REST::Server.new(handlers, name: "My App Server")
# server.bind_tcp("0.0.0.0", 5000)
# server.listen
#
# # I [19:58:45.947] My App Server is listening at http://127.0.0.1:5000
# # I [19:58:48.479] My App Server is shutting down!
# ```
class Onyx::REST::Server < HTTP::Server
# Initialize with an array of *handlers*.
def initialize(
handlers : Array,
*,
@name : String = "Onyx::REST::Server",
@logger : Logger? = Logger.new(STDOUT),
@logger_severity : Logger::Severity = Logger::INFO
)
super(HTTP::Server.build_middleware(handlers.map(&.as(HTTP::Handler))))
end
# Initialize with a single *handler*.
def self.new(handler : HTTP::Handler, *args, **nargs)
new([handler], *args, **nargs)
end
# Start listening for requests. Blocks the runtime, just like the vanilla `HTTP::Server`.
def listen
if logger = @logger
io = IO::Memory.new
io << "⬛".colorize(:green).mode(:bold) << " " << @name
io << " is listening at ".colorize(:light_gray)
io << @sockets.join(", ") { |s| format_address(s) }
logger.log(@logger_severity, io.to_s)
end
Signal::INT.trap do
if logger = @logger
puts "\n"
io = IO::Memory.new
io << "⬛".colorize(:red).mode(:bold) << " " << @name
io << " is shutting down!".colorize(:light_gray)
logger.not_nil!.log(@logger_severity, io.to_s)
end
exit
end
super
end
protected def format_address(socket : Socket::Server)
case socket
when OpenSSL::SSL::Server then "https://#{socket.local_address}"
when TCPServer then "http://#{socket.local_address}"
when UNIXServer then "#{socket.path}"
else "?"
end
end
end