@@ -58,14 +58,15 @@ const LOCAL_SERVER_URL = 'http://localhost:4444';
5858
5959const SERVER_HANDLER_STREAM_ECHO = ( req , res ) => req . pipe ( res ) ;
6060
61- function startHTTPServer ( options ) {
61+ function startHTTPServer ( handlerOrOptions , options ) {
6262
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 ) ;
6667
6768 return new Promise ( ( resolve , reject ) => {
68- http . createServer ( handler || async function ( req , res ) {
69+ const server = http . createServer ( handler || async function ( req , res ) {
6970 try {
7071 req . headers [ 'content-length' ] && res . setHeader ( 'content-length' , req . headers [ 'content-length' ] ) ;
7172
@@ -93,9 +94,21 @@ function startHTTPServer(options) {
9394 } ) . listen ( port , function ( err ) {
9495 err ? reject ( err ) : resolve ( this ) ;
9596 } ) ;
97+
98+ server . keepAliveTimeout = keepAlive ;
9699 } ) ;
97100}
98101
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+
99112const handleFormData = ( req ) => {
100113 return new Promise ( ( resolve , reject ) => {
101114 const form = new formidable . IncomingForm ( ) ;
@@ -131,16 +144,12 @@ function generateReadableStream(length = 1024 * 1024, chunkSize = 10 * 1024, sle
131144}
132145
133146describe ( 'supports http with nodejs' , function ( ) {
147+ afterEach ( async function ( ) {
148+ await Promise . all ( [ stopHTTPServer ( server ) , stopHTTPServer ( proxy ) ] ) ;
149+
150+ server = null ;
151+ proxy = null ;
134152
135- afterEach ( function ( ) {
136- if ( server ) {
137- server . close ( ) ;
138- server = null ;
139- }
140- if ( proxy ) {
141- proxy . close ( ) ;
142- proxy = null ;
143- }
144153 delete process . env . http_proxy ;
145154 delete process . env . https_proxy ;
146155 delete process . env . no_proxy ;
@@ -382,53 +391,57 @@ describe('supports http with nodejs', function () {
382391 } ) ;
383392 } ) ;
384393
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 ) {
389399 requestCount += 1 ;
390400 if ( requestCount <= totalRedirectCount ) {
391401 res . setHeader ( 'Location' , 'http://localhost:4444' ) ;
392402 res . writeHead ( 302 ) ;
393403 }
394404 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+ } ;
405417
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 , ( ) => { } ) ;
431421 } ) ;
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' ) ;
432445 } ) ;
433446 } ) ;
434447
@@ -666,31 +679,18 @@ describe('supports http with nodejs', function () {
666679 } ) ;
667680 } ) ;
668681
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 ) {
673684 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 } ) ;
677687
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 / ) ;
694694 } ) ;
695695
696696 it ( 'should support max content length for redirected' , function ( done ) {
@@ -711,7 +711,7 @@ describe('supports http with nodejs', function () {
711711 var success = false , failure = false , error ;
712712
713713 axios . get ( 'http://localhost:4444/one' , {
714- maxContentLength : 2000
714+ maxContentLength : 2000 ,
715715 } ) . then ( function ( res ) {
716716 success = true ;
717717 } ) . catch ( function ( err ) {
0 commit comments