moving some logic to tesla adapter
[akkoma] / test / http / adapter_helper / gun_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.HTTP.AdapterHelper.GunTest do
6 use ExUnit.Case, async: true
7 use Pleroma.Tests.Helpers
8 import ExUnit.CaptureLog
9 alias Pleroma.Config
10 alias Pleroma.Gun.Conn
11 alias Pleroma.HTTP.AdapterHelper.Gun
12 alias Pleroma.Pool.Connections
13
14 setup_all do
15 {:ok, _} = Registry.start_link(keys: :unique, name: Pleroma.GunMock)
16 :ok
17 end
18
19 describe "options/1" do
20 clear_config([:http, :adapter]) do
21 Config.put([:http, :adapter], a: 1, b: 2)
22 end
23
24 test "https url with default port" do
25 uri = URI.parse("https://example.com")
26
27 opts = Gun.options(uri)
28 assert opts[:certificates_verification]
29 tls_opts = opts[:tls_opts]
30 assert tls_opts[:verify] == :verify_peer
31 assert tls_opts[:depth] == 20
32 assert tls_opts[:reuse_sessions] == false
33
34 assert tls_opts[:verify_fun] ==
35 {&:ssl_verify_hostname.verify_fun/3, [check_hostname: 'example.com']}
36
37 assert File.exists?(tls_opts[:cacertfile])
38 end
39
40 test "https ipv4 with default port" do
41 uri = URI.parse("https://127.0.0.1")
42
43 opts = Gun.options(uri)
44
45 assert opts[:tls_opts][:verify_fun] ==
46 {&:ssl_verify_hostname.verify_fun/3, [check_hostname: '127.0.0.1']}
47 end
48
49 test "https ipv6 with default port" do
50 uri = URI.parse("https://[2a03:2880:f10c:83:face:b00c:0:25de]")
51
52 opts = Gun.options(uri)
53
54 assert opts[:tls_opts][:verify_fun] ==
55 {&:ssl_verify_hostname.verify_fun/3,
56 [check_hostname: '2a03:2880:f10c:83:face:b00c:0:25de']}
57 end
58
59 test "https url with non standart port" do
60 uri = URI.parse("https://example.com:115")
61
62 opts = Gun.options(uri)
63
64 assert opts[:certificates_verification]
65 assert opts[:transport] == :tls
66 end
67
68 test "receive conn by default" do
69 uri = URI.parse("http://another-domain.com")
70 :ok = Conn.open(uri, :gun_connections)
71
72 received_opts = Gun.options(uri)
73 assert received_opts[:close_conn] == false
74 assert is_pid(received_opts[:conn])
75 end
76
77 test "don't receive conn if receive_conn is false" do
78 uri = URI.parse("http://another-domain2.com")
79 :ok = Conn.open(uri, :gun_connections)
80
81 opts = [receive_conn: false]
82 received_opts = Gun.options(opts, uri)
83 assert received_opts[:close_conn] == nil
84 assert received_opts[:conn] == nil
85 end
86
87 test "get conn on next request" do
88 level = Application.get_env(:logger, :level)
89 Logger.configure(level: :debug)
90 on_exit(fn -> Logger.configure(level: level) end)
91 uri = URI.parse("http://some-domain2.com")
92
93 assert capture_log(fn ->
94 opts = Gun.options(uri)
95
96 assert opts[:conn] == nil
97 assert opts[:close_conn] == nil
98 end) =~
99 "Gun connections pool checkin was not successful. Trying to open conn for next request."
100
101 opts = Gun.options(uri)
102
103 assert is_pid(opts[:conn])
104 assert opts[:close_conn] == false
105 end
106
107 test "merges with defaul http adapter config" do
108 defaults = Gun.options(URI.parse("https://example.com"))
109 assert Keyword.has_key?(defaults, :a)
110 assert Keyword.has_key?(defaults, :b)
111 end
112
113 test "default ssl adapter opts with connection" do
114 uri = URI.parse("https://some-domain.com")
115
116 :ok = Conn.open(uri, :gun_connections)
117
118 opts = Gun.options(uri)
119
120 assert opts[:certificates_verification]
121 tls_opts = opts[:tls_opts]
122 assert tls_opts[:verify] == :verify_peer
123 assert tls_opts[:depth] == 20
124 assert tls_opts[:reuse_sessions] == false
125
126 assert opts[:close_conn] == false
127 assert is_pid(opts[:conn])
128 end
129
130 test "parses string proxy host & port" do
131 proxy = Config.get([:http, :proxy_url])
132 Config.put([:http, :proxy_url], "localhost:8123")
133 on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
134
135 uri = URI.parse("https://some-domain.com")
136 opts = Gun.options([receive_conn: false], uri)
137 assert opts[:proxy] == {'localhost', 8123}
138 end
139
140 test "parses tuple proxy scheme host and port" do
141 proxy = Config.get([:http, :proxy_url])
142 Config.put([:http, :proxy_url], {:socks, 'localhost', 1234})
143 on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
144
145 uri = URI.parse("https://some-domain.com")
146 opts = Gun.options([receive_conn: false], uri)
147 assert opts[:proxy] == {:socks, 'localhost', 1234}
148 end
149
150 test "passed opts have more weight than defaults" do
151 proxy = Config.get([:http, :proxy_url])
152 Config.put([:http, :proxy_url], {:socks5, 'localhost', 1234})
153 on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
154 uri = URI.parse("https://some-domain.com")
155 opts = Gun.options([receive_conn: false, proxy: {'example.com', 4321}], uri)
156
157 assert opts[:proxy] == {'example.com', 4321}
158 end
159 end
160
161 describe "after_request/1" do
162 test "body_as not chunks" do
163 uri = URI.parse("http://some-domain.com")
164 :ok = Conn.open(uri, :gun_connections)
165 opts = Gun.options(uri)
166 :ok = Gun.after_request(opts)
167 conn = opts[:conn]
168
169 assert %Connections{
170 conns: %{
171 "http:some-domain.com:80" => %Pleroma.Gun.Conn{
172 conn: ^conn,
173 conn_state: :idle,
174 used_by: []
175 }
176 }
177 } = Connections.get_state(:gun_connections)
178 end
179
180 test "body_as chunks" do
181 uri = URI.parse("http://some-domain.com")
182 :ok = Conn.open(uri, :gun_connections)
183 opts = Gun.options([body_as: :chunks], uri)
184 :ok = Gun.after_request(opts)
185 conn = opts[:conn]
186 self = self()
187
188 assert %Connections{
189 conns: %{
190 "http:some-domain.com:80" => %Pleroma.Gun.Conn{
191 conn: ^conn,
192 conn_state: :active,
193 used_by: [{^self, _}]
194 }
195 }
196 } = Connections.get_state(:gun_connections)
197 end
198
199 test "with no connection" do
200 uri = URI.parse("http://uniq-domain.com")
201
202 :ok = Conn.open(uri, :gun_connections)
203
204 opts = Gun.options([body_as: :chunks], uri)
205 conn = opts[:conn]
206 opts = Keyword.delete(opts, :conn)
207 self = self()
208
209 :ok = Gun.after_request(opts)
210
211 assert %Connections{
212 conns: %{
213 "http:uniq-domain.com:80" => %Pleroma.Gun.Conn{
214 conn: ^conn,
215 conn_state: :active,
216 used_by: [{^self, _}]
217 }
218 }
219 } = Connections.get_state(:gun_connections)
220 end
221
222 test "with ipv4" do
223 uri = URI.parse("http://127.0.0.1")
224 :ok = Conn.open(uri, :gun_connections)
225 opts = Gun.options(uri)
226 send(:gun_connections, {:gun_up, opts[:conn], :http})
227 :ok = Gun.after_request(opts)
228 conn = opts[:conn]
229
230 assert %Connections{
231 conns: %{
232 "http:127.0.0.1:80" => %Pleroma.Gun.Conn{
233 conn: ^conn,
234 conn_state: :idle,
235 used_by: []
236 }
237 }
238 } = Connections.get_state(:gun_connections)
239 end
240
241 test "with ipv6" do
242 uri = URI.parse("http://[2a03:2880:f10c:83:face:b00c:0:25de]")
243 :ok = Conn.open(uri, :gun_connections)
244 opts = Gun.options(uri)
245 send(:gun_connections, {:gun_up, opts[:conn], :http})
246 :ok = Gun.after_request(opts)
247 conn = opts[:conn]
248
249 assert %Connections{
250 conns: %{
251 "http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Pleroma.Gun.Conn{
252 conn: ^conn,
253 conn_state: :idle,
254 used_by: []
255 }
256 }
257 } = Connections.get_state(:gun_connections)
258 end
259 end
260
261 describe "format_host/1" do
262 test "with domain" do
263 assert Gun.format_host("example.com") == 'example.com'
264 end
265
266 test "with idna domain" do
267 assert Gun.format_host("ですexample.com") == 'xn--example-183fne.com'
268 end
269
270 test "with ipv4" do
271 assert Gun.format_host("127.0.0.1") == '127.0.0.1'
272 end
273
274 test "with ipv6" do
275 assert Gun.format_host("2a03:2880:f10c:83:face:b00c:0:25de") ==
276 '2a03:2880:f10c:83:face:b00c:0:25de'
277 end
278 end
279 end