@@ -75,7 +75,7 @@ var parsers = new FreeList('parsers', 1000, function () {
7575 parser . incoming . method = info . method ;
7676 } else {
7777 // client only
78- parser . incoming . statusCode = info . statusCode ;
78+ parser . incoming . statusCode = info . statusCode ;
7979 }
8080
8181 parser . incoming . upgrade = info . upgrade ;
@@ -178,6 +178,8 @@ var transferEncodingExpression = /Transfer-Encoding/i;
178178var closeExpression = / c l o s e / i;
179179var chunkExpression = / c h u n k / i;
180180var contentLengthExpression = / C o n t e n t - L e n g t h / i;
181+ var expectExpression = / E x p e c t / i;
182+ var continueExpression = / 1 0 0 - c o n t i n u e / i;
181183
182184
183185/* Abstract base class for ServerRequest and ClientResponse. */
@@ -302,7 +304,6 @@ sys.inherits(OutgoingMessage, events.EventEmitter);
302304exports . OutgoingMessage = OutgoingMessage ;
303305
304306// This abstract either writing directly to the socket or buffering it.
305- // Rename to _writeRaw() ?
306307OutgoingMessage . prototype . _send = function ( data , encoding ) {
307308 // This is a shameful hack to get the headers and first body chunk onto
308309 // the same packet. Future versions of Node are going to take care of
@@ -316,7 +317,10 @@ OutgoingMessage.prototype._send = function (data, encoding) {
316317 }
317318 this . _headerSent = true ;
318319 }
320+ this . _writeRaw ( data , encoding )
321+ }
319322
323+ OutgoingMessage . prototype . _writeRaw = function ( data , encoding ) {
320324 if ( this . connection . _outgoing [ 0 ] === this && this . connection . writable ) {
321325 // There might be pending data in the this.output buffer.
322326 while ( this . output . length ) {
@@ -371,6 +375,7 @@ OutgoingMessage.prototype._storeHeader = function (firstLine, headers) {
371375 var sentConnectionHeader = false ;
372376 var sentContentLengthHeader = false ;
373377 var sentTransferEncodingHeader = false ;
378+ var sentExpect = false ;
374379
375380 // firstLine in the case of request is: "GET /index.html HTTP/1.1\r\n"
376381 // in the case of response it is: "HTTP/1.1 200 OK\r\n"
@@ -396,6 +401,9 @@ OutgoingMessage.prototype._storeHeader = function (firstLine, headers) {
396401 } else if ( contentLengthExpression . test ( field ) ) {
397402 sentContentLengthHeader = true ;
398403
404+ } else if ( expectExpression . test ( field ) ) {
405+ sentExpect = true ;
406+
399407 }
400408 }
401409
@@ -451,7 +459,11 @@ OutgoingMessage.prototype._storeHeader = function (firstLine, headers) {
451459
452460 this . _header = messageHeader + CRLF ;
453461 this . _headerSent = false ;
454- // wait until the first body chunk, or close(), is sent to flush.
462+ // wait until the first body chunk, or close(), is sent to flush,
463+ // UNLESS we're sending Expect: 100-continue.
464+ if ( sentExpect ) {
465+ this . _send ( "" ) ;
466+ }
455467} ;
456468
457469
@@ -592,6 +604,10 @@ function ServerResponse (req) {
592604sys . inherits ( ServerResponse , OutgoingMessage ) ;
593605exports . ServerResponse = ServerResponse ;
594606
607+ ServerResponse . prototype . writeContinue = function ( ) {
608+ this . _writeRaw ( "HTTP/1.1 100 Continue" + CRLF + CRLF , 'ascii' ) ;
609+ this . _sent100 = true ;
610+ }
595611
596612ServerResponse . prototype . writeHead = function ( statusCode ) {
597613 var reasonPhrase , headers , headerIndex ;
@@ -613,16 +629,28 @@ ServerResponse.prototype.writeHead = function (statusCode) {
613629 var statusLine = "HTTP/1.1 " + statusCode . toString ( ) + " "
614630 + reasonPhrase + CRLF ;
615631
616- if ( statusCode === 204 || statusCode === 304 ) {
632+ if ( statusCode === 204
633+ || statusCode === 304
634+ || ( statusCode >= 100 && statusCode <= 199 )
635+ ) {
617636 // RFC 2616, 10.2.5:
618637 // The 204 response MUST NOT include a message-body, and thus is always
619638 // terminated by the first empty line after the header fields.
620639 // RFC 2616, 10.3.5:
621640 // The 304 response MUST NOT contain a message-body, and thus is always
622641 // terminated by the first empty line after the header fields.
642+ // RFC 2616, 10.1 Informational 1xx:
643+ // This class of status code indicates a provisional response,
644+ // consisting only of the Status-Line and optional headers, and is
645+ // terminated by an empty line.
623646 this . _hasBody = false ;
624647 }
625648
649+ // don't keep alive connections where the client expects 100 Continue
650+ // but we sent a final status; they may put extra bytes on the wire.
651+ if ( this . _expect_continue && ! this . _sent100 ) {
652+ this . _shouldKeepAlive = false ;
653+ }
626654
627655 this . _storeHeader ( statusLine , headers ) ;
628656} ;
@@ -843,7 +871,19 @@ function connectionListener (socket) {
843871 res . shouldKeepAlive = shouldKeepAlive ;
844872 socket . _outgoing . push ( res ) ;
845873
846- self . emit ( 'request' , req , res ) ;
874+ if ( 'expect' in req . headers
875+ && ( req . httpVersionMajor == 1 && req . httpVersionMinor == 1 )
876+ && continueExpression . test ( req . headers [ 'expect' ] ) ) {
877+ res . _expect_continue = true ;
878+ if ( self . listeners ( "checkContinue" ) . length ) {
879+ self . emit ( "checkContinue" , req , res )
880+ } else {
881+ res . writeContinue ( ) ;
882+ self . emit ( 'request' , req , res ) ;
883+ }
884+ } else {
885+ self . emit ( 'request' , req , res ) ;
886+ }
847887 return false ; // Not a HEAD response. (Not even a response!)
848888 } ;
849889}
@@ -952,6 +992,12 @@ Client.prototype._initParser = function () {
952992 // A major oversight in HTTP. Hence this nastiness.
953993 var isHeadResponse = req . method == "HEAD" ;
954994 debug ( 'isHeadResponse ' + isHeadResponse ) ;
995+
996+ if ( res . statusCode == 100 ) {
997+ // restart the parser, as this is a continue message.
998+ req . emit ( "continue" ) ;
999+ return true ;
1000+ }
9551001
9561002 if ( req . shouldKeepAlive && res . headers . connection === 'close' ) {
9571003 req . shouldKeepAlive = false ;
0 commit comments