1111import os
1212import re
1313import pytest
14+ from http .server import BaseHTTPRequestHandler , HTTPServer
15+ from threading import Thread
1416
1517
1618# Use the same port across tests
1921mock_server_thread = None
2022
2123
24+ # Simple HTTP proxy server for testing proxy functionality
25+ class SimpleProxyHandler (BaseHTTPRequestHandler ):
26+ """A simple HTTP proxy handler that logs requests"""
27+
28+ def do_GET (self ):
29+ self .send_response (200 )
30+ self .send_header ("Content-Type" , "text/plain" )
31+ self .end_headers ()
32+ self .wfile .write (b"Request proxied successfully" )
33+ print (f"Proxy handled request: { self .path } " )
34+
35+ def do_PUT (self ):
36+ self .send_response (200 )
37+ self .send_header ("Content-Type" , "text/plain" )
38+ self .end_headers ()
39+ self .wfile .write (b"Request proxied successfully" )
40+ print (f"Proxy handled PUT request: { self .path } " )
41+
42+ def log_message (self , format , * args ):
43+ # Customize logging to show it's from the proxy
44+ print (f"PROXY LOG: { format % args } " )
45+
46+
47+ # Global variables for proxy server
48+ proxy_port = get_free_port ()
49+ proxy_server = None
50+ proxy_server_thread = None
51+
52+
2253def setup_module (module ):
2354 """setup any state specific to the execution of the given module."""
2455 global mock_server
2556 global mock_server_thread
57+ global proxy_server
58+ global proxy_server_thread
59+
60+ # Start the mock registry server
2661 mock_server , mock_server_thread = start_mock_server (port )
2762
63+ # Start the proxy server
64+ proxy_server = HTTPServer (("localhost" , proxy_port ), SimpleProxyHandler )
65+ proxy_server_thread = Thread (target = proxy_server .serve_forever )
66+ proxy_server_thread .setDaemon (True )
67+ proxy_server_thread .start ()
68+ print (f"Proxy server started on port { proxy_port } " )
69+
2870
2971def teardown_module (module ):
3072 """teardown any state that was previously setup with a setup_module
3173 method.
3274 """
3375 mock_server .server_close ()
76+ proxy_server .server_close ()
3477
3578
3679def test_distribution_mock_server (tmp_path ):
@@ -47,6 +90,24 @@ def test_distribution_mock_server(tmp_path):
4790 )
4891 assert not client .Config .Debug
4992
93+ print ("Testing creation of client with proxy" )
94+ proxy_url = f"http://localhost:{ proxy_port } "
95+ proxy_client = NewClient (
96+ mock_url ,
97+ WithUsernamePassword ("testuser" , "testpass" ),
98+ WithDefaultName ("testname" ),
99+ WithUserAgent ("reggie-tests" ),
100+ WithProxy (proxy_url ),
101+ )
102+ assert proxy_client .Config .Proxy == proxy_url
103+
104+ # Make a request with the proxy client
105+ req = proxy_client .NewRequest ("GET" , "/v2/<n>/tags/list" )
106+ response = proxy_client .Do (req )
107+ assert (
108+ response .status_code == 200
109+ ), f"Expected status code 200, got { response .status_code } "
110+
50111 print ("Testing setting debug option" )
51112 clientDebug = NewClient (mock_url , WithDebug (True ))
52113 assert clientDebug .Config .Debug
@@ -189,6 +250,27 @@ def test_distribution_mock_server(tmp_path):
189250 print ("Check that the body did not get lost somewhere" )
190251 assert req .body == "abc"
191252
253+ print ("Test proxy request with different configuration" )
254+ # Create a client with a different proxy configuration
255+ alt_proxy_url = f"http://localhost:{ proxy_port } /alternate"
256+ alt_proxy_client = NewClient (
257+ mock_url ,
258+ WithProxy (alt_proxy_url ),
259+ )
260+ assert alt_proxy_client .Config .Proxy == alt_proxy_url
261+
262+ # Verify that proxy setting is correctly passed to the request
263+ proxy_req = alt_proxy_client .NewRequest ("GET" , "/v2/test/tags/list" )
264+ assert (
265+ proxy_req .proxies
266+ ), "Request should have non-empty proxies dictionary when proxy is set"
267+ assert (
268+ proxy_req .proxies .get ("http" ) == alt_proxy_url
269+ ), "HTTP proxy not correctly set"
270+ assert (
271+ proxy_req .proxies .get ("https" ) == alt_proxy_url
272+ ), "HTTPS proxy not correctly set"
273+
192274 print ("Test that the retry callback is invoked, if configured." )
193275 newBody = "not the original body"
194276
@@ -214,3 +296,12 @@ def errorFunc(r):
214296 )
215297 except Exception as exc :
216298 assert "ruhroh" in str (exc )
299+
300+ print ("Test proxy setting in request client" )
301+ # Directly test the SetProxy method on the request client
302+ req = client .NewRequest ("GET" , "/test/endpoint" )
303+ proxy_addr = f"http://localhost:{ proxy_port } /direct-test"
304+ req .SetProxy (proxy_addr )
305+ # Verify that the proxy is set in the underlying request object when it's executed
306+ response = client .Do (req )
307+ assert response .status_code == 200 , "Request through proxy should succeed"
0 commit comments