2828
2929@pytest .mark .describe ("HTTPTransport - Instantiation" )
3030class TestInstantiation (object ):
31- @pytest .fixture (
32- params = ["HTTP" , "SOCKS4" , "SOCKS5" ]
33- )
34- def proxy_type (request ):
31+ # @pytest.fixture(
32+ # params=["HTTP", "SOCKS4", "SOCKS5"]
33+ # )
34+ # def proxy_type(self, request):
35+ # return request.param
36+
37+ # @pytest.fixture(params=[
38+ # pytest.param((None, None), id="No Auth"),
39+ # pytest.param(("fake_username", "fake_password"), id="Auth (standard chars)"),
40+ # pytest.param(("malicious-user\\r\\nX-Evil-Header: injected-value", "fake_password"), id="Auth (malicious chars)")
41+ # ])
42+ # def proxy_auth(self, request):
43+ # return request.param
44+
45+ # @pytest.fixture
46+ # def proxy_options(self, proxy_type, proxy_auth):
47+ # return ProxyOptions(
48+ # proxy_type=proxy_type,
49+ # proxy_addr="127.0.0.1",
50+ # proxy_port=1080,
51+ # proxy_username=proxy_auth[0],
52+ # proxy_password=proxy_auth[1],
53+ # )
54+
55+ @pytest .fixture (params = ["HTTP" , "SOCKS4" , "SOCKS5" ])
56+ def proxy_type (self , request ):
3557 return request .param
3658
37- @pytest .fixture (params = ["No Auth" , "Auth (standard chars)" , "Auth (special chars)" ])
38- def proxy_auth_type (request ):
59+ @pytest .fixture (
60+ params = [
61+ pytest .param ((None , None ), id = "No Auth" ),
62+ pytest .param (("fake_username" , "fake_password" ), id = "Auth" ),
63+ ]
64+ )
65+ def proxy_auth (self , request ):
3966 return request .param
4067
41- def proxy_options (self , proxy_type , proxy_auth_type ):
42- if "No Auth" in proxy_auth_type :
43- proxy = ProxyOptions (proxy_type = proxy_type , proxy_addr = "127.0.0.1" , proxy_port = 1080 )
44- else :
45- proxy = ProxyOptions (
46- proxy_type = proxy_type ,
47- proxy_addr = "127.0.0.1" ,
48- proxy_port = 1080 ,
49- proxy_username = "fake_username" ,
50- proxy_password = "fake_password" ,
51- )
52- return proxy
68+ @pytest .fixture
69+ def proxy_options (self , proxy_type , proxy_auth ):
70+ return ProxyOptions (
71+ proxy_type = proxy_type ,
72+ proxy_addr = "127.0.0.1" ,
73+ proxy_port = 1080 ,
74+ proxy_username = proxy_auth [0 ],
75+ proxy_password = proxy_auth [1 ],
76+ )
5377
5478 @pytest .mark .it ("Stores the hostname for later use" )
5579 def test_sets_required_parameters (self , mocker ):
@@ -69,7 +93,6 @@ def test_sets_required_parameters(self, mocker):
6993 @pytest .mark .it (
7094 "Creates a dictionary of proxies from the 'proxy_options' parameter, if the parameter is provided"
7195 )
72-
7396 def test_proxy_format (self , proxy_options ):
7497 http_transport_object = HTTPTransport (hostname = fake_hostname , proxy_options = proxy_options )
7598
@@ -96,6 +119,70 @@ def test_proxy_format(self, proxy_options):
96119 assert http_transport_object ._proxies ["http" ] == expected_proxy_string
97120 assert http_transport_object ._proxies ["https" ] == expected_proxy_string
98121
122+ @pytest .mark .it ("URL encodes the proxy username and password when creating the proxy strings" )
123+ @pytest .mark .parametrize (
124+ "proxy_username, proxy_password, encoded_username, encoded_password" ,
125+ [
126+ pytest .param (
127+ "u$ern@me" ,
128+ "p@$$w?rd" ,
129+ "u%24ern%40me" ,
130+ "p%40%24%24w%3Frd" ,
131+ id = "Standard URL encoding" ,
132+ ),
133+ pytest .param (
134+ "user name with spaces" ,
135+ "password with spaces" ,
136+ "user%20name%20with%20spaces" ,
137+ "password%20with%20spaces" ,
138+ id = "URL encoding of ' ' character" ,
139+ ),
140+ pytest .param (
141+ "user/name/with/slashes" ,
142+ "password/with/slashes" ,
143+ "user%2Fname%2Fwith%2Fslashes" ,
144+ "password%2Fwith%2Fslashes" ,
145+ id = "URL encoding of '/' character" ,
146+ ),
147+ pytest .param (
148+ "malicious-user\\ r\\ nX-Evil-Header: injected-value" ,
149+ "malicious-password\\ r\\ nX-Evil-Header: injected-value" ,
150+ "malicious-user%5Cr%5CnX-Evil-Header%3A%20injected-value" ,
151+ "malicious-password%5Cr%5CnX-Evil-Header%3A%20injected-value" ,
152+ id = "URL encoding of malicious chars" ,
153+ ),
154+ ],
155+ )
156+ def test_proxy_auth_url_encoded (
157+ self , proxy_type , proxy_username , proxy_password , encoded_username , encoded_password
158+ ):
159+ proxy_options = ProxyOptions (
160+ proxy_type = proxy_type ,
161+ proxy_addr = "127.0.0.1" ,
162+ proxy_port = 1080 ,
163+ proxy_username = proxy_username ,
164+ proxy_password = proxy_password ,
165+ )
166+
167+ http_transport_object = HTTPTransport (hostname = fake_hostname , proxy_options = proxy_options )
168+
169+ expected_proxy_string = "{username}:{password}@{address}:{port}" .format (
170+ username = encoded_username ,
171+ password = encoded_password ,
172+ address = proxy_options .proxy_address ,
173+ port = proxy_options .proxy_port ,
174+ )
175+
176+ if proxy_options .proxy_type == "HTTP" :
177+ expected_proxy_string = "http://" + expected_proxy_string
178+ elif proxy_options .proxy_type == "SOCKS4" :
179+ expected_proxy_string = "socks4://" + expected_proxy_string
180+ else :
181+ expected_proxy_string = "socks5://" + expected_proxy_string
182+
183+ assert http_transport_object ._proxies ["http" ] == expected_proxy_string
184+ assert http_transport_object ._proxies ["https" ] == expected_proxy_string
185+
99186 @pytest .mark .it (
100187 "Configures TLS/SSL context to use TLS 1.2, require certificates and check hostname"
101188 )
0 commit comments