1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.HTTP.AdapterHelper.GunTest do
6 use ExUnit.Case, async: true
7 use Pleroma.Tests.Helpers
8 import ExUnit.CaptureLog
10 alias Pleroma.Gun.Conn
11 alias Pleroma.HTTP.AdapterHelper.Gun
12 alias Pleroma.Pool.Connections
15 {:ok, _} = Registry.start_link(keys: :unique, name: Pleroma.GunMock)
19 describe "options/1" do
20 clear_config([:http, :adapter]) do
21 Config.put([:http, :adapter], a: 1, b: 2)
24 test "https url with default port" do
25 uri = URI.parse("https://example.com")
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
34 assert tls_opts[:verify_fun] ==
35 {&:ssl_verify_hostname.verify_fun/3, [check_hostname: 'example.com']}
37 assert File.exists?(tls_opts[:cacertfile])
40 test "https ipv4 with default port" do
41 uri = URI.parse("https://127.0.0.1")
43 opts = Gun.options(uri)
45 assert opts[:tls_opts][:verify_fun] ==
46 {&:ssl_verify_hostname.verify_fun/3, [check_hostname: '127.0.0.1']}
49 test "https ipv6 with default port" do
50 uri = URI.parse("https://[2a03:2880:f10c:83:face:b00c:0:25de]")
52 opts = Gun.options(uri)
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']}
59 test "https url with non standart port" do
60 uri = URI.parse("https://example.com:115")
62 opts = Gun.options(uri)
64 assert opts[:certificates_verification]
65 assert opts[:transport] == :tls
68 test "receive conn by default" do
69 uri = URI.parse("http://another-domain.com")
70 :ok = Conn.open(uri, :gun_connections)
72 received_opts = Gun.options(uri)
73 assert received_opts[:close_conn] == false
74 assert is_pid(received_opts[:conn])
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)
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
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")
93 assert capture_log(fn ->
94 opts = Gun.options(uri)
96 assert opts[:conn] == nil
97 assert opts[:close_conn] == nil
99 "Gun connections pool checkin was not successful. Trying to open conn for next request."
101 opts = Gun.options(uri)
103 assert is_pid(opts[:conn])
104 assert opts[:close_conn] == false
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)
113 test "default ssl adapter opts with connection" do
114 uri = URI.parse("https://some-domain.com")
116 :ok = Conn.open(uri, :gun_connections)
118 opts = Gun.options(uri)
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
126 assert opts[:close_conn] == false
127 assert is_pid(opts[:conn])
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)
135 uri = URI.parse("https://some-domain.com")
136 opts = Gun.options([receive_conn: false], uri)
137 assert opts[:proxy] == {'localhost', 8123}
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)
145 uri = URI.parse("https://some-domain.com")
146 opts = Gun.options([receive_conn: false], uri)
147 assert opts[:proxy] == {:socks, 'localhost', 1234}
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)
157 assert opts[:proxy] == {'example.com', 4321}
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)
171 "http:some-domain.com:80" => %Pleroma.Gun.Conn{
177 } = Connections.get_state(:gun_connections)
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)
190 "http:some-domain.com:80" => %Pleroma.Gun.Conn{
193 used_by: [{^self, _}]
196 } = Connections.get_state(:gun_connections)
199 test "with no connection" do
200 uri = URI.parse("http://uniq-domain.com")
202 :ok = Conn.open(uri, :gun_connections)
204 opts = Gun.options([body_as: :chunks], uri)
206 opts = Keyword.delete(opts, :conn)
209 :ok = Gun.after_request(opts)
213 "http:uniq-domain.com:80" => %Pleroma.Gun.Conn{
216 used_by: [{^self, _}]
219 } = Connections.get_state(:gun_connections)
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)
232 "http:127.0.0.1:80" => %Pleroma.Gun.Conn{
238 } = Connections.get_state(:gun_connections)
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)
251 "http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Pleroma.Gun.Conn{
257 } = Connections.get_state(:gun_connections)
261 describe "format_host/1" do
262 test "with domain" do
263 assert Gun.format_host("example.com") == 'example.com'
266 test "with idna domain" do
267 assert Gun.format_host("ですexample.com") == 'xn--example-183fne.com'
271 assert Gun.format_host("127.0.0.1") == '127.0.0.1'
275 assert Gun.format_host("2a03:2880:f10c:83:face:b00c:0:25de") ==
276 '2a03:2880:f10c:83:face:b00c:0:25de'