class

ServerX::AppServer

Inherits ServerX::PooledServer < Reference < Object

The production server: the pooled zero-alloc transport driving a stock HTTP::Handler. Framing — keep-alive, pipelining, Content-Length and chunked request bodies, body draining, hard limits — is decided by the transport (see PooledServer); the handler sees a standard HTTP::Server::Context and any Crystal framework works on top.

The HTTP::Server::Response is allocated once per connection and reused across keep-alive requests via Response#reset (the same trick the stdlib RequestProcessor plays). The request body is exposed through a reader that serves straight from the connection buffer and streams from the socket for bodies larger than the buffer.

Constants

HEADER_NAMES = {"Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Authorization", "Cache-Control", "Connection", "Content-Disposition", "Content-Encoding", "Content-Length", "Content-Range", "Content-Type", "Cookie", "Date", "ETag", "Expect", "If-Match", "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Keep-Alive", "Last-Modified", "Location", "Origin", "Proxy-Authorization", "Range", "Referer", "Server", "TE", "Transfer-Encoding", "Upgrade", "User-Agent", "X-Forwarded-For", "X-Forwarded-Proto", "X-Real-IP", "X-Request-Id", "Sec-WebSocket-Key", "Sec-WebSocket-Version", "Sec-WebSocket-Protocol", "Sec-WebSocket-Extensions"}
Log = ::Log.for("serverx.app")
METHODS = {"GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH", "TRACE", "CONNECT"}

Interned HTTP vocabulary: methods and common header names are a small finite set, so the handler receives shared String literals instead of fresh allocations (Crystal strings are immutable — sharing is safe; HTTP::Headers keys are case-insensitive, so canonicalizing the case of a known name is invisible to handlers). Unknown names fall back to a normal allocation.

Constructors

new(handler : HTTP::Handler, host : String, port : Int32, stats : Stats = Stats.new, **opts)
Source

Nested types