Packages
bandit
0.5.1
1.12.0
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
retired
1.9.0
1.8.0
1.7.0
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.0
1.2.3
1.2.2
1.2.1
1.2.0
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-pre.18
1.0.0-pre.17
1.0.0-pre.16
1.0.0-pre.15
1.0.0-pre.14
1.0.0-pre.13
1.0.0-pre.12
1.0.0-pre.11
1.0.0-pre.10
1.0.0-pre.9
1.0.0-pre.8
1.0.0-pre.7
1.0.0-pre.6
1.0.0-pre.5
1.0.0-pre.4
1.0.0-pre.3
1.0.0-pre.2
1.0.0-pre.1
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.2.3
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
A pure-Elixir HTTP server built for Plug & WebSock apps
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/bandit/initial_handler.ex
defmodule Bandit.InitialHandler do
@moduledoc false
# The initial protocol implementation used for all connections. Switches to a
# specific protocol implementation based on configuration, ALPN negotiation, and
# line heuristics.
use ThousandIsland.Handler
# Attempts to guess the protocol in use, returning the applicable next handler and any
# data consumed in the course of guessing which must be processed by the actual protocol handler
@impl ThousandIsland.Handler
def handle_connection(socket, state) do
{alpn_protocol(socket), sniff_wire(socket)}
|> case do
{Bandit.HTTP2.Handler, Bandit.HTTP2.Handler} ->
{:switch, Bandit.HTTP2.Handler, state}
{Bandit.HTTP1.Handler, {:no_match, data}} ->
{:switch, Bandit.HTTP1.Handler, data, state}
{:no_match, Bandit.HTTP2.Handler} ->
{:switch, Bandit.HTTP2.Handler, state}
{:no_match, {:no_match, data}} ->
{:switch, Bandit.HTTP1.Handler, data, state}
_other ->
{:error, "Could not determine a protocol", state}
end
end
# Returns the protocol as negotiated via ALPN, if applicable
defp alpn_protocol(socket) do
case ThousandIsland.Socket.negotiated_protocol(socket) do
{:ok, "h2"} ->
Bandit.HTTP2.Handler
{:ok, "http/1.1"} ->
Bandit.HTTP1.Handler
_ ->
:no_match
end
end
# Returns the protocol as suggested by received data, if possible
defp sniff_wire(socket) do
case ThousandIsland.Socket.recv(socket, 24) do
{:ok, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"} -> Bandit.HTTP2.Handler
{:ok, data} -> {:no_match, data}
{:error, error} -> {:error, error}
end
end
end