Packages
bandit
0.6.0
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
test/support/simple_websocket_client.ex
defmodule SimpleWebSocketClient do
@moduledoc false
alias Bandit.WebSocket.Frame
defdelegate tcp_client(context), to: ClientHelpers
def http1_handshake(client, module, params \\ [], deflate \\ false) do
params = Keyword.put(params, :websock, module)
params = if deflate, do: Keyword.put(params, :compress, "true"), else: params
extensions = if deflate, do: "Sec-WebSocket-Extensions: permessage-deflate\r\n", else: ""
:gen_tcp.send(client, """
GET /?#{URI.encode_query(params)} HTTP/1.1\r
Host: server.example.com\r
Upgrade: websocket\r
Connection: keep-alive, Upgrade\r
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r
Sec-WebSocket-Version: 13\r
#{extensions}
\r
""")
{:ok, response} = :gen_tcp.recv(client, 216)
[
"HTTP/1.1 101 Switching Protocols",
"date: " <> _date,
"cache-control: max-age=0, private, must-revalidate",
"upgrade: websocket",
"connection: Upgrade",
"sec-websocket-accept: s3pPLMBiTxaQ9kYGzzhZRbK\+xOo=",
""
] = String.split(response, "\r\n")
if deflate do
{:ok, "sec-websocket-extensions: permessage-deflate\r\n"} = :gen_tcp.recv(client, 46)
end
{:ok, "\r\n"} = :gen_tcp.recv(client, 2)
end
def connection_closed_for_reading?(client) do
:gen_tcp.recv(client, 0) == {:error, :closed}
end
def connection_closed_for_writing?(client) do
:gen_tcp.send(client, <<>>) == {:error, :closed}
end
def recv_text_frame(client) do
{:ok, 0x8, 0x1, body} = recv_frame(client)
{:ok, body}
end
def recv_deflated_text_frame(client) do
{:ok, 0xC, 0x1, body} = recv_frame(client)
{:ok, body}
end
def recv_binary_frame(client) do
{:ok, 0x8, 0x2, body} = recv_frame(client)
{:ok, body}
end
def recv_deflated_binary_frame(client) do
{:ok, 0xC, 0x2, body} = recv_frame(client)
{:ok, body}
end
def recv_connection_close_frame(client) do
{:ok, 0x8, 0x8, body} = recv_frame(client)
{:ok, body}
end
def recv_ping_frame(client) do
{:ok, 0x8, 0x9, body} = recv_frame(client)
{:ok, body}
end
def recv_pong_frame(client) do
{:ok, 0x8, 0xA, body} = recv_frame(client)
{:ok, body}
end
defp recv_frame(client) do
{:ok, header} = :gen_tcp.recv(client, 2)
<<flags::4, opcode::4, 0::1, length::7>> = header
{:ok, data} =
case length do
0 ->
{:ok, <<>>}
126 ->
{:ok, <<length::16>>} = :gen_tcp.recv(client, 2)
:gen_tcp.recv(client, length)
127 ->
{:ok, <<length::64>>} = :gen_tcp.recv(client, 8)
:gen_tcp.recv(client, length)
length ->
:gen_tcp.recv(client, length)
end
{:ok, flags, opcode, data}
end
def send_continuation_frame(client, data, flags \\ 0x8) do
send_frame(client, flags, 0x0, data)
end
def send_text_frame(client, data, flags \\ 0x8) do
send_frame(client, flags, 0x1, data)
end
def send_binary_frame(client, data, flags \\ 0x8) do
send_frame(client, flags, 0x2, data)
end
def send_connection_close_frame(client, reason) do
send_frame(client, 0x8, 0x8, <<reason::16>>)
end
def send_ping_frame(client, data) do
send_frame(client, 0x8, 0x9, data)
end
def send_pong_frame(client, data) do
send_frame(client, 0x8, 0xA, data)
end
defp send_frame(client, flags, opcode, data) do
mask = :rand.uniform(1_000_000)
masked_data = Frame.mask(data, mask)
mask_flag_and_size =
case byte_size(masked_data) do
size when size <= 125 -> <<1::1, size::7>>
size when size <= 65_535 -> <<1::1, 126::7, size::16>>
size -> <<1::1, 127::7, size::64>>
end
:gen_tcp.send(client, [<<flags::4, opcode::4>>, mask_flag_and_size, <<mask::32>>, masked_data])
end
end