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