@@ -111,6 +111,72 @@ func TestProxyHTTP(t *testing.T) {
111111 }
112112}
113113
114+ // TestProxyHTTPBlocklist tests that the proxy can block HTTP requests from
115+ // a blocked IP.
116+ func TestProxyHTTPBlocklist (t * testing.T ) {
117+ services := []* proxy.Service {{
118+ Address : testTargetServiceAddress ,
119+ HostRegexp : testHostRegexp ,
120+ PathRegexp : testPathRegexpHTTP ,
121+ Protocol : "http" ,
122+ Auth : "off" ,
123+ }}
124+
125+ mockAuth := auth .NewMockAuthenticator ()
126+
127+ // Block the IP that will be used in the request.
128+ blockedIP := "127.0.0.1"
129+ p , err := proxy .New (mockAuth , services , []string {blockedIP })
130+ require .NoError (t , err )
131+
132+ // Start the proxy server.
133+ server := & http.Server {
134+ Addr : testProxyAddr ,
135+ Handler : http .HandlerFunc (p .ServeHTTP ),
136+ }
137+ go func () {
138+ if err := server .ListenAndServe (); err != http .ErrServerClosed {
139+ t .Errorf ("proxy serve error: %v" , err )
140+ }
141+ }()
142+ defer closeOrFail (t , server )
143+
144+ // Start the backend server.
145+ backendService := & http.Server {Addr : testTargetServiceAddress }
146+ go func () { _ = startBackendHTTP (backendService ) }()
147+ defer closeOrFail (t , backendService )
148+
149+ time .Sleep (100 * time .Millisecond )
150+
151+ // Make a request with a spoofed RemoteAddr that matches the blocklist.
152+ req , err := http .NewRequest (
153+ "GET" ,
154+ fmt .Sprintf ("http://%s/http/test" , testProxyAddr ),
155+ nil ,
156+ )
157+ require .NoError (t , err )
158+
159+ // Create a custom transport to override the local IP — simulate blocked IP.
160+ customTransport := & http.Transport {
161+ DialContext : func (_ context.Context , _ , _ string ) (net.Conn , error ) {
162+ lAddr , _ := net .ResolveTCPAddr ("tcp" , "127.0.0.1:0" )
163+ d := net.Dialer {LocalAddr : lAddr }
164+ return d .DialContext (context .Background (), "tcp" , testProxyAddr )
165+ },
166+ }
167+ client := & http.Client {Transport : customTransport }
168+
169+ resp , err := client .Do (req )
170+ require .NoError (t , err )
171+ defer resp .Body .Close ()
172+
173+ require .Equal (t , http .StatusForbidden , resp .StatusCode )
174+
175+ body , err := io .ReadAll (resp .Body )
176+ require .NoError (t , err )
177+ require .Equal (t , "access denied\n " , string (body ))
178+ }
179+
114180// runHTTPTest tests that the proxy can forward HTTP requests to a backend
115181// service and handle L402 authentication correctly.
116182func runHTTPTest (t * testing.T , tc * testCase , method string ) {
@@ -125,7 +191,7 @@ func runHTTPTest(t *testing.T, tc *testCase, method string) {
125191 }}
126192
127193 mockAuth := auth .NewMockAuthenticator ()
128- p , err := proxy .New (mockAuth , services )
194+ p , err := proxy .New (mockAuth , services , [] string {} )
129195 require .NoError (t , err )
130196
131197 // Start server that gives requests to the proxy.
@@ -288,7 +354,7 @@ func runGRPCTest(t *testing.T, tc *testCase) {
288354
289355 // Create the proxy server and start serving on TLS.
290356 mockAuth := auth .NewMockAuthenticator ()
291- p , err := proxy .New (mockAuth , services )
357+ p , err := proxy .New (mockAuth , services , [] string {} )
292358 require .NoError (t , err )
293359 server := & http.Server {
294360 Addr : testProxyAddr ,
0 commit comments