Open
Description
Bug Report
Using the logger to print any kind of message (Log.setup
doesn't seem to trigger this) results in the HTTP::Server infinitely spamming logs whenever the file descriptor limit is reached.
require "http/server"
Log.info { "test" }
server = HTTP::Server.new do | context |
loop do
context.response.puts ":keepalive #{Time.utc.to_unix}"
context.response.puts
context.response.flush
sleep 2.seconds
end
end
server.listen 12345
Results in
2025-06-01T19:01:40.364067Z ERROR - http.server: Error while connecting a new socket
accept: Too many open files (Socket::Error)
...
2025-06-01T19:01:40.364070Z ERROR - http.server: Error while connecting a new socket
accept: Too many open files (Socket::Error)
...
2025-06-01T19:01:40.364074Z ERROR - http.server: Error while connecting a new socket
accept: Too many open files (Socket::Error)
...
and so on
When the logger isn't present, the program just crashes instantly and only two exceptions are logged.
Crystal 1.16.0 (2025-04-11)
LLVM: 19.1.7
Default target: x86_64-pc-linux-gnu
Here's a simple script that can trigger this bug in the above code
Simple request to spam request a server to trigger this
require "http"
require "wait_group"
ADDRESS = URI.parse("http://localhost:12345")
def make_client
client = HTTP::Client.new(ADDRESS)
client.get("/") do | response |
until response.body_io.closed?
response.body_io.gets
end
end
ensure
client.try &.close
end
5.times do
clients_opened = [] of HTTP::Client
# Create in batches as to not trigger our own file descriptor limit
250.times { spawn { make_client } }
end
sleep