View Source Bandit (Bandit v0.7.3)
Bandit is an HTTP server for Plug and WebSock apps.
As an HTTP server, Bandit's primary goal is to act as 'glue' between client connections managed by Thousand Island and application code defined via the Plug and/or WebSock APIs. As such there really isn't a whole lot of user-visible surface area to Bandit, and as a consequence the API documentation presented here is somewhat sparse. This is by design! Bandit is intended to 'just work' in almost all cases; the only thought users typically have to put into Bandit comes in the choice of which options (if any) they would like to change when starting a Bandit server. The sparseness of the Bandit API should not be taken as an indicator of the comprehensiveness or robustness of the project.
using-bandit-with-phoenix
Using Bandit With Phoenix
Bandit fully supports Phoenix. Phoenix applications which use WebSockets for features such as Channels or LiveView require Phoenix 1.7 or later.
Using Bandit to host your Phoenix application couldn't be simpler:
Add Bandit as a dependency in your Phoenix application's
mix.exs
:{:bandit, ">= 0.7.0"}
Add the following to your endpoint configuration in
config/config.exs
:config :your_app, YourAppWeb.Endpoint, adapter: Bandit.PhoenixAdapter
That's it! You should now see messages at startup indicating that Phoenix is using Bandit to serve your endpoint.
For more details about how to configure Bandit within Phoenix, consult the
Bandit.PhoenixAdapter
documentation.
using-bandit-with-plug-applications
Using Bandit With Plug Applications
Using Bandit to host your own Plug is very straightforward. Assuming you have a Plug module
implemented already, you can host it within Bandit by adding something similar to the following
to your application's Application.start/2
function:
def start(_type, _args) do
children = [
{Bandit, plug: MyApp.MyPlug, scheme: :http, options: [port: 4000]}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
For details about writing Plug based applications, consult the excellent Plug documentation for plenty of examples & tips to get started. Bandit supports the complete Plug API & should work correctly with any Plug-based application. If you encounter errors using Bandit your Plug app, please do get in touch by filing an issue on the Bandit GitHub project (especially if the error does not occur with another HTTP server such as Cowboy).
config-options
Config Options
Bandit takes a number of options at startup:
plug
: The plug to handle connections. Can be specified asMyPlug
or{MyPlug, plug_opts}
display_plug
: The plug to use when describing the connection in logs. Useful for situations such as Phoenix code reloading where you have a 'wrapper' plug but wish to refer to the connection by the endpoint namescheme
: One of:http
or:https
. If:https
is specified, you will need to specifycertfile
andkeyfile
in thetransport_options
subsection ofoptions
. Defaults to:http
options
: Options to pass toThousandIsland
. For an exhaustive list of options see theThousandIsland
documentation, however some common options are:port
: The port to bind to. Defaults to 4000num_acceptors
: The number of acceptor processes to run. This is mostly a performance tuning knob and can usually be left at the default value of 100read_timeout
: How long to wait for data from the client before timing out and closing the connection, specified in milliseconds. Defaults to60_000
millisecondsshutdown_timeout
: How long to wait for existing connections to complete before forcibly shutting them down at server shutdown, specified in milliseconds. Defaults to15_000
milliseconds. May also be:infinity
or:brutal_kill
as described in theSupervisor
documentation.transport_options
: A keyword list of options to be passed into the transport socket's listen functiontransport_module
: The name of the module which provides basic socket functions. This overrides any value set forscheme
and is intended for cases where control over the socket at a fundamental level is needed. You almost certainly don't want to fuss with this option unless you know exactly what you're doinghandler_module
: The name of the module which Thousand Island will use to handle requests. This overrides Bandit's built in handler and is intended for cases where control over requests at a fundamental level is needed. You almost certainly don't want to fuss with this option unless you know exactly what you're doing
http_1_options
: Options to configure the HTTP/1 stack in Bandit. Valid options are:enabled
: Whether or not to serve HTTP/1 requests. Defaults to truemax_request_line_length
: The maximum permitted length of the request line (expressed as the number of bytes on the wire) in an HTTP/1.1 request. Defaults to 10_000 bytesmax_header_length
: The maximum permitted length of any single header (combined key & value, expressed as the number of bytes on the wire) in an HTTP/1.1 request. Defaults to 10_000 bytesmax_header_count
: The maximum permitted number of headers in an HTTP/1.1 request. Defaults to 50 headersmax_requests
: The maximum number of requests to serve in a single HTTP/1.1 connection before closing the connection. Defaults to 0 (no limit)compress
: Whether or not to attempt compression of responses via content-encoding negotiation as described in RFC9110§8.4. Defaults to truedeflate_opts
: A keyword list of options to set on the deflate library. Possible options are:level
: The compression level to use for deflation. May be one ofnone
,default
,best_compression
,best_speed
, or an integer in0..9
. See :zlib documentation for more information. Defaults todefault
window_bits
: The base-2 log of the size of the histroy buffer. Largers values compress better, but use more memory. Defaults to 15memory_level
: The memory level to use for deflation. May be an integer in1..9
. See :zlib documentation for more information. Defaults to8
strategy
: The strategy to use for deflation. May be one ofdefault
,filtered
,huffman_only
, orrle
. See :zlib documentation for more information. Defaults todefault
http_2_options
: Options to configure the HTTP/2 stack in Bandit. Valid options are:enabled
: Whether or not to serve HTTP/2 requests. Defaults to truemax_header_key_length
: The maximum permitted length of any single header key (expressed as the number of decompressed bytes) in an HTTP/2 request. Defaults to 10_000 bytesmax_header_value_length
: The maximum permitted length of any single header value (expressed as the number of decompressed bytes) in an HTTP/2 request. Defaults to 10_000 bytesmax_header_count
: The maximum permitted number of headers in an HTTP/2 request. Defaults to 50 headersmax_requests
: The maximum number of requests to serve in a single HTTP/2 connection before closing the connection. Defaults to 0 (no limit)default_local_settings
: Options to override the default values for local HTTP/2 settings. Values provided here will override the defaults specified in RFC9113§6.5.2.compress
: Whether or not to attempt compression of responses via content-encoding negotiation as described in RFC9110§8.4. Defaults to truedeflate_opts
: A keyword list of options to set on the deflate library. Possible options are the same as thedeflate_opts
option under thehttp_1_options
section above
websocket_options
: Options to configure the WebSocket stack in Bandit. Valid options are:enabled
: Whether or not to serve WebSocket upgrade requests. Defaults to truemax_frame_size
: The maximum size of a single WebSocket frame (expressed as a number of bytes on the wire). Defaults to 0 (no limit)validate_text_frames
: Whether or not to validate text frames as being UTF-8. Strictly speaking this is required per RFC6455§5.6, however it can be an expensive operation and one that may be safely skipped in some situations. Defaults to truecompress
: Whether or not to allow per-message deflate compression globally. Note that upgrade requests still need to set thecompress: true
option inconnection_opts
on a per-upgrade basis for compression to be negotiated (see 'WebSocket Support' section below for details). Defaults totrue
deflate_opts
: A keyword list of options to set on the deflate library. Possible options are the same as thedeflate_opts
option under thehttp_1_options
section above, with the exception that thewindow_bits
parameter is not available
setting-up-an-https-server
Setting up an HTTPS Server
By far the most common stumbling block encountered with configuration involves setting up an HTTPS server. Bandit is comparatively easy to set up in this regard, with a working example looking similar to the following:
def start(_type, _args) do
bandit_options = [
port: 4000,
transport_options: [
certfile: Path.join(__DIR__, "path/to/cert.pem"),
keyfile: Path.join(__DIR__, "path/to/key.pem")
]
]
children = [
{Bandit, plug: MyApp.MyPlug, scheme: :https, options: bandit_options}
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
websocket-support
WebSocket Support
Bandit supports WebSocket implementations via the WebSock and WebSockAdapter libraries, which provide a generic abstraction for WebSockets (very similar to how Plug is a generic abstraction on top of HTTP). Bandit fully supports all aspects of these libraries.
Applications should validate that the connection represents a valid WebSocket request before attempting an upgrade (Bandit will validate the connection as part of the upgrade process, but does not provide any capacity for an application to be notified if the upgrade is not successful). If an application wishes to negotiate WebSocket subprotocols or otherwise set any response headers, it should do so before upgrading.
Link to this section Summary
Functions
Starts a Bandit server using the provided arguments. See "Config Options' above for specific options to pass to this function.
Link to this section Types
A Plug definition
Link to this section Functions
@spec child_spec(keyword()) :: Supervisor.child_spec()
Starts a Bandit server using the provided arguments. See "Config Options' above for specific options to pass to this function.