class
HTTP::Server
- HTTP::Server
- Reference
- Object
Overview
A concurrent HTTP server implementation.
A server is initialized with a handler chain responsible for processing each incoming request.
NOTE To use Server, you must explicitly import it with require "http/server"
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello world!"
end
address = server.bind_tcp 8080
puts "Listening on http://#{address}"
server.listen
Request processing
The handler chain receives an instance of HTTP::Server::Context that holds
the HTTP::Request to process and a HTTP::Server::Response which it can
configure and write to.
Each connection is processed concurrently in a separate Fiber and can handle
multiple subsequent requests-response cycles with connection keep-alive.
Handler chain
The handler given to a server can simply be a block that receives an HTTP::Server::Context,
or it can be an instance of HTTP::Handler. An HTTP::Handler has a #next
method to forward processing to the next handler in the chain.
For example, an initial handler might handle exceptions raised from subsequent
handlers and return a 500 Server Error status (see HTTP::ErrorHandler).
The next handler might log all incoming requests (see HTTP::LogHandler).
And the final handler deals with routing and application logic.
require "http/server"
server = HTTP::Server.new([
HTTP::ErrorHandler.new,
HTTP::LogHandler.new,
HTTP::CompressHandler.new,
HTTP::StaticFileHandler.new("."),
])
server.bind_tcp "127.0.0.1", 8080
server.listen
Response object
The HTTP::Server::Response object has status and headers properties that can be
configured before writing the response body. Once any response output has been
written, changing the status and headers properties has no effect.
The HTTP::Server::Response is a write-only IO, so all IO methods are available
on it for sending the response body.
Binding to sockets
The server can be bound to one or more server sockets (see #bind)
Supported types:
- TCP socket:
#bind_tcp,#bind_unused_port - TCP socket with TLS/SSL:
#bind_tls - Unix socket
#bind_unix
#bind(uri : URI) and #bind(uri : String) parse socket configuration for
one of these types from an URI. This can be useful for injecting plain text
configuration values.
Each of these methods returns the Socket::Address that was added to this
server.
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello world!"
end
address = server.bind_tcp "0.0.0.0", 8080
puts "Listening on http://#{address}"
server.listen
It is also possible to bind a generic Socket::Server using
#bind(socket : Socket::Server) which can be used for custom network protocol
configurations.
Server loop
After defining all server sockets to listen to, the server can be started by
calling #listen. This call blocks until the server is closed.
A server can be closed by calling #close. This closes the server sockets and
stops processing any new requests, even on connections with keep-alive enabled.
Currently processing requests are not interrupted but also not waited for.
In order to give them some grace period for finishing, the calling context
can add a timeout like sleep 10.seconds after #listen returns.
Reusing connections
The request processor supports reusing a connection for subsequent
requests. This is used by default for HTTP/1.1 or when requested by
the Connection: keep-alive header. This is signalled by this header being
set on the HTTP::Server::Response when it's passed into the handler chain.
If in the handler chain this header is overridden to Connection: close, then
the connection will not be reused after the request has been processed.
Reusing the connection also requires that the request body (if present) is entirely consumed in the handler chain. Otherwise the connection will be closed.
Defined in:
core_ext/http_server.crcore_ext/http_server_context.cr
core_ext/http_server_response.cr:3
core_ext/http_server_response.cr:168
Constructors
-
.new(handler : HTTP::Handler | HTTP::Handler::HandlerProc)
Creates a new HTTP server with the given handler.
Instance Method Summary
-
#bind_tls(host : String, port : Int32, context : OpenSSL::SSL::Context::Server, reuse_port : Bool = false) : Socket::IPAddress
Creates an
OpenSSL::SSL::Serverand adds it as a socket. -
#max_headers_size : Int32
TODO respect max_headers_size
-
#max_headers_size=(max_headers_size : Int32)
TODO respect max_headers_size
-
#max_request_line_size : Int32
TODO respect max_request_line_size
-
#max_request_line_size=(max_request_line_size : Int32)
TODO respect max_request_line_size
Constructor Detail
Creates a new HTTP server with the given handler.
Instance Method Detail
Creates an OpenSSL::SSL::Server and adds it as a socket.
The SSL server wraps a TCPServer listening on host:port.
require "http/server"
server = HTTP::Server.new { }
context = OpenSSL::SSL::Context::Server.new
context.certificate_chain = "openssl.crt"
context.private_key = "openssl.key"
server.bind_tls "127.0.0.1", 8080, context