1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.HTTP.Adapter.GunTest do
6 use ExUnit.Case, async: true
7 use Pleroma.Tests.Helpers
8 import ExUnit.CaptureLog
10 alias Pleroma.HTTP.Adapter.Gun
11 alias Pleroma.Pool.Connections
14 {:ok, _} = Registry.start_link(keys: :unique, name: Pleroma.Gun.API.Mock)
18 describe "options/1" do
19 clear_config([:http, :adapter]) do
20 Config.put([:http, :adapter], a: 1, b: 2)
23 test "https url with default port" do
24 uri = URI.parse("https://example.com")
26 opts = Gun.options(uri)
27 assert opts[:certificates_verification]
28 tls_opts = opts[:tls_opts]
29 assert tls_opts[:verify] == :verify_peer
30 assert tls_opts[:depth] == 20
31 assert tls_opts[:reuse_sessions] == false
33 assert tls_opts[:verify_fun] ==
34 {&:ssl_verify_hostname.verify_fun/3, [check_hostname: 'example.com']}
36 assert File.exists?(tls_opts[:cacertfile])
38 assert opts[:original] == "example.com:443"
41 test "https ipv4 with default port" do
42 uri = URI.parse("https://127.0.0.1")
44 opts = Gun.options(uri)
46 assert opts[:tls_opts][:verify_fun] ==
47 {&:ssl_verify_hostname.verify_fun/3, [check_hostname: '127.0.0.1']}
49 assert opts[:original] == "127.0.0.1:443"
52 test "https ipv6 with default port" do
53 uri = URI.parse("https://[2a03:2880:f10c:83:face:b00c:0:25de]")
55 opts = Gun.options(uri)
57 assert opts[:tls_opts][:verify_fun] ==
58 {&:ssl_verify_hostname.verify_fun/3,
59 [check_hostname: '2a03:2880:f10c:83:face:b00c:0:25de']}
61 assert opts[:original] == "2a03:2880:f10c:83:face:b00c:0:25de:443"
64 test "https url with non standart port" do
65 uri = URI.parse("https://example.com:115")
67 opts = Gun.options(uri)
69 assert opts[:certificates_verification]
70 assert opts[:transport] == :tls
73 test "receive conn by default" do
74 uri = URI.parse("http://another-domain.com")
75 :ok = Connections.open_conn(uri, :gun_connections)
77 received_opts = Gun.options(uri)
78 assert received_opts[:close_conn] == false
79 assert is_pid(received_opts[:conn])
82 test "don't receive conn if receive_conn is false" do
83 uri = URI.parse("http://another-domain2.com")
84 :ok = Connections.open_conn(uri, :gun_connections)
86 opts = [receive_conn: false]
87 received_opts = Gun.options(opts, uri)
88 assert received_opts[:close_conn] == nil
89 assert received_opts[:conn] == nil
92 test "get conn on next request" do
93 level = Application.get_env(:logger, :level)
94 Logger.configure(level: :info)
95 on_exit(fn -> Logger.configure(level: level) end)
96 uri = URI.parse("http://some-domain2.com")
98 assert capture_log(fn ->
99 opts = Gun.options(uri)
101 assert opts[:conn] == nil
102 assert opts[:close_conn] == nil
104 "Gun connections pool checkin was not succesfull. Trying to open conn for next request."
106 opts = Gun.options(uri)
108 assert is_pid(opts[:conn])
109 assert opts[:close_conn] == false
112 test "merges with defaul http adapter config" do
113 defaults = Gun.options(URI.parse("https://example.com"))
114 assert Keyword.has_key?(defaults, :a)
115 assert Keyword.has_key?(defaults, :b)
118 test "default ssl adapter opts with connection" do
119 uri = URI.parse("https://some-domain.com")
121 :ok = Connections.open_conn(uri, :gun_connections)
123 opts = Gun.options(uri)
125 assert opts[:certificates_verification]
126 tls_opts = opts[:tls_opts]
127 assert tls_opts[:verify] == :verify_peer
128 assert tls_opts[:depth] == 20
129 assert tls_opts[:reuse_sessions] == false
131 assert opts[:original] == "some-domain.com:443"
132 assert opts[:close_conn] == false
133 assert is_pid(opts[:conn])
136 test "parses string proxy host & port" do
137 proxy = Config.get([:http, :proxy_url])
138 Config.put([:http, :proxy_url], "localhost:8123")
139 on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
141 uri = URI.parse("https://some-domain.com")
142 opts = Gun.options([receive_conn: false], uri)
143 assert opts[:proxy] == {'localhost', 8123}
146 test "parses tuple proxy scheme host and port" do
147 proxy = Config.get([:http, :proxy_url])
148 Config.put([:http, :proxy_url], {:socks, 'localhost', 1234})
149 on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
151 uri = URI.parse("https://some-domain.com")
152 opts = Gun.options([receive_conn: false], uri)
153 assert opts[:proxy] == {:socks, 'localhost', 1234}
156 test "passed opts have more weight than defaults" do
157 proxy = Config.get([:http, :proxy_url])
158 Config.put([:http, :proxy_url], {:socks5, 'localhost', 1234})
159 on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
160 uri = URI.parse("https://some-domain.com")
161 opts = Gun.options([receive_conn: false, proxy: {'example.com', 4321}], uri)
163 assert opts[:proxy] == {'example.com', 4321}
167 describe "after_request/1" do
168 test "body_as not chunks" do
169 uri = URI.parse("http://some-domain.com")
170 :ok = Connections.open_conn(uri, :gun_connections)
171 opts = Gun.options(uri)
172 :ok = Gun.after_request(opts)
177 "http:some-domain.com:80" => %Pleroma.Gun.Conn{
183 } = Connections.get_state(:gun_connections)
186 test "body_as chunks" do
187 uri = URI.parse("http://some-domain.com")
188 :ok = Connections.open_conn(uri, :gun_connections)
189 opts = Gun.options([body_as: :chunks], uri)
190 :ok = Gun.after_request(opts)
196 "http:some-domain.com:80" => %Pleroma.Gun.Conn{
199 used_by: [{^self, _}]
202 } = Connections.get_state(:gun_connections)
205 test "with no connection" do
206 uri = URI.parse("http://uniq-domain.com")
208 :ok = Connections.open_conn(uri, :gun_connections)
210 opts = Gun.options([body_as: :chunks], uri)
212 opts = Keyword.delete(opts, :conn)
215 :ok = Gun.after_request(opts)
219 "http:uniq-domain.com:80" => %Pleroma.Gun.Conn{
222 used_by: [{^self, _}]
225 } = Connections.get_state(:gun_connections)
229 uri = URI.parse("http://127.0.0.1")
230 :ok = Connections.open_conn(uri, :gun_connections)
231 opts = Gun.options(uri)
232 send(:gun_connections, {:gun_up, opts[:conn], :http})
233 :ok = Gun.after_request(opts)
238 "http:127.0.0.1:80" => %Pleroma.Gun.Conn{
244 } = Connections.get_state(:gun_connections)
248 uri = URI.parse("http://[2a03:2880:f10c:83:face:b00c:0:25de]")
249 :ok = Connections.open_conn(uri, :gun_connections)
250 opts = Gun.options(uri)
251 send(:gun_connections, {:gun_up, opts[:conn], :http})
252 :ok = Gun.after_request(opts)
257 "http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Pleroma.Gun.Conn{
263 } = Connections.get_state(:gun_connections)