-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathadapter.ex
More file actions
70 lines (57 loc) · 1.95 KB
/
adapter.ex
File metadata and controls
70 lines (57 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
defmodule Diff.Hex.Adapter do
@behaviour :hex_http
@opts [follow_redirect: true, max_redirect: 5]
@impl true
def request(method, uri, req_headers, req_body, _config) do
{content_type, payload} = deconstruct_body(req_body)
req_headers = prepare_headers(req_headers, content_type)
resp = :hackney.request(method, uri, req_headers, payload, @opts)
with {:ok, status, resp_headers, client_ref} <- resp,
{:ok, resp_body} <- :hackney.body(client_ref) do
resp_headers = Map.new(resp_headers)
{:ok, {status, resp_headers, resp_body}}
end
end
@impl true
def request_to_file(method, uri, req_headers, req_body, filename, _config) do
{content_type, payload} = deconstruct_body(req_body)
req_headers = prepare_headers(req_headers, content_type)
case :hackney.request(method, uri, req_headers, payload, @opts) do
{:ok, 200, resp_headers, ref} ->
resp_headers = Map.new(resp_headers)
case File.open(filename, [:write, :binary], &stream_body_to_file(ref, &1)) do
{:ok, :ok} -> {:ok, {200, resp_headers}}
{:ok, {:error, _} = error} -> error
{:error, reason} -> {:error, reason}
end
{:ok, status, resp_headers, ref} ->
:hackney.skip_body(ref)
resp_headers = Map.new(resp_headers)
{:ok, {status, resp_headers}}
{:error, reason} ->
{:error, reason}
end
end
defp stream_body_to_file(ref, file) do
case :hackney.stream_body(ref) do
{:ok, data} ->
:ok = IO.binwrite(file, data)
stream_body_to_file(ref, file)
:done ->
:ok
{:error, reason} ->
{:error, reason}
end
end
defp prepare_headers(req_headers, content_type) do
if content_type do
req_headers
|> Map.put("content-type", content_type)
else
req_headers
end
|> Enum.to_list()
end
defp deconstruct_body(:undefined), do: {nil, ""}
defp deconstruct_body(body), do: body
end