@@ -58,14 +58,15 @@ const LOCAL_SERVER_URL = 'http://localhost:4444';
58
58
59
59
const SERVER_HANDLER_STREAM_ECHO = ( req , res ) => req . pipe ( res ) ;
60
60
61
- function startHTTPServer ( options ) {
61
+ function startHTTPServer ( handlerOrOptions , options ) {
62
62
63
- const { handler, useBuffering = false , rate = undefined , port = 4444 } = typeof options === 'function' ? {
64
- handler : options
65
- } : options || { } ;
63
+ const { handler, useBuffering = false , rate = undefined , port = 4444 , keepAlive = 1000 } =
64
+ Object . assign ( typeof handlerOrOptions === 'function' ? {
65
+ handler : handlerOrOptions
66
+ } : handlerOrOptions || { } , options ) ;
66
67
67
68
return new Promise ( ( resolve , reject ) => {
68
- http . createServer ( handler || async function ( req , res ) {
69
+ const server = http . createServer ( handler || async function ( req , res ) {
69
70
try {
70
71
req . headers [ 'content-length' ] && res . setHeader ( 'content-length' , req . headers [ 'content-length' ] ) ;
71
72
@@ -93,9 +94,21 @@ function startHTTPServer(options) {
93
94
} ) . listen ( port , function ( err ) {
94
95
err ? reject ( err ) : resolve ( this ) ;
95
96
} ) ;
97
+
98
+ server . keepAliveTimeout = keepAlive ;
96
99
} ) ;
97
100
}
98
101
102
+ const stopHTTPServer = async ( server , timeout = 10000 ) => {
103
+ if ( server ) {
104
+ if ( typeof server . closeAllConnections === 'function' ) {
105
+ server . closeAllConnections ( ) ;
106
+ }
107
+
108
+ await Promise . race ( [ new Promise ( resolve => server . close ( resolve ) ) , setTimeoutAsync ( timeout ) ] ) ;
109
+ }
110
+ }
111
+
99
112
const handleFormData = ( req ) => {
100
113
return new Promise ( ( resolve , reject ) => {
101
114
const form = new formidable . IncomingForm ( ) ;
@@ -131,16 +144,12 @@ function generateReadableStream(length = 1024 * 1024, chunkSize = 10 * 1024, sle
131
144
}
132
145
133
146
describe ( 'supports http with nodejs' , function ( ) {
147
+ afterEach ( async function ( ) {
148
+ await Promise . all ( [ stopHTTPServer ( server ) , stopHTTPServer ( proxy ) ] ) ;
149
+
150
+ server = null ;
151
+ proxy = null ;
134
152
135
- afterEach ( function ( ) {
136
- if ( server ) {
137
- server . close ( ) ;
138
- server = null ;
139
- }
140
- if ( proxy ) {
141
- proxy . close ( ) ;
142
- proxy = null ;
143
- }
144
153
delete process . env . http_proxy ;
145
154
delete process . env . https_proxy ;
146
155
delete process . env . no_proxy ;
@@ -382,53 +391,57 @@ describe('supports http with nodejs', function () {
382
391
} ) ;
383
392
} ) ;
384
393
385
- it ( 'should support beforeRedirect and proxy with redirect' , function ( done ) {
386
- var requestCount = 0 ;
387
- var totalRedirectCount = 5 ;
388
- server = http . createServer ( function ( req , res ) {
394
+ it ( 'should support beforeRedirect and proxy with redirect' , async ( ) => {
395
+ let requestCount = 0 ;
396
+ let totalRedirectCount = 5 ;
397
+
398
+ server = await startHTTPServer ( function ( req , res ) {
389
399
requestCount += 1 ;
390
400
if ( requestCount <= totalRedirectCount ) {
391
401
res . setHeader ( 'Location' , 'http://localhost:4444' ) ;
392
402
res . writeHead ( 302 ) ;
393
403
}
394
404
res . end ( ) ;
395
- } ) . listen ( 4444 , function ( ) {
396
- var proxyUseCount = 0 ;
397
- proxy = http . createServer ( function ( request , response ) {
398
- proxyUseCount += 1 ;
399
- var parsed = url . parse ( request . url ) ;
400
- var opts = {
401
- host : parsed . hostname ,
402
- port : parsed . port ,
403
- path : parsed . path
404
- } ;
405
+ } , { port : 4444 } ) ;
406
+
407
+ let proxyUseCount = 0 ;
408
+ proxy = await startHTTPServer ( function ( req , res ) {
409
+ proxyUseCount += 1 ;
410
+ const targetUrl = new URL ( req . url , 'http://' + req . headers . host ) ;
411
+ const opts = {
412
+ host : targetUrl . hostname ,
413
+ port : targetUrl . port ,
414
+ path : targetUrl . path ,
415
+ method : req . method
416
+ } ;
405
417
406
- http . get ( opts , function ( res ) {
407
- response . writeHead ( res . statusCode , res . headers ) ;
408
- res . on ( 'data' , function ( data ) {
409
- response . write ( data )
410
- } ) ;
411
- res . on ( 'end' , function ( ) {
412
- response . end ( ) ;
413
- } ) ;
414
- } ) ;
415
- } ) . listen ( 4000 , function ( ) {
416
- var configBeforeRedirectCount = 0 ;
417
- axios . get ( 'http://localhost:4444/' , {
418
- proxy : {
419
- host : 'localhost' ,
420
- port : 4000
421
- } ,
422
- maxRedirects : totalRedirectCount ,
423
- beforeRedirect : function ( options ) {
424
- configBeforeRedirectCount += 1 ;
425
- }
426
- } ) . then ( function ( res ) {
427
- assert . equal ( totalRedirectCount , configBeforeRedirectCount , 'should invoke config.beforeRedirect option on every redirect' ) ;
428
- assert . equal ( totalRedirectCount + 1 , proxyUseCount , 'should go through proxy on every redirect' ) ;
429
- done ( ) ;
430
- } ) . catch ( done ) ;
418
+ const request = http . get ( opts , function ( response ) {
419
+ res . writeHead ( response . statusCode , response . headers ) ;
420
+ stream . pipeline ( response , res , ( ) => { } ) ;
431
421
} ) ;
422
+
423
+ request . on ( 'error' , ( err ) => {
424
+ console . warn ( 'request error' , err ) ;
425
+ res . statusCode = 500 ;
426
+ res . end ( ) ;
427
+ } )
428
+
429
+ } , { port : 4000 } ) ;
430
+
431
+ let configBeforeRedirectCount = 0 ;
432
+
433
+ await axios . get ( 'http://localhost:4444/' , {
434
+ proxy : {
435
+ host : 'localhost' ,
436
+ port : 4000
437
+ } ,
438
+ maxRedirects : totalRedirectCount ,
439
+ beforeRedirect : function ( options ) {
440
+ configBeforeRedirectCount += 1 ;
441
+ }
442
+ } ) . then ( function ( res ) {
443
+ assert . equal ( totalRedirectCount , configBeforeRedirectCount , 'should invoke config.beforeRedirect option on every redirect' ) ;
444
+ assert . equal ( totalRedirectCount + 1 , proxyUseCount , 'should go through proxy on every redirect' ) ;
432
445
} ) ;
433
446
} ) ;
434
447
@@ -666,31 +679,18 @@ describe('supports http with nodejs', function () {
666
679
} ) ;
667
680
} ) ;
668
681
669
- it ( 'should support max content length' , function ( done ) {
670
- var str = Array ( 100000 ) . join ( 'ж' ) ;
671
-
672
- server = http . createServer ( function ( req , res ) {
682
+ it ( 'should support max content length' , async function ( ) {
683
+ server = await startHTTPServer ( function ( req , res ) {
673
684
res . setHeader ( 'Content-Type' , 'text/html; charset=UTF-8' ) ;
674
- res . end ( str ) ;
675
- } ) . listen ( 4444 , function ( ) {
676
- var success = false , failure = false , error ;
685
+ res . end ( Array ( 5000 ) . join ( '#' ) ) ;
686
+ } , { port : 4444 } ) ;
677
687
678
- axios . get ( 'http://localhost:4444/' , {
679
- maxContentLength : 2000
680
- } ) . then ( function ( res ) {
681
- success = true ;
682
- } ) . catch ( function ( err ) {
683
- error = err ;
684
- failure = true ;
685
- } ) ;
686
-
687
- setTimeout ( function ( ) {
688
- assert . equal ( success , false , 'request should not succeed' ) ;
689
- assert . equal ( failure , true , 'request should fail' ) ;
690
- assert . equal ( error . message , 'maxContentLength size of 2000 exceeded' ) ;
691
- done ( ) ;
692
- } , 100 ) ;
693
- } ) ;
688
+ await assert . rejects ( ( ) => {
689
+ return axios . get ( 'http://localhost:4444/' , {
690
+ maxContentLength : 2000 ,
691
+ maxRedirects : 0
692
+ } )
693
+ } , / m a x C o n t e n t L e n g t h s i z e o f 2 0 0 0 e x c e e d e d / ) ;
694
694
} ) ;
695
695
696
696
it ( 'should support max content length for redirected' , function ( done ) {
@@ -711,7 +711,7 @@ describe('supports http with nodejs', function () {
711
711
var success = false , failure = false , error ;
712
712
713
713
axios . get ( 'http://localhost:4444/one' , {
714
- maxContentLength : 2000
714
+ maxContentLength : 2000 ,
715
715
} ) . then ( function ( res ) {
716
716
success = true ;
717
717
} ) . catch ( function ( err ) {
0 commit comments