class

Kemal::Config

Inherits Reference < Object

Stores all the configuration options for a Kemal application. It's a singleton and you can access it like.

Kemal.config

Constants

CUSTOM_HANDLERS = [] of Tuple(Int32 | ::Nil, HTTP::Handler)
ERROR_HANDLERS = {} of Int32 => (HTTP::Server::Context, Exception -> String)
EXCEPTION_HANDLERS = {} of Exception.class => (HTTP::Server::Context, Exception -> String)
FILTER_HANDLERS = [] of HTTP::Handler
HANDLERS = [] of HTTP::Handler
INSTANCE = Config.new

Constructors

Instance methods

add_error_handler(status_code : Int32, &handler : HTTP::Server::Context, Exception -> _)

Adds an error handler for the given HTTP status code

Source
add_exception_handler(exception : Exception.class, &handler : HTTP::Server::Context, Exception -> _)

Adds an error handler for the given exception

Source
add_filter_handler(handler : HTTP::Handler)
Source
add_handler(handler : HTTP::Handler, position : Int32)
Source
add_handler(handler : HTTP::Handler)
Source
always_rescue
Source
always_rescue=(always_rescue : Bool)
Source
app_name
Source
app_name=(app_name : String)
Source
clear

Returns every setting to its default and empties the handler tables. Specs call this after each example; a setting clear forgets is one that leaks from the example that set it into the next.

Source
env=(env : String)
Source
error_handlers

Returns the defined error handlers for HTTP status codes

Source
exception_handlers

Returns the defined error handlers for exceptions

Source
extra_options
Source
extra_options
Source
extra_options=(extra_options : Nil | OptionParser -> _)
Source
handlers
Source
handlers=(handlers : Array(HTTP::Handler))
Source
host_binding
Source
host_binding=(host_binding : String)
Source
logger

DEPRECATED Use standard library Log

Source
logger=(logger : Kemal::BaseLogHandler)

DEPRECATED Use standard library Log

Source
logging
Source
logging=(logging : Bool)
Source
max_file_uploads

Maximum number of file parts accepted in a single multipart/form-data request.

Every file part is spooled to its own temporary file, which stays open until the request is over, so the count is what bounds the file descriptors and disk entries one request can hold — max_request_body_size does not: an 8 MB body fits some 100,000 one-byte parts. A request carrying more file parts than this is answered with 413 before the next one is written to disk; the ones already spooled are cleaned up with the request. Form fields without a filename do not count. 0 refuses file uploads altogether.

Source
max_file_uploads=(max_file_uploads : Int32)

Maximum number of file parts accepted in a single multipart/form-data request.

Every file part is spooled to its own temporary file, which stays open until the request is over, so the count is what bounds the file descriptors and disk entries one request can hold — max_request_body_size does not: an 8 MB body fits some 100,000 one-byte parts. A request carrying more file parts than this is answered with 413 before the next one is written to disk; the ones already spooled are cleaned up with the request. Form fields without a filename do not count. 0 refuses file uploads altogether.

Source
max_multipart_form_field_size
Source
max_multipart_form_field_size=(max_multipart_form_field_size : Int32)
Source
max_ranges

Maximum number of byte ranges accepted in a single Range request header.

A Range header listing more parts than this is ignored and the full representation is served with 200 instead. Since send_file also refuses range sets asking for more bytes in total than the file holds, a multi-range response stays within the file's own size plus roughly 150 bytes of multipart framing per part. Raising this therefore raises the framing a single request can ask for; 0 ignores Range headers entirely and advertises Accept-Ranges: none.

Without a bound, a header such as bytes=0-,0-,0-,... makes the server re-read the whole file once per range. RFC 9110 §14.2 explicitly allows rejecting such range sets, as they indicate "either a broken client or a deliberate denial-of-service attack".

Source
max_ranges=(max_ranges : Int32)

Maximum number of byte ranges accepted in a single Range request header.

