|
| 1 | +%%% -*- erlang -*- |
| 2 | +%%% |
| 3 | +%%% This file is part of hackney released under the Apache 2 license. |
| 4 | +%%% See the NOTICE for more information. |
| 5 | +%%% |
| 6 | +%%% Copyright (c) 2025 Benoît Chesneau <[email protected]> |
| 7 | +%%% |
| 8 | + |
| 9 | +-module(hackney_proxy_tests). |
| 10 | +-include_lib("eunit/include/eunit.hrl"). |
| 11 | + |
| 12 | +%% Test empty proxy environment variables handling |
| 13 | +empty_proxy_env_test_() -> |
| 14 | + {setup, |
| 15 | + fun setup/0, |
| 16 | + fun teardown/1, |
| 17 | + fun(State) -> |
| 18 | + [ |
| 19 | + {"Empty http_proxy", fun() -> test_empty_proxy_env("http_proxy", State) end}, |
| 20 | + {"Empty HTTP_PROXY", fun() -> test_empty_proxy_env("HTTP_PROXY", State) end}, |
| 21 | + {"Empty https_proxy", fun() -> test_empty_proxy_env("https_proxy", State) end}, |
| 22 | + {"Empty HTTPS_PROXY", fun() -> test_empty_proxy_env("HTTPS_PROXY", State) end}, |
| 23 | + {"Whitespace http_proxy", fun() -> test_whitespace_proxy_env("http_proxy", State) end}, |
| 24 | + {"Whitespace HTTPS_PROXY", fun() -> test_whitespace_proxy_env("HTTPS_PROXY", State) end}, |
| 25 | + {"Multiple spaces proxy", fun() -> test_multiple_spaces_proxy_env("http_proxy", State) end}, |
| 26 | + {"Valid proxy URL", fun() -> test_valid_proxy_env("http_proxy", State) end}, |
| 27 | + {"Valid proxy with spaces", fun() -> test_valid_proxy_with_spaces("HTTP_PROXY", State) end} |
| 28 | + ] |
| 29 | + end}. |
| 30 | + |
| 31 | +setup() -> |
| 32 | + %% Save current environment variables |
| 33 | + SavedEnv = [{Var, os:getenv(Var)} || Var <- ["http_proxy", "HTTP_PROXY", |
| 34 | + "https_proxy", "HTTPS_PROXY", |
| 35 | + "all_proxy", "ALL_PROXY"]], |
| 36 | + %% Clear all proxy environment variables |
| 37 | + [os:unsetenv(Var) || {Var, _} <- SavedEnv], |
| 38 | + %% Clear hackney's cached proxy settings |
| 39 | + application:unset_env(hackney, http_proxy), |
| 40 | + application:unset_env(hackney, https_proxy), |
| 41 | + SavedEnv. |
| 42 | + |
| 43 | +teardown(SavedEnv) -> |
| 44 | + %% Restore original environment variables |
| 45 | + lists:foreach(fun |
| 46 | + ({Var, false}) -> os:unsetenv(Var); |
| 47 | + ({Var, Value}) -> os:putenv(Var, Value) |
| 48 | + end, SavedEnv), |
| 49 | + %% Clear hackney's cached proxy settings |
| 50 | + application:unset_env(hackney, http_proxy), |
| 51 | + application:unset_env(hackney, https_proxy). |
| 52 | + |
| 53 | +test_empty_proxy_env(Var, _State) -> |
| 54 | + os:putenv(Var, ""), |
| 55 | + %% Clear cached values first |
| 56 | + application:unset_env(hackney, http_proxy), |
| 57 | + application:unset_env(hackney, https_proxy), |
| 58 | + %% This should not crash and should return false (no proxy) |
| 59 | + Result = hackney:get_proxy_env(http), |
| 60 | + ?assertEqual(false, Result), |
| 61 | + os:unsetenv(Var). |
| 62 | + |
| 63 | +test_whitespace_proxy_env(Var, _State) -> |
| 64 | + os:putenv(Var, " "), |
| 65 | + %% Clear cached values first |
| 66 | + application:unset_env(hackney, http_proxy), |
| 67 | + application:unset_env(hackney, https_proxy), |
| 68 | + %% This should not crash and should return false (no proxy) |
| 69 | + Result = hackney:get_proxy_env(http), |
| 70 | + ?assertEqual(false, Result), |
| 71 | + os:unsetenv(Var). |
| 72 | + |
| 73 | +test_multiple_spaces_proxy_env(Var, _State) -> |
| 74 | + os:putenv(Var, " \t \n "), |
| 75 | + %% Clear cached values first |
| 76 | + application:unset_env(hackney, http_proxy), |
| 77 | + application:unset_env(hackney, https_proxy), |
| 78 | + %% This should not crash and should return false (no proxy) |
| 79 | + Result = hackney:get_proxy_env(http), |
| 80 | + ?assertEqual(false, Result), |
| 81 | + os:unsetenv(Var). |
| 82 | + |
| 83 | +test_valid_proxy_env(Var, _State) -> |
| 84 | + ProxyUrl = "http://proxy.example.com:8080", |
| 85 | + os:putenv(Var, ProxyUrl), |
| 86 | + %% Clear cached values first |
| 87 | + application:unset_env(hackney, http_proxy), |
| 88 | + application:unset_env(hackney, https_proxy), |
| 89 | + %% This should return the proxy URL |
| 90 | + Result = hackney:get_proxy_env(http), |
| 91 | + ?assertEqual({ok, ProxyUrl}, Result), |
| 92 | + os:unsetenv(Var). |
| 93 | + |
| 94 | +test_valid_proxy_with_spaces(Var, _State) -> |
| 95 | + ProxyUrl = " http://proxy.example.com:8080 ", |
| 96 | + ExpectedUrl = "http://proxy.example.com:8080", |
| 97 | + os:putenv(Var, ProxyUrl), |
| 98 | + %% Clear cached values first |
| 99 | + application:unset_env(hackney, http_proxy), |
| 100 | + application:unset_env(hackney, https_proxy), |
| 101 | + %% This should return the proxy URL with stripped spaces |
| 102 | + Result = hackney:get_proxy_env(http), |
| 103 | + ?assertEqual({ok, ExpectedUrl}, Result), |
| 104 | + os:unsetenv(Var). |
| 105 | + |
| 106 | +%% Direct tests for do_get_proxy_env function |
| 107 | +do_get_proxy_env_test_() -> |
| 108 | + [ |
| 109 | + {"Empty list returns false", |
| 110 | + fun() -> ?assertEqual(false, hackney:do_get_proxy_env([])) end}, |
| 111 | + {"All empty values returns false", |
| 112 | + fun() -> |
| 113 | + os:putenv("TEST_PROXY1", ""), |
| 114 | + os:putenv("TEST_PROXY2", " "), |
| 115 | + os:putenv("TEST_PROXY3", "\t\n"), |
| 116 | + Result = hackney:do_get_proxy_env(["TEST_PROXY1", "TEST_PROXY2", "TEST_PROXY3"]), |
| 117 | + ?assertEqual(false, Result), |
| 118 | + os:unsetenv("TEST_PROXY1"), |
| 119 | + os:unsetenv("TEST_PROXY2"), |
| 120 | + os:unsetenv("TEST_PROXY3") |
| 121 | + end}, |
| 122 | + {"First valid proxy is returned", |
| 123 | + fun() -> |
| 124 | + os:putenv("TEST_PROXY1", ""), |
| 125 | + os:putenv("TEST_PROXY2", " http://proxy.example.com "), |
| 126 | + os:putenv("TEST_PROXY3", "http://proxy2.example.com"), |
| 127 | + Result = hackney:do_get_proxy_env(["TEST_PROXY1", "TEST_PROXY2", "TEST_PROXY3"]), |
| 128 | + ?assertEqual({ok, "http://proxy.example.com"}, Result), |
| 129 | + os:unsetenv("TEST_PROXY1"), |
| 130 | + os:unsetenv("TEST_PROXY2"), |
| 131 | + os:unsetenv("TEST_PROXY3") |
| 132 | + end} |
| 133 | + ]. |
| 134 | + |
0 commit comments