Bandit

Build StatusDocsHex.pm

Bandit is an HTTP server for Plug apps.

Bandit is written entirely in Elixir and is built atop Thousand Island. It can serve HTTP/1.x and HTTP/2 clients over both HTTP and HTTPS. It is written with correctness, clarity & performance as fundamental goals. It was introduced at ElixirConf 2021.

In recent performance tests, Bandit’s HTTP/1.x engine is up to 5x faster than Cowboy depending on the number of concurrent requests. When comparing HTTP/2 performance, Bandit is up to 2.3x faster than Cowboy (this number is likely even higher, as Cowboy was unable to complete many test runs without error). This is possible because Bandit has been built from the ground up for use with Plug applications; this focus pays dividends in both performance and also in the approachability of the code base.

Bandit also emphasizes correctness. Its HTTP/2 implementation scores 100% on the h2spec suite in strict mode. Extensive units tests (90%+ coverage for all non-legacy modules), credo analysis and dialyzer coverage round out a test suite that ensures that Bandit is and will remain a platform you can count on.

Lastly, Bandit exists to demystify the lower layers of infrastructure code. In a world where The New Thing is nearly always adding abstraction on top of abstraction, it’s important to have foundational work that is approachable & understandable by users above it in the stack.

Project Goals

Project Status

Bandit is still a young project, and much work remains before it is ready for production use. That having been said, much progress has been made already. The project is progressing steadily towards full Phoenix support, with a phased development plan focusing on one major set of features at a time.

As of the current 0.4.x release series, Bandit features the following:

Today, almost any non-Phoenix Plug app should work with Bandit as a drop-in replacement for Cowboy. However, Bandit is still a long way away from being a drop-in solution for Phoenix apps. There are three main pieces of work to be done in order for this to happen:

To summarize, the roadmap to full Phoenix support and an eventual 1.0 release looks more or less like the following:

Usage

Usage of Bandit 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

Bandit takes a number of options at startup, which are described in detail in the Bandit documentation. 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

Implementation Details

Bandit’s HTTP/2 implementation is described in detail in its own README. Similar documentation for the HTTP/1.x implementation is a work in progress.

Contributing

Contributions to Bandit are very much welcome! Before undertaking any substantial work, please open an issue on the project to discuss ideas and planned approaches so we can ensure we keep progress moving in the same direction.

All contributors must agree and adhere to the project’s Code of Conduct.

Security disclosures should be sent privately to mat@geeky.net.

Installation

Bandit is available in Hex. The package can be installed by adding bandit to your list of dependencies in mix.exs:

def deps do
  [
    {:bandit, "~> 0.4.3"}
  ]
end

Documentation can be found at https://hexdocs.pm/bandit.

License

MIT