A Range header listing more parts than this is ignored and the full representation is served with 200 instead. Since send_file also refuses range sets asking for more bytes in total than the file holds, a multi-range response stays within the file's own size plus roughly 150 bytes of multipart framing per part. Raising this therefore raises the framing a single request can ask for; 0 ignores Range headers entirely and advertises Accept-Ranges: none.

Without a bound, a header such as bytes=0-,0-,0-,... makes the server re-read the whole file once per range. RFC 9110 §14.2 explicitly allows rejecting such range sets, as they indicate "either a broken client or a deliberate denial-of-service attack".

Source
max_request_body_size
Source
max_request_body_size=(max_request_body_size : Int32)
Source
max_route_cache_size
Source
max_route_cache_size=(max_route_cache_size : Int32)
Source
port
Source
port=(port : Int32)
Source
powered_by_header=(powered_by_header : Bool)
Source
powered_by_header?
Source
public_folder
Source
public_folder=(public_folder : String)
Source
running
Source
running=(running : Bool)
Source
scheme
Source
serve_static
Source
serve_static=(serve_static : Bool | Hash(String, Bool))
Source
server
Source
server=(server : HTTP::Server | Nil)
Source
setup
Source
show_exceptions=(show_exceptions : Bool | Nil)

Whether an unhandled exception is answered with the development error page — exception message, backtrace with source, response headers, cookies — or the static production page that says nothing about the failure.

Unset (nil, the default) means "only in the development environment". Every other environment name, including one that is misspelt or unknown, gets the production page: the development page exists to debug locally, not to serve as the fallback for a KEMAL_ENV that failed to say production. Set it to true to show the page in another environment, or to false to never show it.

Source
show_exceptions?
Source
shutdown_message
Source
shutdown_message=(shutdown_message : Bool)
Source
shutdown_timeout

How long Kemal.run waits, once the server has been stopped, for the requests that were being served at that moment to finish. Nothing in flight: it returns at once. Still something in flight when the time is up: it logs a warning and returns anyway, so a stuck handler cannot hold a deploy hostage.

A WebSocket or SSE connection counts as in flight for as long as it stays open, so an application holding such connections waits the full time on every shutdown unless it closes them itself from the Kemal.run block or a Kemal.stop caller. A second termination signal during the wait exits immediately.

Source
shutdown_timeout=(shutdown_timeout : Time::Span)

How long Kemal.run waits, once the server has been stopped, for the requests that were being served at that moment to finish. Nothing in flight: it returns at once. Still something in flight when the time is up: it logs a warning and returns anyway, so a stuck handler cannot hold a deploy hostage.

A WebSocket or SSE connection counts as in flight for as long as it stays open, so an application holding such connections waits the full time on every shutdown unless it closes them itself from the Kemal.run block or a Kemal.stop caller. A second termination signal during the wait exits immediately.

Source
static_headers
Source
static_headers=(static_headers : HTTP::Server::Context, String, File::Info -> | Nil)
Source
websocket_allowed_origins

WebSocket Origin policy for upgrade requests.

  • Empty (default): same-origin — Origin must match the request Host (scheme is taken from Origin, so TLS termination in front of Kemal still works). Missing or empty Origin is rejected with 403.
  • Non-empty allowlist: Origin must match one of the entries after normalization (scheme/host/port only). Missing Origin is rejected.
  • Include "*" to allow any origin, including requests without Origin (previous allow-all behavior).
  • Use "null" to allow the browser's opaque "null" origin.

Entries use the serialized origin form, e.g. "https://example.com" or "http://localhost:3000".

Source
websocket_allowed_origins=(websocket_allowed_origins : Array(String))

WebSocket Origin policy for upgrade requests.

  • Empty (default): same-origin — Origin must match the request Host (scheme is taken from Origin, so TLS termination in front of Kemal still works). Missing or empty Origin is rejected with 403.
  • Non-empty allowlist: Origin must match one of the entries after normalization (scheme/host/port only). Missing Origin is rejected.
  • Include "*" to allow any origin, including requests without Origin (previous allow-all behavior).
  • Use "null" to allow the browser's opaque "null" origin.

Entries use the serialized origin form, e.g. "https://example.com" or "http://localhost:3000".

Source