@@ -114,19 +114,30 @@ function parserOnHeadersComplete(info) {
114
114
return skipBody ;
115
115
}
116
116
117
+ // XXX This is a mess.
118
+ // TODO: http.Parser should be a Writable emits request/response events.
117
119
function parserOnBody ( b , start , len ) {
118
120
var parser = this ;
119
- var slice = b . slice ( start , start + len ) ;
120
- if ( parser . incoming . _paused || parser . incoming . _pendings . length ) {
121
- parser . incoming . _pendings . push ( slice ) ;
122
- } else {
123
- parser . incoming . _emitData ( slice ) ;
121
+ var stream = parser . incoming ;
122
+ var rs = stream . _readableState ;
123
+ var socket = stream . socket ;
124
+
125
+ // pretend this was the result of a stream._read call.
126
+ if ( len > 0 ) {
127
+ var slice = b . slice ( start , start + len ) ;
128
+ rs . onread ( null , slice ) ;
124
129
}
130
+
131
+ if ( rs . length >= rs . highWaterMark )
132
+ socket . pause ( ) ;
125
133
}
126
134
127
135
function parserOnMessageComplete ( ) {
128
136
var parser = this ;
129
- parser . incoming . complete = true ;
137
+ var stream = parser . incoming ;
138
+ var socket = stream . socket ;
139
+
140
+ stream . complete = true ;
130
141
131
142
// Emit any trailing headers.
132
143
var headers = parser . _headers ;
@@ -140,19 +151,13 @@ function parserOnMessageComplete() {
140
151
parser . _url = '' ;
141
152
}
142
153
143
- if ( ! parser . incoming . upgrade ) {
154
+ if ( ! stream . upgrade )
144
155
// For upgraded connections, also emit this after parser.execute
145
- if ( parser . incoming . _paused || parser . incoming . _pendings . length ) {
146
- parser . incoming . _pendings . push ( END_OF_FILE ) ;
147
- } else {
148
- parser . incoming . readable = false ;
149
- parser . incoming . _emitEnd ( ) ;
150
- }
151
- }
156
+ stream . _readableState . onread ( null , null ) ;
152
157
153
158
if ( parser . socket . readable ) {
154
159
// force to read the next incoming message
155
- parser . socket . resume ( ) ;
160
+ socket . resume ( ) ;
156
161
}
157
162
}
158
163
@@ -263,9 +268,13 @@ function utcDate() {
263
268
264
269
/* Abstract base class for ServerRequest and ClientResponse. */
265
270
function IncomingMessage ( socket ) {
266
- Stream . call ( this ) ;
271
+ Stream . Readable . call ( this ) ;
272
+
273
+ // XXX This implementation is kind of all over the place
274
+ // When the parser emits body chunks, they go in this list.
275
+ // _read() pulls them out, and when it finds EOF, it ends.
276
+ this . _pendings = [ ] ;
267
277
268
- // TODO Remove one of these eventually.
269
278
this . socket = socket ;
270
279
this . connection = socket ;
271
280
@@ -276,77 +285,49 @@ function IncomingMessage(socket) {
276
285
277
286
this . readable = true ;
278
287
279
- this . _paused = false ;
280
288
this . _pendings = [ ] ;
281
-
282
- this . _endEmitted = false ;
289
+ this . _pendingIndex = 0 ;
283
290
284
291
// request (server) only
285
292
this . url = '' ;
286
-
287
293
this . method = null ;
288
294
289
295
// response (client) only
290
296
this . statusCode = null ;
291
297
this . client = this . socket ;
298
+
299
+ // flag for backwards compatibility grossness.
300
+ this . _consuming = false ;
292
301
}
293
- util . inherits ( IncomingMessage , Stream ) ;
302
+ util . inherits ( IncomingMessage , Stream . Readable ) ;
294
303
295
304
296
305
exports . IncomingMessage = IncomingMessage ;
297
306
298
307
299
- IncomingMessage . prototype . destroy = function ( error ) {
300
- this . socket . destroy ( error ) ;
308
+ IncomingMessage . prototype . read = function ( n ) {
309
+ this . _consuming = true ;
310
+ return Stream . Readable . prototype . read . call ( this , n ) ;
301
311
} ;
302
312
303
313
304
- IncomingMessage . prototype . setEncoding = function ( encoding ) {
305
- var StringDecoder = require ( 'string_decoder' ) . StringDecoder ; // lazy load
306
- this . _decoder = new StringDecoder ( encoding ) ;
307
- } ;
308
-
309
-
310
- IncomingMessage . prototype . pause = function ( ) {
311
- this . _paused = true ;
312
- this . socket . pause ( ) ;
314
+ IncomingMessage . prototype . _read = function ( n , callback ) {
315
+ // We actually do almost nothing here, because the parserOnBody
316
+ // function fills up our internal buffer directly. However, we
317
+ // do need to unpause the underlying socket so that it flows.
318
+ if ( ! this . socket . readable )
319
+ return callback ( null , null ) ;
320
+ else
321
+ this . socket . resume ( ) ;
313
322
} ;
314
323
315
324
316
- IncomingMessage . prototype . resume = function ( ) {
317
- this . _paused = false ;
318
- if ( this . socket ) {
319
- this . socket . resume ( ) ;
320
- }
321
-
322
- this . _emitPending ( ) ;
325
+ IncomingMessage . prototype . destroy = function ( error ) {
326
+ this . socket . destroy ( error ) ;
323
327
} ;
324
328
325
329
326
- IncomingMessage . prototype . _emitPending = function ( callback ) {
327
- if ( this . _pendings . length ) {
328
- var self = this ;
329
- process . nextTick ( function ( ) {
330
- while ( ! self . _paused && self . _pendings . length ) {
331
- var chunk = self . _pendings . shift ( ) ;
332
- if ( chunk !== END_OF_FILE ) {
333
- assert ( Buffer . isBuffer ( chunk ) ) ;
334
- self . _emitData ( chunk ) ;
335
- } else {
336
- assert ( self . _pendings . length === 0 ) ;
337
- self . readable = false ;
338
- self . _emitEnd ( ) ;
339
- }
340
- }
341
330
342
- if ( callback ) {
343
- callback ( ) ;
344
- }
345
- } ) ;
346
- } else if ( callback ) {
347
- callback ( ) ;
348
- }
349
- } ;
350
331
351
332
352
333
IncomingMessage . prototype . _emitData = function ( d ) {
@@ -1016,7 +997,7 @@ ServerResponse.prototype.writeHead = function(statusCode) {
1016
997
1017
998
// don't keep alive connections where the client expects 100 Continue
1018
999
// but we sent a final status; they may put extra bytes on the wire.
1019
- if ( this . _expect_continue && ! this . _sent100 ) {
1000
+ if ( this . _expect_continue && ! this . _sent100 ) {
1020
1001
this . shouldKeepAlive = false ;
1021
1002
}
1022
1003
@@ -1321,11 +1302,10 @@ function socketCloseListener() {
1321
1302
// Socket closed before we emitted 'end' below.
1322
1303
req . res . emit ( 'aborted' ) ;
1323
1304
var res = req . res ;
1324
- req . res . _emitPending ( function ( ) {
1325
- res . _emitEnd ( ) ;
1305
+ res . on ( 'end' , function ( ) {
1326
1306
res . emit ( 'close' ) ;
1327
- res = null ;
1328
1307
} ) ;
1308
+ res . _readableState . onread ( null , null ) ;
1329
1309
} else if ( ! req . res && ! req . _hadError ) {
1330
1310
// This socket error fired before we started to
1331
1311
// receive a response. The error needs to
@@ -1428,11 +1408,13 @@ function socketOnData(d, start, end) {
1428
1408
}
1429
1409
1430
1410
1411
+ // client
1431
1412
function parserOnIncomingClient ( res , shouldKeepAlive ) {
1432
1413
var parser = this ;
1433
1414
var socket = this . socket ;
1434
1415
var req = socket . _httpMessage ;
1435
1416
1417
+
1436
1418
// propogate "domain" setting...
1437
1419
if ( req . domain && ! res . domain ) {
1438
1420
debug ( 'setting "res.domain"' ) ;
@@ -1480,15 +1462,21 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
1480
1462
1481
1463
DTRACE_HTTP_CLIENT_RESPONSE ( socket , req ) ;
1482
1464
COUNTER_HTTP_CLIENT_RESPONSE ( ) ;
1483
- req . emit ( 'response' , res ) ;
1484
1465
req . res = res ;
1485
1466
res . req = req ;
1486
-
1467
+ var handled = req . emit ( 'response' , res ) ;
1487
1468
res . on ( 'end' , responseOnEnd ) ;
1488
1469
1470
+ // If the user did not listen for the 'response' event, then they
1471
+ // can't possibly read the data, so we .resume() it into the void
1472
+ // so that the socket doesn't hang there in a paused state.
1473
+ if ( ! handled )
1474
+ res . resume ( ) ;
1475
+
1489
1476
return isHeadResponse ;
1490
1477
}
1491
1478
1479
+ // client
1492
1480
function responseOnEnd ( ) {
1493
1481
var res = this ;
1494
1482
var req = res . req ;
@@ -1784,7 +1772,7 @@ function connectionListener(socket) {
1784
1772
incoming . push ( req ) ;
1785
1773
1786
1774
var res = new ServerResponse ( req ) ;
1787
- debug ( 'server response shouldKeepAlive: ' + shouldKeepAlive ) ;
1775
+
1788
1776
res . shouldKeepAlive = shouldKeepAlive ;
1789
1777
DTRACE_HTTP_SERVER_REQUEST ( req , socket ) ;
1790
1778
COUNTER_HTTP_SERVER_REQUEST ( ) ;
@@ -1806,6 +1794,12 @@ function connectionListener(socket) {
1806
1794
1807
1795
incoming . shift ( ) ;
1808
1796
1797
+ // if the user never called req.read(), and didn't pipe() or
1798
+ // .resume() or .on('data'), then we call req.resume() so that the
1799
+ // bytes will be pulled off the wire.
1800
+ if ( ! req . _consuming )
1801
+ req . resume ( ) ;
1802
+
1809
1803
res . detachSocket ( socket ) ;
1810
1804
1811
1805
if ( res . _last ) {
0 commit comments