22var common = require ( '../common' ) ;
33var assert = require ( 'assert' ) ;
44
5+ // Here we are testing the HTTP server module's flood prevention mechanism.
6+ // When writeable.write returns false (ie the underlying send() indicated the
7+ // native buffer is full), the HTTP server cork()s the readable part of the
8+ // stream. This means that new requests will not be read (however request which
9+ // have already been read, but are awaiting processing will still be
10+ // processed).
11+
12+ // Normally when the writable stream emits a 'drain' event, the server then
13+ // uncorks the readable stream, although we arent testing that part here.
14+
515switch ( process . argv [ 2 ] ) {
616 case undefined :
717 return parent ( ) ;
@@ -18,22 +28,31 @@ function parent() {
1828 var childClosed = false ;
1929 var requests = 0 ;
2030 var connections = 0 ;
31+ var backloggedReqs = 0 ;
2132
2233 var server = http . createServer ( function ( req , res ) {
2334 requests ++ ;
2435 res . setHeader ( 'content-length' , bigResponse . length ) ;
25- res . end ( bigResponse ) ;
36+ if ( ! res . write ( bigResponse ) ) {
37+ if ( backloggedReqs == 0 ) {
38+ // Once the native buffer fills (ie write() returns false), the flood
39+ // prevention should kick in.
40+ // This means the stream should emit no more 'data' events. However we
41+ // may still be asked to process more requests if they were read before
42+ // mechanism activated.
43+ req . socket . on ( 'data' , function ( ) { assert ( false ) ; } ) ;
44+ }
45+ backloggedReqs ++ ;
46+ }
47+ res . end ( ) ;
2648 } ) ;
2749
2850 server . on ( 'connection' , function ( conn ) {
2951 connections ++ ;
3052 } ) ;
3153
32- // kill the connection after a bit, verifying that the
33- // flood of requests was eventually halted.
3454 server . setTimeout ( 200 , function ( conn ) {
3555 gotTimeout = true ;
36- conn . destroy ( ) ;
3756 } ) ;
3857
3958 server . listen ( common . PORT , function ( ) {
@@ -53,17 +72,16 @@ function parent() {
5372 assert . equal ( connections , 1 ) ;
5473 // The number of requests we end up processing before the outgoing
5574 // connection backs up and requires a drain is implementation-dependent.
56- // We can safely assume is more than 250.
5775 console . log ( 'server got %d requests' , requests ) ;
58- assert ( requests >= 250 ) ;
76+ console . log ( 'server sent %d backlogged requests' , backloggedReqs ) ;
77+
5978 console . log ( 'ok' ) ;
6079 } ) ;
6180}
6281
6382function child ( ) {
6483 var net = require ( 'net' ) ;
6584
66- var gotEpipe = false ;
6785 var conn = net . connect ( { port : common . PORT } ) ;
6886
6987 var req = 'GET / HTTP/1.1\r\nHost: localhost:' +
@@ -72,17 +90,14 @@ function child() {
7290 req = new Array ( 10241 ) . join ( req ) ;
7391
7492 conn . on ( 'connect' , function ( ) {
93+ //kill child after 1s of flooding
94+ setTimeout ( function ( ) { conn . destroy ( ) ; } , 1000 ) ;
7595 write ( ) ;
7696 } ) ;
7797
7898 conn . on ( 'drain' , write ) ;
7999
80- conn . on ( 'error' , function ( er ) {
81- gotEpipe = true ;
82- } ) ;
83-
84100 process . on ( 'exit' , function ( ) {
85- assert ( gotEpipe ) ;
86101 console . log ( 'ok - child' ) ;
87102 } ) ;
88103
0 commit comments