Current section

Files

Jump to
kadabra lib kadabra.ex
Raw

lib/kadabra.ex

defmodule Kadabra do
@moduledoc """
HTTP/2 client for Elixir.
"""
alias Kadabra.{Connection, Supervisor}
@doc ~S"""
Opens a new connection.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> is_pid(pid)
true
"""
@spec open(charlist, :https, Keyword.t) :: {:ok, pid} | {:error, term}
def open(uri, scheme, opts \\ []) do
port = Keyword.get(opts, :port, 443)
reconnect = Keyword.get(opts, :reconnect, true)
nopts =
opts
|> List.keydelete(:port, 0)
|> List.keydelete(:reconnect, 0)
start_opts = [scheme: scheme, ssl: nopts, port: port, reconnect: reconnect]
Supervisor.start_link(uri, self(), start_opts)
end
@doc ~S"""
Closes an existing connection.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> Kadabra.close(pid)
iex> receive do
...> {:closed, _pid} -> "connection closed!"
...> end
"connection closed!"
"""
@spec close(pid) :: :ok
def close(pid) do
pid
|> Connection.via_tuple()
|> Connection.close()
end
@doc ~S"""
Pings an existing connection.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> Kadabra.ping(pid)
iex> receive do
...> {:pong, _pid} -> "got pong!"
...> end
"got pong!"
"""
def ping(pid), do: GenServer.cast(Connection.via_tuple(pid), {:send, :ping})
@doc ~S"""
Makes a request with given headers.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> path = "/reqinfo" # Route echoes PUT body in uppercase
iex> headers = [
...> {":method", "GET"},
...> {":path", path},
...> ]
iex> Kadabra.request(pid, headers)
iex> response = receive do
...> {:end_stream, %Kadabra.Stream.Response{} = response} -> response
...> after 5_000 -> :timed_out
...> end
iex> {response.id, response.status}
{1, 200}
"""
def request(pid, headers) do
GenServer.cast(Connection.via_tuple(pid), {:send, :headers, headers})
end
@doc ~S"""
Makes a request with given headers and body.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> path = "/ECHO" # Route echoes PUT body in uppercase
iex> body = "sample echo request"
iex> headers = [
...> {":method", "PUT"},
...> {":path", path},
...> ]
iex> Kadabra.request(pid, headers, body)
iex> response = receive do
...> {:end_stream, %Kadabra.Stream.Response{} = response} -> response
...> after 5_000 -> :timed_out
...> end
iex> {response.id, response.status, response.body}
{1, 200, "SAMPLE ECHO REQUEST"}
"""
def request(pid, headers, body) do
GenServer.cast(Connection.via_tuple(pid), {:send, :headers, headers, body})
end
@doc ~S"""
Makes a GET request.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> Kadabra.get(pid, "/reqinfo")
:ok
iex> response = receive do
...> {:end_stream, response} -> response
...> end
iex> {response.id, response.status}
{1, 200}
"""
def get(pid, path) do
headers = [
{":method", "GET"},
{":path", path},
]
request(pid, headers)
end
@doc ~S"""
Makes a POST request.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> Kadabra.post(pid, "/", "test=123")
:ok
iex> response = receive do
...> {:end_stream, response} -> response
...> end
iex> {response.id, response.status}
{1, 200}
"""
def post(pid, path, payload) do
headers = [
{":method", "POST"},
{":path", path},
]
request(pid, headers, payload)
end
@doc ~S"""
Makes a PUT request.
## Examples
iex> {:ok, pid} = Kadabra.open('http2.golang.org', :https)
iex> Kadabra.put(pid, "/crc32", "test")
:ok
iex> stream = receive do
...> {:end_stream, stream} -> stream
...> end
iex> stream.status
200
iex> stream.body
"bytes=4, CRC32=d87f7e0c"
"""
def put(pid, path, payload) do
headers = [
{":method", "PUT"},
{":path", path},
]
request(pid, headers, payload)
end
end