Current section
Files
Jump to
Current section
Files
lib/tus_client.ex
defmodule TusClient do
@moduledoc false
alias TusClient.{Options, Patch, Post}
require Logger
@behaviour TusClient.Behaviour
@type upload_error ::
:file_error
| :generic
| :location
| :not_supported
| :too_large
| :too_many_errors
| :transport
| :unfulfilled_extensions
@spec upload(
binary(),
binary(),
list(
{:metadata, binary()}
| {:max_retries, integer()}
| {:chunk_size, integer()}
| {:headers, list()}
| {:ssl, list()}
)
) :: {:ok, binary} | {:error, upload_error()}
def upload(base_url, path, opts \\ []) do
with {:ok, _} <- Options.request(base_url, get_headers(opts), opts),
{:ok, %{location: loc}} <-
Post.request(base_url, path, get_headers(opts), opts) do
do_patch(loc, path, opts)
end
end
defp do_patch(location, path, opts) do
location
|> Patch.request(0, path, get_headers(opts), opts)
|> do_patch(location, path, opts, 1, 0)
end
defp do_patch({:ok, new_offset}, location, path, opts, _retry_nr, _offset) do
case file_size(path) do
^new_offset ->
{:ok, location}
_ ->
location
|> Patch.request(new_offset, path, get_headers(opts), opts)
|> do_patch(location, path, opts, 0, new_offset)
end
end
defp do_patch({:error, reason}, location, path, opts, retry_nr, offset) do
case get_max_retries(opts) do
^retry_nr ->
Logger.error("Max retries reached, bailing out...")
{:error, :too_many_errors}
_ ->
Logger.warning("Patch error #{inspect(reason)}, retrying...")
location
|> Patch.request(offset, path, get_headers(opts), opts)
|> do_patch(location, path, opts, retry_nr + 1, offset)
end
end
defp file_size(path) do
{:ok, %{size: size}} = File.stat(path)
size
end
defp get_max_retries(opts) do
Keyword.get(opts, :max_retries, 3)
end
defp get_headers(opts) do
Keyword.get(opts, :headers, [])
end
end