Current section

Files

Jump to
adbc lib adbc_helper.ex
Raw

lib/adbc_helper.ex

defmodule Adbc.Helper do
@moduledoc false
@doc false
def error_to_exception(string) when is_binary(string) do
ArgumentError.exception(string)
end
def error_to_exception(list) when is_list(list) do
ArgumentError.exception(List.to_string(list))
end
def error_to_exception({:adbc_error, message, vendor_code, state}) do
Adbc.Error.exception(message: message, vendor_code: vendor_code, state: state)
end
def error_to_exception(%Adbc.Error{} = exception) do
exception
end
def option(callee, func, args)
def option(pid, func, args) when is_pid(pid) do
case GenServer.call(pid, {:option, func, args}) do
:ok ->
:ok
{:ok, value} ->
{:ok, value}
{:error, reason} ->
{:error, error_to_exception(reason)}
end
end
def option(ref, func, [type, key | args]) when is_reference(ref) do
with {:error, reason} <- apply(Adbc.Nif, func, [ref, type, to_string(key) | args]) do
{:error, error_to_exception(reason)}
end
end
def option_ok_or_halt(callee, func, args) do
case option(callee, func, args) do
:ok -> {:cont, :ok}
{:error, _} = error -> {:halt, error}
end
end
@doc false
def download(url, ignore_proxy) do
url_charlist = String.to_charlist(url)
{:ok, _} = Application.ensure_all_started(:inets)
{:ok, _} = Application.ensure_all_started(:ssl)
{:ok, _} = Application.ensure_all_started(:public_key)
if !ignore_proxy do
if proxy = System.get_env("HTTP_PROXY") || System.get_env("http_proxy") do
%{host: host, port: port} = URI.parse(proxy)
:httpc.set_options([{:proxy, {{String.to_charlist(host), port}, []}}])
end
if proxy = System.get_env("HTTPS_PROXY") || System.get_env("https_proxy") do
%{host: host, port: port} = URI.parse(proxy)
:httpc.set_options([{:https_proxy, {{String.to_charlist(host), port}, []}}])
end
end
# https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/inets
# TODO: This may no longer be necessary from Erlang/OTP 25.0 or later.
https_options = [
ssl:
[
verify: :verify_peer,
customize_hostname_check: [
match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
]
] ++ cacerts_options()
]
options = [body_format: :binary]
case :httpc.request(:get, {url_charlist, []}, https_options, options) do
{:ok, {{_, 200, _}, _headers, body}} ->
{:ok, body}
other ->
{:error, "couldn't fetch file from #{url}: #{inspect(other)}"}
end
end
defp cacerts_options do
cond do
custom_certs = System.get_env("ADBC_CACERTS_PATH") ->
[cacertfile: custom_certs]
certs = otp_cacerts() ->
[cacerts: certs]
Application.spec(:castore, :vsn) ->
[cacertfile: Application.app_dir(:castore, "priv/cacerts.pem")]
true ->
IO.warn("""
No certificate trust store was found.
A certificate trust store is required in
order to download locales for your configuration.
Since elixir_make could not detect a system
installed certificate trust store one of the
following actions may be taken:
1. Use OTP 25+ on an OS that has built-in certificate
trust store.
2. Install the hex package `castore`. It will
be automatically detected after recompilation.
""")
[]
end
end
if System.otp_release() >= "25" do
defp otp_cacerts do
:public_key.cacerts_get()
rescue
_ -> nil
end
else
defp otp_cacerts, do: nil
end
end