Packages

A tiny, tiny library to stream big big files. HTTPStream wraps HTTP requests into a Stream.

Current section

Files

Jump to
http_stream lib http_stream.ex
Raw

lib/http_stream.ex

defmodule HTTPStream do
@moduledoc """
Main API interface.
HTTPStream is a tiny tiny library for streaming big big files. It works by
wrapping HTTP requests onto a Stream. You can use it with Flow, write it to
disk through regular streams and more!
```
HTTPStream.get(large_image_url)
|> Stream.into(File.stream!("large_image.png"))
|> Stream.run()
```
The adapter can be configured by setting in your `config/config.exs`:
```
config :http_stream, adapter: HTTPStream.Adapter.Mint
```
At the moment, only two adapters are supported: Mint (default) and HTTPoison.
"""
alias HTTPStream.Adapter
alias HTTPStream.Request
@type method :: String.t()
@doc """
Performs a GET request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:query` (optional) - Keyword list of query params to add to the request.
"""
@spec get(String.t(), keyword()) :: Enumerable.t()
def get(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
query = Keyword.get(opts, :query, [])
request("GET", url, headers, query)
end
@doc """
Performs a DELETE request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:query` (optional) - Keyword list of query params to add to the request.
"""
@spec delete(String.t(), keyword()) :: Enumerable.t()
def delete(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
query = Keyword.get(opts, :query, [])
request("DELETE", url, headers, query)
end
@doc """
Performs a OPTIONS request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:query` (optional) - Keyword list of query params to add to the request.
"""
@spec options(String.t(), keyword()) :: Enumerable.t()
def options(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
query = Keyword.get(opts, :query, [])
request("OPTIONS", url, headers, query)
end
@doc """
Performs a TRACE request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:query` (optional) - Keyword list of query params to add to the request.
"""
@spec trace(String.t(), keyword()) :: Enumerable.t()
def trace(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
query = Keyword.get(opts, :query, [])
request("TRACE", url, headers, query)
end
@doc """
Performs a HEAD request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:query` (optional) - Keyword list of query params to add to the request.
"""
@spec head(String.t(), keyword()) :: Enumerable.t()
def head(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
query = Keyword.get(opts, :query, [])
request("HEAD", url, headers, query)
end
@doc """
Performs a POST request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:params` (optional) - Keyword list of query params to add to the request.
"""
@spec post(String.t(), keyword()) :: Enumerable.t()
def post(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
params = Keyword.get(opts, :params, "") |> to_json()
request("POST", url, headers, params)
end
@doc """
Performs a PUT request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:params` (optional) - Keyword list of query params to add to the request.
"""
@spec put(String.t(), keyword()) :: Enumerable.t()
def put(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
params = Keyword.get(opts, :params, "") |> to_json()
request("PUT", url, headers, params)
end
@doc """
Performs a PATCH request.
Supported options:
* `:headers` (optional) - Keyword list of HTTP headers to add to the request.
* `:params` (optional) - Keyword list of query params to add to the request.
"""
@spec patch(String.t(), keyword()) :: Enumerable.t()
def patch(url, opts \\ []) do
headers = Keyword.get(opts, :headers, []) |> to_keyword()
params = Keyword.get(opts, :params, "") |> to_json()
request("PATCH", url, headers, params)
end
@doc """
Performs an HTTP request.
Supported methods: GET, OPTIONS, HEAD, TRACE, POST, PUT, PATCH and DELETE
"""
@spec request(method(), String.t(), keyword(), binary()) :: Enumerable.t()
def request(method, url, headers \\ [], body \\ "") do
Request.new(method, url, headers: headers, body: body)
|> do_request()
end
defp do_request(%Request{} = request) do
Stream.resource(
fn -> adapter().request(request) end,
&adapter().parse_chunks/1,
&adapter().close/1
)
end
defp to_keyword(enum) do
Stream.map(enum, fn {k, v} -> {to_string(k), v} end)
|> Enum.to_list()
end
defp to_json(term), do: Jason.encode!(term)
defp adapter, do: Application.get_env(:http_stream, :adapter, Adapter.Mint)
end