1- import { describe , it , expect , mock , afterAll } from "bun:test"
1+ import { describe , it , expect , mock , afterAll , beforeAll } from "bun:test"
22import { buildQueryString } from "../src/utils"
33import { FetchProxy } from "../src/proxy"
44
5- afterAll ( ( ) => {
5+ let testServer : any
6+ let testPort : number
7+
8+ beforeAll ( async ( ) => {
9+ // Create a local test server that mimics httpbin.org/get
10+ testPort = 3000 + Math . floor ( Math . random ( ) * 1000 )
11+ testServer = Bun . serve ( {
12+ port : testPort ,
13+ fetch ( req ) {
14+ const url = new URL ( req . url )
15+ return new Response (
16+ JSON . stringify ( {
17+ url : req . url ,
18+ headers : Object . fromEntries ( req . headers . entries ( ) ) ,
19+ args : Object . fromEntries ( url . searchParams . entries ( ) ) ,
20+ method : req . method ,
21+ } ) ,
22+ {
23+ headers : { "Content-Type" : "application/json" } ,
24+ } ,
25+ )
26+ } ,
27+ } )
28+
29+ // Wait for server to be ready
30+ for ( let i = 0 ; i < 20 ; i ++ ) {
31+ try {
32+ const response = await fetch ( `http://localhost:${ testPort } /test` )
33+ if ( response . ok ) break
34+ } catch ( e ) {
35+ if ( i === 19 ) throw new Error ( "Test server failed to start" )
36+ await new Promise ( ( resolve ) => setTimeout ( resolve , 150 ) )
37+ }
38+ }
39+ } )
40+
41+ afterAll ( async ( ) => {
642 mock . restore ( )
43+ if ( testServer ) {
44+ testServer . stop ( )
45+ }
746} )
847
948describe ( "Query String Injection Security Tests" , ( ) => {
@@ -180,7 +219,7 @@ describe("Query String Injection Security Tests", () => {
180219 describe ( "Proxy Integration with Query Injection" , ( ) => {
181220 it ( "should safely handle query string injection through proxy" , async ( ) => {
182221 const proxy = new FetchProxy ( {
183- base : " http://httpbin.org" ,
222+ base : ` http://localhost: ${ testPort } ` ,
184223 circuitBreaker : { enabled : false } ,
185224 } )
186225
@@ -191,14 +230,14 @@ describe("Query String Injection Security Tests", () => {
191230 special : "value with spaces and symbols!@#$%^&*()" ,
192231 }
193232
194- const request = new Request ( " http://httpbin.org /get" )
233+ const request = new Request ( ` http://localhost: ${ testPort } /get` )
195234
196235 try {
197236 const response = await proxy . proxy ( request , "/get" , {
198237 queryString : safeParams ,
199238 } )
200239
201- // Should get a successful response (httpbin.org should handle encoded params safely)
240+ // Should get a successful response (local server should handle encoded params safely)
202241 expect ( response . status ) . toBe ( 200 )
203242
204243 const data = ( await response . json ( ) ) as any
@@ -220,7 +259,7 @@ describe("Query String Injection Security Tests", () => {
220259
221260 it ( "should reject dangerous CRLF injection attempts in proxy" , async ( ) => {
222261 const proxy = new FetchProxy ( {
223- base : " http://httpbin.org" ,
262+ base : ` http://localhost: ${ testPort } ` ,
224263 circuitBreaker : { enabled : false } ,
225264 } )
226265
@@ -230,7 +269,7 @@ describe("Query String Injection Security Tests", () => {
230269 crlf : "value\r\nX-Injected-Header: evil" ,
231270 }
232271
233- const request = new Request ( " http://httpbin.org /get" )
272+ const request = new Request ( ` http://localhost: ${ testPort } /get` )
234273
235274 // This should return a 400 Bad Request due to our security validation
236275 const response = await proxy . proxy ( request , "/get" , {
@@ -246,11 +285,11 @@ describe("Query String Injection Security Tests", () => {
246285
247286 it ( "should safely merge query strings with existing URL parameters" , async ( ) => {
248287 const proxy = new FetchProxy ( {
249- base : " http://httpbin.org" ,
288+ base : ` http://localhost: ${ testPort } ` ,
250289 circuitBreaker : { enabled : false } ,
251290 } )
252291
253- const request = new Request ( " http://httpbin.org /get" )
292+ const request = new Request ( ` http://localhost: ${ testPort } /get` )
254293
255294 try {
256295 // Test merging with URL that already has query parameters
0 commit comments