Skip to content

Commit 63502b2

Browse files
authored
feat: add ssl opt to httpc by default (#626)
1 parent 152b6ef commit 63502b2

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

lib/tesla/adapter/httpc.ex

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ defmodule Tesla.Adapter.Httpc do
88
consistency between adapters
99
"""
1010

11+
current_otp_version = List.to_integer(:erlang.system_info(:otp_release))
12+
1113
@behaviour Tesla.Adapter
1214
import Tesla.Adapter.Shared, only: [stream_to_fun: 1, next_chunk: 1]
1315
alias Tesla.Multipart
@@ -18,12 +20,37 @@ defmodule Tesla.Adapter.Httpc do
1820
@impl Tesla.Adapter
1921
def call(env, opts) do
2022
opts = Tesla.Adapter.opts(@override_defaults, env, opts)
23+
opts = add_default_ssl_opt(env, opts)
2124

2225
with {:ok, {status, headers, body}} <- request(env, opts) do
2326
{:ok, format_response(env, status, headers, body)}
2427
end
2528
end
2629

30+
# TODO: remove this once OTP 25+ is required
31+
if current_otp_version >= 25 do
32+
def add_default_ssl_opt(env, opts) do
33+
default_ssl_opt = [
34+
ssl: [
35+
verify: :verify_peer,
36+
cacerts: :public_key.cacerts_get(),
37+
depth: 3,
38+
customize_hostname_check: [
39+
match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
40+
],
41+
crl_check: true,
42+
crl_cache: {:ssl_crl_cache, {:internal, [http: 1000]}}
43+
]
44+
]
45+
46+
Tesla.Adapter.opts(default_ssl_opt, env, opts)
47+
end
48+
else
49+
def add_default_ssl_opt(_env, opts) do
50+
opts
51+
end
52+
end
53+
2754
defp format_response(env, {_, status, _}, headers, body) do
2855
%{env | status: status, headers: format_headers(headers), body: format_body(body)}
2956
end

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ defmodule Tesla.Mixfile do
1717
test_coverage: [tool: ExCoveralls],
1818
dialyzer: [
1919
plt_core_path: "_build/#{Mix.env()}",
20-
plt_add_apps: [:mix, :inets, :idna, :ssl_verify_fun, :ex_unit],
20+
plt_add_apps: [:public_key, :mix, :inets, :idna, :ssl_verify_fun, :ex_unit],
2121
plt_add_deps: :apps_direct
2222
],
2323
docs: docs(),

test/tesla/adapter/httpc_test.exs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,36 @@ defmodule Tesla.Adapter.HttpcTest do
4545

4646
assert data["headers"]["content-type"] == "text/plain"
4747
end
48+
49+
describe "badssl" do
50+
@describetag :integration
51+
52+
test "expired.badssl.com" do
53+
assert {:error, :econnrefused} =
54+
Tesla.get(Tesla.client([], Tesla.Adapter.Httpc), "https://expired.badssl.com")
55+
end
56+
57+
test "wrong.host.badssl.com" do
58+
assert {:error, :econnrefused} =
59+
Tesla.get(Tesla.client([], Tesla.Adapter.Httpc), "https://wrong.host.badssl.com")
60+
end
61+
62+
test "self-signed.badssl.com" do
63+
assert {:error, :econnrefused} =
64+
Tesla.get(Tesla.client([], Tesla.Adapter.Httpc), "https://self-signed.badssl.com")
65+
end
66+
67+
test "untrusted-root.badssl.com" do
68+
assert {:error, :econnrefused} =
69+
Tesla.get(
70+
Tesla.client([], Tesla.Adapter.Httpc),
71+
"https://untrusted-root.badssl.com"
72+
)
73+
end
74+
75+
test "revoked.badssl.com" do
76+
assert {:error, :econnrefused} =
77+
Tesla.get(Tesla.client([], Tesla.Adapter.Httpc), "https://revoked.badssl.com")
78+
end
79+
end
4880
end

0 commit comments

Comments
 (0)