Merge remote-tracking branch 'origin/v0.8'
[platform/upstream/nodejs.git] / lib / http.js
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 var util = require('util');
23 var net = require('net');
24 var Stream = require('stream');
25 var url = require('url');
26 var EventEmitter = require('events').EventEmitter;
27 var FreeList = require('freelist').FreeList;
28 var HTTPParser = process.binding('http_parser').HTTPParser;
29 var assert = require('assert').ok;
30 var END_OF_FILE = {};
31
32
33 var debug;
34 if (process.env.NODE_DEBUG && /http/.test(process.env.NODE_DEBUG)) {
35   debug = function(x) { console.error('HTTP: %s', x); };
36 } else {
37   debug = function() { };
38 }
39
40 // Only called in the slow case where slow means
41 // that the request headers were either fragmented
42 // across multiple TCP packets or too large to be
43 // processed in a single run. This method is also
44 // called to process trailing HTTP headers.
45 function parserOnHeaders(headers, url) {
46   // Once we exceeded headers limit - stop collecting them
47   if (this.maxHeaderPairs <= 0 ||
48       this._headers.length < this.maxHeaderPairs) {
49     this._headers = this._headers.concat(headers);
50   }
51   this._url += url;
52 }
53
54 // info.headers and info.url are set only if .onHeaders()
55 // has not been called for this request.
56 //
57 // info.url is not set for response parsers but that's not
58 // applicable here since all our parsers are request parsers.
59 function parserOnHeadersComplete(info) {
60   var parser = this;
61   var headers = info.headers;
62   var url = info.url;
63
64   if (!headers) {
65     headers = parser._headers;
66     parser._headers = [];
67   }
68
69   if (!url) {
70     url = parser._url;
71     parser._url = '';
72   }
73
74   parser.incoming = new IncomingMessage(parser.socket);
75   parser.incoming.httpVersionMajor = info.versionMajor;
76   parser.incoming.httpVersionMinor = info.versionMinor;
77   parser.incoming.httpVersion = info.versionMajor + '.' + info.versionMinor;
78   parser.incoming.url = url;
79
80   var n = headers.length;
81
82   // If parser.maxHeaderPairs <= 0 - assume that there're no limit
83   if (parser.maxHeaderPairs > 0) {
84     n = Math.min(n, parser.maxHeaderPairs);
85   }
86
87   for (var i = 0; i < n; i += 2) {
88     var k = headers[i];
89     var v = headers[i + 1];
90     parser.incoming._addHeaderLine(k, v);
91   }
92
93
94   if (info.method) {
95     // server only
96     parser.incoming.method = info.method;
97   } else {
98     // client only
99     parser.incoming.statusCode = info.statusCode;
100     // CHECKME dead code? we're always a request parser
101   }
102
103   parser.incoming.upgrade = info.upgrade;
104
105   var skipBody = false; // response to HEAD or CONNECT
106
107   if (!info.upgrade) {
108     // For upgraded connections and CONNECT method request,
109     // we'll emit this after parser.execute
110     // so that we can capture the first part of the new protocol
111     skipBody = parser.onIncoming(parser.incoming, info.shouldKeepAlive);
112   }
113
114   return skipBody;
115 }
116
117 // XXX This is a mess.
118 // TODO: http.Parser should be a Writable emits request/response events.
119 function parserOnBody(b, start, len) {
120   var parser = this;
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);
129   }
130
131   if (rs.length >= rs.highWaterMark)
132     socket.pause();
133 }
134
135 function parserOnMessageComplete() {
136   var parser = this;
137   var stream = parser.incoming;
138   var socket = stream.socket;
139
140   stream.complete = true;
141
142   // Emit any trailing headers.
143   var headers = parser._headers;
144   if (headers) {
145     for (var i = 0, n = headers.length; i < n; i += 2) {
146       var k = headers[i];
147       var v = headers[i + 1];
148       parser.incoming._addHeaderLine(k, v);
149     }
150     parser._headers = [];
151     parser._url = '';
152   }
153
154   if (!stream.upgrade)
155     // For upgraded connections, also emit this after parser.execute
156     stream._readableState.onread(null, null);
157
158   if (parser.socket.readable) {
159     // force to read the next incoming message
160     socket.resume();
161   }
162 }
163
164
165 var parsers = new FreeList('parsers', 1000, function() {
166   var parser = new HTTPParser(HTTPParser.REQUEST);
167
168   parser._headers = [];
169   parser._url = '';
170
171   // Only called in the slow case where slow means
172   // that the request headers were either fragmented
173   // across multiple TCP packets or too large to be
174   // processed in a single run. This method is also
175   // called to process trailing HTTP headers.
176   parser.onHeaders = parserOnHeaders;
177   parser.onHeadersComplete = parserOnHeadersComplete;
178   parser.onBody = parserOnBody;
179   parser.onMessageComplete = parserOnMessageComplete;
180
181   return parser;
182 });
183 exports.parsers = parsers;
184
185
186 var CRLF = '\r\n';
187 var STATUS_CODES = exports.STATUS_CODES = {
188   100 : 'Continue',
189   101 : 'Switching Protocols',
190   102 : 'Processing',                 // RFC 2518, obsoleted by RFC 4918
191   200 : 'OK',
192   201 : 'Created',
193   202 : 'Accepted',
194   203 : 'Non-Authoritative Information',
195   204 : 'No Content',
196   205 : 'Reset Content',
197   206 : 'Partial Content',
198   207 : 'Multi-Status',               // RFC 4918
199   300 : 'Multiple Choices',
200   301 : 'Moved Permanently',
201   302 : 'Moved Temporarily',
202   303 : 'See Other',
203   304 : 'Not Modified',
204   305 : 'Use Proxy',
205   307 : 'Temporary Redirect',
206   400 : 'Bad Request',
207   401 : 'Unauthorized',
208   402 : 'Payment Required',
209   403 : 'Forbidden',
210   404 : 'Not Found',
211   405 : 'Method Not Allowed',
212   406 : 'Not Acceptable',
213   407 : 'Proxy Authentication Required',
214   408 : 'Request Time-out',
215   409 : 'Conflict',
216   410 : 'Gone',
217   411 : 'Length Required',
218   412 : 'Precondition Failed',
219   413 : 'Request Entity Too Large',
220   414 : 'Request-URI Too Large',
221   415 : 'Unsupported Media Type',
222   416 : 'Requested Range Not Satisfiable',
223   417 : 'Expectation Failed',
224   418 : 'I\'m a teapot',              // RFC 2324
225   422 : 'Unprocessable Entity',       // RFC 4918
226   423 : 'Locked',                     // RFC 4918
227   424 : 'Failed Dependency',          // RFC 4918
228   425 : 'Unordered Collection',       // RFC 4918
229   426 : 'Upgrade Required',           // RFC 2817
230   428 : 'Precondition Required',      // RFC 6585
231   429 : 'Too Many Requests',          // RFC 6585
232   431 : 'Request Header Fields Too Large',// RFC 6585
233   500 : 'Internal Server Error',
234   501 : 'Not Implemented',
235   502 : 'Bad Gateway',
236   503 : 'Service Unavailable',
237   504 : 'Gateway Time-out',
238   505 : 'HTTP Version not supported',
239   506 : 'Variant Also Negotiates',    // RFC 2295
240   507 : 'Insufficient Storage',       // RFC 4918
241   509 : 'Bandwidth Limit Exceeded',
242   510 : 'Not Extended',               // RFC 2774
243   511 : 'Network Authentication Required' // RFC 6585
244 };
245
246
247 var connectionExpression = /Connection/i;
248 var transferEncodingExpression = /Transfer-Encoding/i;
249 var closeExpression = /close/i;
250 var chunkExpression = /chunk/i;
251 var contentLengthExpression = /Content-Length/i;
252 var dateExpression = /Date/i;
253 var expectExpression = /Expect/i;
254 var continueExpression = /100-continue/i;
255
256 var dateCache;
257 function utcDate() {
258   if (!dateCache) {
259     var d = new Date();
260     dateCache = d.toUTCString();
261     setTimeout(function() {
262       dateCache = undefined;
263     }, 1000 - d.getMilliseconds());
264   }
265   return dateCache;
266 }
267
268
269 /* Abstract base class for ServerRequest and ClientResponse. */
270 function IncomingMessage(socket) {
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 = [];
277
278   this.socket = socket;
279   this.connection = socket;
280
281   this.httpVersion = null;
282   this.complete = false;
283   this.headers = {};
284   this.trailers = {};
285
286   this.readable = true;
287
288   this._pendings = [];
289   this._pendingIndex = 0;
290
291   // request (server) only
292   this.url = '';
293   this.method = null;
294
295   // response (client) only
296   this.statusCode = null;
297   this.client = this.socket;
298
299   // flag for backwards compatibility grossness.
300   this._consuming = false;
301 }
302 util.inherits(IncomingMessage, Stream.Readable);
303
304
305 exports.IncomingMessage = IncomingMessage;
306
307
308 IncomingMessage.prototype.read = function(n) {
309   this._consuming = true;
310   return Stream.Readable.prototype.read.call(this, n);
311 };
312
313
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();
322 };
323
324
325 IncomingMessage.prototype.destroy = function(error) {
326   this.socket.destroy(error);
327 };
328
329
330
331
332
333 IncomingMessage.prototype._emitData = function(d) {
334   if (this._decoder) {
335     var string = this._decoder.write(d);
336     if (string.length) {
337       this.emit('data', string);
338     }
339   } else {
340     this.emit('data', d);
341   }
342 };
343
344
345 IncomingMessage.prototype._emitEnd = function() {
346   if (!this._endEmitted) {
347     if (this._decoder) {
348       var ret = this._decoder.end();
349       if (ret)
350         this.emit('data', ret);
351     }
352     this.emit('end');
353   }
354
355   this._endEmitted = true;
356 };
357
358
359 // Add the given (field, value) pair to the message
360 //
361 // Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
362 // same header with a ', ' if the header in question supports specification of
363 // multiple values this way. If not, we declare the first instance the winner
364 // and drop the second. Extended header fields (those beginning with 'x-') are
365 // always joined.
366 IncomingMessage.prototype._addHeaderLine = function(field, value) {
367   var dest = this.complete ? this.trailers : this.headers;
368
369   field = field.toLowerCase();
370   switch (field) {
371     // Array headers:
372     case 'set-cookie':
373       if (field in dest) {
374         dest[field].push(value);
375       } else {
376         dest[field] = [value];
377       }
378       break;
379
380     // Comma separate. Maybe make these arrays?
381     case 'accept':
382     case 'accept-charset':
383     case 'accept-encoding':
384     case 'accept-language':
385     case 'connection':
386     case 'cookie':
387     case 'pragma':
388     case 'link':
389     case 'www-authenticate':
390     case 'proxy-authenticate':
391     case 'sec-websocket-extensions':
392     case 'sec-websocket-protocol':
393       if (field in dest) {
394         dest[field] += ', ' + value;
395       } else {
396         dest[field] = value;
397       }
398       break;
399
400
401     default:
402       if (field.slice(0, 2) == 'x-') {
403         // except for x-
404         if (field in dest) {
405           dest[field] += ', ' + value;
406         } else {
407           dest[field] = value;
408         }
409       } else {
410         // drop duplicates
411         if (!(field in dest)) dest[field] = value;
412       }
413       break;
414   }
415 };
416
417
418 function OutgoingMessage() {
419   Stream.call(this);
420
421   this.output = [];
422   this.outputEncodings = [];
423
424   this.writable = true;
425
426   this._last = false;
427   this.chunkedEncoding = false;
428   this.shouldKeepAlive = true;
429   this.useChunkedEncodingByDefault = true;
430   this.sendDate = false;
431
432   this._hasBody = true;
433   this._trailer = '';
434
435   this.finished = false;
436 }
437 util.inherits(OutgoingMessage, Stream);
438
439
440 exports.OutgoingMessage = OutgoingMessage;
441
442
443 OutgoingMessage.prototype.destroy = function(error) {
444   this.socket.destroy(error);
445 };
446
447
448 // This abstract either writing directly to the socket or buffering it.
449 OutgoingMessage.prototype._send = function(data, encoding) {
450   // This is a shameful hack to get the headers and first body chunk onto
451   // the same packet. Future versions of Node are going to take care of
452   // this at a lower level and in a more general way.
453   if (!this._headerSent) {
454     if (typeof data === 'string') {
455       data = this._header + data;
456     } else {
457       this.output.unshift(this._header);
458       this.outputEncodings.unshift('ascii');
459     }
460     this._headerSent = true;
461   }
462   return this._writeRaw(data, encoding);
463 };
464
465
466 OutgoingMessage.prototype._writeRaw = function(data, encoding) {
467   if (data.length === 0) {
468     return true;
469   }
470
471   if (this.connection &&
472       this.connection._httpMessage === this &&
473       this.connection.writable) {
474     // There might be pending data in the this.output buffer.
475     while (this.output.length) {
476       if (!this.connection.writable) {
477         this._buffer(data, encoding);
478         return false;
479       }
480       var c = this.output.shift();
481       var e = this.outputEncodings.shift();
482       this.connection.write(c, e);
483     }
484
485     // Directly write to socket.
486     return this.connection.write(data, encoding);
487   } else {
488     this._buffer(data, encoding);
489     return false;
490   }
491 };
492
493
494 OutgoingMessage.prototype._buffer = function(data, encoding) {
495   if (data.length === 0) return;
496
497   var length = this.output.length;
498
499   if (length === 0 || typeof data != 'string') {
500     this.output.push(data);
501     this.outputEncodings.push(encoding);
502     return false;
503   }
504
505   var lastEncoding = this.outputEncodings[length - 1];
506   var lastData = this.output[length - 1];
507
508   if ((encoding && lastEncoding === encoding) ||
509       (!encoding && data.constructor === lastData.constructor)) {
510     this.output[length - 1] = lastData + data;
511     return false;
512   }
513
514   this.output.push(data);
515   this.outputEncodings.push(encoding);
516
517   return false;
518 };
519
520
521 OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
522   var sentConnectionHeader = false;
523   var sentContentLengthHeader = false;
524   var sentTransferEncodingHeader = false;
525   var sentDateHeader = false;
526   var sentExpect = false;
527
528   // firstLine in the case of request is: 'GET /index.html HTTP/1.1\r\n'
529   // in the case of response it is: 'HTTP/1.1 200 OK\r\n'
530   var messageHeader = firstLine;
531   var field, value;
532   var self = this;
533
534   function store(field, value) {
535     // Protect against response splitting. The if statement is there to
536     // minimize the performance impact in the common case.
537     if (/[\r\n]/.test(value))
538       value = value.replace(/[\r\n]+[ \t]*/g, '');
539
540     messageHeader += field + ': ' + value + CRLF;
541
542     if (connectionExpression.test(field)) {
543       sentConnectionHeader = true;
544       if (closeExpression.test(value)) {
545         self._last = true;
546       } else {
547         self.shouldKeepAlive = true;
548       }
549
550     } else if (transferEncodingExpression.test(field)) {
551       sentTransferEncodingHeader = true;
552       if (chunkExpression.test(value)) self.chunkedEncoding = true;
553
554     } else if (contentLengthExpression.test(field)) {
555       sentContentLengthHeader = true;
556     } else if (dateExpression.test(field)) {
557       sentDateHeader = true;
558     } else if (expectExpression.test(field)) {
559       sentExpect = true;
560     }
561   }
562
563   if (headers) {
564     var keys = Object.keys(headers);
565     var isArray = (Array.isArray(headers));
566     var field, value;
567
568     for (var i = 0, l = keys.length; i < l; i++) {
569       var key = keys[i];
570       if (isArray) {
571         field = headers[key][0];
572         value = headers[key][1];
573       } else {
574         field = key;
575         value = headers[key];
576       }
577
578       if (Array.isArray(value)) {
579         for (var j = 0; j < value.length; j++) {
580           store(field, value[j]);
581         }
582       } else {
583         store(field, value);
584       }
585     }
586   }
587
588   // Date header
589   if (this.sendDate == true && sentDateHeader == false) {
590     messageHeader += 'Date: ' + utcDate() + CRLF;
591   }
592
593   // keep-alive logic
594   if (sentConnectionHeader === false) {
595     var shouldSendKeepAlive = this.shouldKeepAlive &&
596         (sentContentLengthHeader ||
597          this.useChunkedEncodingByDefault ||
598          this.agent);
599     if (shouldSendKeepAlive) {
600       messageHeader += 'Connection: keep-alive\r\n';
601     } else {
602       this._last = true;
603       messageHeader += 'Connection: close\r\n';
604     }
605   }
606
607   if (sentContentLengthHeader == false && sentTransferEncodingHeader == false) {
608     if (this._hasBody) {
609       if (this.useChunkedEncodingByDefault) {
610         messageHeader += 'Transfer-Encoding: chunked\r\n';
611         this.chunkedEncoding = true;
612       } else {
613         this._last = true;
614       }
615     } else {
616       // Make sure we don't end the 0\r\n\r\n at the end of the message.
617       this.chunkedEncoding = false;
618     }
619   }
620
621   this._header = messageHeader + CRLF;
622   this._headerSent = false;
623
624   // wait until the first body chunk, or close(), is sent to flush,
625   // UNLESS we're sending Expect: 100-continue.
626   if (sentExpect) this._send('');
627 };
628
629
630 OutgoingMessage.prototype.setHeader = function(name, value) {
631   if (arguments.length < 2) {
632     throw new Error('`name` and `value` are required for setHeader().');
633   }
634
635   if (this._header) {
636     throw new Error('Can\'t set headers after they are sent.');
637   }
638
639   var key = name.toLowerCase();
640   this._headers = this._headers || {};
641   this._headerNames = this._headerNames || {};
642   this._headers[key] = value;
643   this._headerNames[key] = name;
644 };
645
646
647 OutgoingMessage.prototype.getHeader = function(name) {
648   if (arguments.length < 1) {
649     throw new Error('`name` is required for getHeader().');
650   }
651
652   if (!this._headers) return;
653
654   var key = name.toLowerCase();
655   return this._headers[key];
656 };
657
658
659 OutgoingMessage.prototype.removeHeader = function(name) {
660   if (arguments.length < 1) {
661     throw new Error('`name` is required for removeHeader().');
662   }
663
664   if (this._header) {
665     throw new Error('Can\'t remove headers after they are sent.');
666   }
667
668   if (!this._headers) return;
669
670   var key = name.toLowerCase();
671   delete this._headers[key];
672   delete this._headerNames[key];
673 };
674
675
676 OutgoingMessage.prototype._renderHeaders = function() {
677   if (this._header) {
678     throw new Error('Can\'t render headers after they are sent to the client.');
679   }
680
681   if (!this._headers) return {};
682
683   var headers = {};
684   var keys = Object.keys(this._headers);
685   for (var i = 0, l = keys.length; i < l; i++) {
686     var key = keys[i];
687     headers[this._headerNames[key]] = this._headers[key];
688   }
689   return headers;
690 };
691
692
693 Object.defineProperty(OutgoingMessage.prototype, 'headersSent', {
694   configurable: true,
695   enumerable: true,
696   get: function() { return !!this._header; }
697 });
698
699
700 OutgoingMessage.prototype.write = function(chunk, encoding) {
701   if (!this._header) {
702     this._implicitHeader();
703   }
704
705   if (!this._hasBody) {
706     debug('This type of response MUST NOT have a body. ' +
707           'Ignoring write() calls.');
708     return true;
709   }
710
711   if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk)) {
712     throw new TypeError('first argument must be a string or Buffer');
713   }
714
715   if (chunk.length === 0) return false;
716
717   var len, ret;
718   if (this.chunkedEncoding) {
719     if (typeof(chunk) === 'string') {
720       len = Buffer.byteLength(chunk, encoding);
721       chunk = len.toString(16) + CRLF + chunk + CRLF;
722       ret = this._send(chunk, encoding);
723     } else {
724       // buffer
725       len = chunk.length;
726       this._send(len.toString(16) + CRLF);
727       this._send(chunk);
728       ret = this._send(CRLF);
729     }
730   } else {
731     ret = this._send(chunk, encoding);
732   }
733
734   debug('write ret = ' + ret);
735   return ret;
736 };
737
738
739 OutgoingMessage.prototype.addTrailers = function(headers) {
740   this._trailer = '';
741   var keys = Object.keys(headers);
742   var isArray = (Array.isArray(headers));
743   var field, value;
744   for (var i = 0, l = keys.length; i < l; i++) {
745     var key = keys[i];
746     if (isArray) {
747       field = headers[key][0];
748       value = headers[key][1];
749     } else {
750       field = key;
751       value = headers[key];
752     }
753
754     this._trailer += field + ': ' + value + CRLF;
755   }
756 };
757
758
759 var zero_chunk_buf = new Buffer('\r\n0\r\n');
760 var crlf_buf = new Buffer('\r\n');
761
762
763 OutgoingMessage.prototype.end = function(data, encoding) {
764   if (this.finished) {
765     return false;
766   }
767   if (!this._header) {
768     this._implicitHeader();
769   }
770
771   if (data && !this._hasBody) {
772     debug('This type of response MUST NOT have a body. ' +
773           'Ignoring data passed to end().');
774     data = false;
775   }
776
777   var ret;
778
779   var hot = this._headerSent === false &&
780             (data && data.length > 0) &&
781             this.output.length === 0 &&
782             this.connection &&
783             this.connection.writable &&
784             this.connection._httpMessage === this;
785
786   if (hot) {
787     // Hot path. They're doing
788     //   res.writeHead();
789     //   res.end(blah);
790     // HACKY.
791
792     if (typeof data === 'string') {
793       if (this.chunkedEncoding) {
794         var l = Buffer.byteLength(data, encoding).toString(16);
795         ret = this.connection.write(this._header + l + CRLF +
796                                     data + '\r\n0\r\n' +
797                                     this._trailer + '\r\n', encoding);
798       } else {
799         ret = this.connection.write(this._header + data, encoding);
800       }
801     } else if (Buffer.isBuffer(data)) {
802       if (this.chunkedEncoding) {
803         var chunk_size = data.length.toString(16);
804
805         // Skip expensive Buffer.byteLength() calls; only ISO-8859-1 characters
806         // are allowed in HTTP headers. Therefore:
807         //
808         //   this._header.length == Buffer.byteLength(this._header.length)
809         //   this._trailer.length == Buffer.byteLength(this._trailer.length)
810         //
811         var header_len = this._header.length;
812         var chunk_size_len = chunk_size.length;
813         var data_len = data.length;
814         var trailer_len = this._trailer.length;
815
816         var len = header_len
817                 + chunk_size_len
818                 + 2   // '\r\n'.length
819                 + data_len
820                 + 5   // '\r\n0\r\n'.length
821                 + trailer_len
822                 + 2;  // '\r\n'.length
823
824         var buf = new Buffer(len);
825         var off = 0;
826
827         buf.write(this._header, off, header_len, 'ascii');
828         off += header_len;
829
830         buf.write(chunk_size, off, chunk_size_len, 'ascii');
831         off += chunk_size_len;
832
833         crlf_buf.copy(buf, off);
834         off += 2;
835
836         data.copy(buf, off);
837         off += data_len;
838
839         zero_chunk_buf.copy(buf, off);
840         off += 5;
841
842         if (trailer_len > 0) {
843           buf.write(this._trailer, off, trailer_len, 'ascii');
844           off += trailer_len;
845         }
846
847         crlf_buf.copy(buf, off);
848
849         ret = this.connection.write(buf);
850       } else {
851         var header_len = this._header.length;
852         var buf = new Buffer(header_len + data.length);
853         buf.write(this._header, 0, header_len, 'ascii');
854         data.copy(buf, header_len);
855         ret = this.connection.write(buf);
856       }
857     } else {
858       throw new TypeError('first argument must be a string or Buffer');
859     }
860     this._headerSent = true;
861
862   } else if (data) {
863     // Normal body write.
864     ret = this.write(data, encoding);
865   }
866
867   if (!hot) {
868     if (this.chunkedEncoding) {
869       ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
870     } else {
871       // Force a flush, HACK.
872       ret = this._send('');
873     }
874   }
875
876   this.finished = true;
877
878   // There is the first message on the outgoing queue, and we've sent
879   // everything to the socket.
880   debug('outgoing message end.');
881   if (this.output.length === 0 && this.connection._httpMessage === this) {
882     this._finish();
883   }
884
885   return ret;
886 };
887
888
889 OutgoingMessage.prototype._finish = function() {
890   assert(this.connection);
891   if (this instanceof ServerResponse) {
892     DTRACE_HTTP_SERVER_RESPONSE(this.connection);
893     COUNTER_HTTP_SERVER_RESPONSE();
894   } else {
895     assert(this instanceof ClientRequest);
896     DTRACE_HTTP_CLIENT_REQUEST(this, this.connection);
897     COUNTER_HTTP_CLIENT_REQUEST();
898   }
899   this.emit('finish');
900 };
901
902
903 OutgoingMessage.prototype._flush = function() {
904   // This logic is probably a bit confusing. Let me explain a bit:
905   //
906   // In both HTTP servers and clients it is possible to queue up several
907   // outgoing messages. This is easiest to imagine in the case of a client.
908   // Take the following situation:
909   //
910   //    req1 = client.request('GET', '/');
911   //    req2 = client.request('POST', '/');
912   //
913   // When the user does
914   //
915   //   req2.write('hello world\n');
916   //
917   // it's possible that the first request has not been completely flushed to
918   // the socket yet. Thus the outgoing messages need to be prepared to queue
919   // up data internally before sending it on further to the socket's queue.
920   //
921   // This function, outgoingFlush(), is called by both the Server and Client
922   // to attempt to flush any pending messages out to the socket.
923
924   if (!this.socket) return;
925
926   var ret;
927   while (this.output.length) {
928
929     if (!this.socket.writable) return; // XXX Necessary?
930
931     var data = this.output.shift();
932     var encoding = this.outputEncodings.shift();
933
934     ret = this.socket.write(data, encoding);
935   }
936
937   if (this.finished) {
938     // This is a queue to the server or client to bring in the next this.
939     this._finish();
940   } else if (ret) {
941     // This is necessary to prevent https from breaking
942     this.emit('drain');
943   }
944 };
945
946
947
948
949 function ServerResponse(req) {
950   OutgoingMessage.call(this);
951
952   if (req.method === 'HEAD') this._hasBody = false;
953
954   this.sendDate = true;
955
956   if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
957     this.useChunkedEncodingByDefault = chunkExpression.test(req.headers.te);
958     this.shouldKeepAlive = false;
959   }
960 }
961 util.inherits(ServerResponse, OutgoingMessage);
962
963
964 exports.ServerResponse = ServerResponse;
965
966 ServerResponse.prototype.statusCode = 200;
967
968 function onServerResponseClose() {
969   this._httpMessage.emit('close');
970 }
971
972 ServerResponse.prototype.assignSocket = function(socket) {
973   assert(!socket._httpMessage);
974   socket._httpMessage = this;
975   socket.on('close', onServerResponseClose);
976   this.socket = socket;
977   this.connection = socket;
978   this._flush();
979 };
980
981 ServerResponse.prototype.detachSocket = function(socket) {
982   assert(socket._httpMessage == this);
983   socket.removeListener('close', onServerResponseClose);
984   socket._httpMessage = null;
985   this.socket = this.connection = null;
986 };
987
988 ServerResponse.prototype.writeContinue = function() {
989   this._writeRaw('HTTP/1.1 100 Continue' + CRLF + CRLF, 'ascii');
990   this._sent100 = true;
991 };
992
993 ServerResponse.prototype._implicitHeader = function() {
994   this.writeHead(this.statusCode);
995 };
996
997 ServerResponse.prototype.writeHead = function(statusCode) {
998   var reasonPhrase, headers, headerIndex;
999
1000   if (typeof arguments[1] == 'string') {
1001     reasonPhrase = arguments[1];
1002     headerIndex = 2;
1003   } else {
1004     reasonPhrase = STATUS_CODES[statusCode] || 'unknown';
1005     headerIndex = 1;
1006   }
1007   this.statusCode = statusCode;
1008
1009   var obj = arguments[headerIndex];
1010
1011   if (obj && this._headers) {
1012     // Slow-case: when progressive API and header fields are passed.
1013     headers = this._renderHeaders();
1014
1015     if (Array.isArray(obj)) {
1016       // handle array case
1017       // TODO: remove when array is no longer accepted
1018       var field;
1019       for (var i = 0, len = obj.length; i < len; ++i) {
1020         field = obj[i][0];
1021         if (field in headers) {
1022           obj.push([field, headers[field]]);
1023         }
1024       }
1025       headers = obj;
1026
1027     } else {
1028       // handle object case
1029       var keys = Object.keys(obj);
1030       for (var i = 0; i < keys.length; i++) {
1031         var k = keys[i];
1032         if (k) headers[k] = obj[k];
1033       }
1034     }
1035   } else if (this._headers) {
1036     // only progressive api is used
1037     headers = this._renderHeaders();
1038   } else {
1039     // only writeHead() called
1040     headers = obj;
1041   }
1042
1043   var statusLine = 'HTTP/1.1 ' + statusCode.toString() + ' ' +
1044                    reasonPhrase + CRLF;
1045
1046   if (statusCode === 204 || statusCode === 304 ||
1047       (100 <= statusCode && statusCode <= 199)) {
1048     // RFC 2616, 10.2.5:
1049     // The 204 response MUST NOT include a message-body, and thus is always
1050     // terminated by the first empty line after the header fields.
1051     // RFC 2616, 10.3.5:
1052     // The 304 response MUST NOT contain a message-body, and thus is always
1053     // terminated by the first empty line after the header fields.
1054     // RFC 2616, 10.1 Informational 1xx:
1055     // This class of status code indicates a provisional response,
1056     // consisting only of the Status-Line and optional headers, and is
1057     // terminated by an empty line.
1058     this._hasBody = false;
1059   }
1060
1061   // don't keep alive connections where the client expects 100 Continue
1062   // but we sent a final status; they may put extra bytes on the wire.
1063   if (this._expect_continue && !this._sent100) {
1064     this.shouldKeepAlive = false;
1065   }
1066
1067   this._storeHeader(statusLine, headers);
1068 };
1069
1070 ServerResponse.prototype.writeHeader = function() {
1071   this.writeHead.apply(this, arguments);
1072 };
1073
1074
1075 // New Agent code.
1076
1077 // The largest departure from the previous implementation is that
1078 // an Agent instance holds connections for a variable number of host:ports.
1079 // Surprisingly, this is still API compatible as far as third parties are
1080 // concerned. The only code that really notices the difference is the
1081 // request object.
1082
1083 // Another departure is that all code related to HTTP parsing is in
1084 // ClientRequest.onSocket(). The Agent is now *strictly*
1085 // concerned with managing a connection pool.
1086
1087 function Agent(options) {
1088   EventEmitter.call(this);
1089
1090   var self = this;
1091   self.options = options || {};
1092   self.requests = {};
1093   self.sockets = {};
1094   self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets;
1095   self.on('free', function(socket, host, port, localAddress) {
1096     var name = host + ':' + port;
1097     if (localAddress) {
1098       name += ':' + localAddress;
1099     }
1100
1101     if (self.requests[name] && self.requests[name].length) {
1102       self.requests[name].shift().onSocket(socket);
1103       if (self.requests[name].length === 0) {
1104         // don't leak
1105         delete self.requests[name];
1106       }
1107     } else {
1108       // If there are no pending requests just destroy the
1109       // socket and it will get removed from the pool. This
1110       // gets us out of timeout issues and allows us to
1111       // default to Connection:keep-alive.
1112       socket.destroy();
1113     }
1114   });
1115   self.createConnection = net.createConnection;
1116 }
1117 util.inherits(Agent, EventEmitter);
1118 exports.Agent = Agent;
1119
1120 Agent.defaultMaxSockets = 5;
1121
1122 Agent.prototype.defaultPort = 80;
1123 Agent.prototype.addRequest = function(req, host, port, localAddress) {
1124   var name = host + ':' + port;
1125   if (localAddress) {
1126     name += ':' + localAddress;
1127   }
1128   if (!this.sockets[name]) {
1129     this.sockets[name] = [];
1130   }
1131   if (this.sockets[name].length < this.maxSockets) {
1132     // If we are under maxSockets create a new one.
1133     req.onSocket(this.createSocket(name, host, port, localAddress, req));
1134   } else {
1135     // We are over limit so we'll add it to the queue.
1136     if (!this.requests[name]) {
1137       this.requests[name] = [];
1138     }
1139     this.requests[name].push(req);
1140   }
1141 };
1142 Agent.prototype.createSocket = function(name, host, port, localAddress, req) {
1143   var self = this;
1144   var options = util._extend({}, self.options);
1145   options.port = port;
1146   options.host = host;
1147   options.localAddress = localAddress;
1148
1149   options.servername = host;
1150   if (req) {
1151     var hostHeader = req.getHeader('host');
1152     if (hostHeader) {
1153       options.servername = hostHeader.replace(/:.*$/, '');
1154     }
1155   }
1156
1157   var s = self.createConnection(options);
1158   if (!self.sockets[name]) {
1159     self.sockets[name] = [];
1160   }
1161   this.sockets[name].push(s);
1162   var onFree = function() {
1163     self.emit('free', s, host, port, localAddress);
1164   }
1165   s.on('free', onFree);
1166   var onClose = function(err) {
1167     // This is the only place where sockets get removed from the Agent.
1168     // If you want to remove a socket from the pool, just close it.
1169     // All socket errors end in a close event anyway.
1170     self.removeSocket(s, name, host, port, localAddress);
1171   }
1172   s.on('close', onClose);
1173   var onRemove = function() {
1174     // We need this function for cases like HTTP 'upgrade'
1175     // (defined by WebSockets) where we need to remove a socket from the pool
1176     //  because it'll be locked up indefinitely
1177     self.removeSocket(s, name, host, port, localAddress);
1178     s.removeListener('close', onClose);
1179     s.removeListener('free', onFree);
1180     s.removeListener('agentRemove', onRemove);
1181   }
1182   s.on('agentRemove', onRemove);
1183   return s;
1184 };
1185 Agent.prototype.removeSocket = function(s, name, host, port, localAddress) {
1186   if (this.sockets[name]) {
1187     var index = this.sockets[name].indexOf(s);
1188     if (index !== -1) {
1189       this.sockets[name].splice(index, 1);
1190       if (this.sockets[name].length === 0) {
1191         // don't leak
1192         delete this.sockets[name];
1193       }
1194     }
1195   }
1196   if (this.requests[name] && this.requests[name].length) {
1197     var req = this.requests[name][0];
1198     // If we have pending requests and a socket gets closed a new one
1199     this.createSocket(name, host, port, localAddress, req).emit('free');
1200   }
1201 };
1202
1203 var globalAgent = new Agent();
1204 exports.globalAgent = globalAgent;
1205
1206
1207 function ClientRequest(options, cb) {
1208   var self = this;
1209   OutgoingMessage.call(self);
1210
1211   self.agent = options.agent === undefined ? globalAgent : options.agent;
1212
1213   var defaultPort = options.defaultPort || 80;
1214
1215   var port = options.port || defaultPort;
1216   var host = options.hostname || options.host || 'localhost';
1217
1218   if (options.setHost === undefined) {
1219     var setHost = true;
1220   }
1221
1222   self.socketPath = options.socketPath;
1223
1224   var method = self.method = (options.method || 'GET').toUpperCase();
1225   self.path = options.path || '/';
1226   if (cb) {
1227     self.once('response', cb);
1228   }
1229
1230   if (!Array.isArray(options.headers)) {
1231     if (options.headers) {
1232       var keys = Object.keys(options.headers);
1233       for (var i = 0, l = keys.length; i < l; i++) {
1234         var key = keys[i];
1235         self.setHeader(key, options.headers[key]);
1236       }
1237     }
1238     if (host && !this.getHeader('host') && setHost) {
1239       var hostHeader = host;
1240       if (port && +port !== defaultPort) {
1241         hostHeader += ':' + port;
1242       }
1243       this.setHeader('Host', hostHeader);
1244     }
1245   }
1246
1247   if (options.auth && !this.getHeader('Authorization')) {
1248     //basic auth
1249     this.setHeader('Authorization', 'Basic ' +
1250                    new Buffer(options.auth).toString('base64'));
1251   }
1252
1253   if (method === 'GET' || method === 'HEAD' || method === 'CONNECT') {
1254     self.useChunkedEncodingByDefault = false;
1255   } else {
1256     self.useChunkedEncodingByDefault = true;
1257   }
1258
1259   if (Array.isArray(options.headers)) {
1260     self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
1261                       options.headers);
1262   } else if (self.getHeader('expect')) {
1263     self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
1264                       self._renderHeaders());
1265   }
1266   if (self.socketPath) {
1267     self._last = true;
1268     self.shouldKeepAlive = false;
1269     if (options.createConnection) {
1270       self.onSocket(options.createConnection(self.socketPath));
1271     } else {
1272       self.onSocket(net.createConnection(self.socketPath));
1273     }
1274   } else if (self.agent) {
1275     // If there is an agent we should default to Connection:keep-alive.
1276     self._last = false;
1277     self.shouldKeepAlive = true;
1278     self.agent.addRequest(self, host, port, options.localAddress);
1279   } else {
1280     // No agent, default to Connection:close.
1281     self._last = true;
1282     self.shouldKeepAlive = false;
1283     if (options.createConnection) {
1284       options.port = port;
1285       options.host = host;
1286       var conn = options.createConnection(options);
1287     } else {
1288       var conn = net.createConnection({
1289         port: port,
1290         host: host,
1291         localAddress: options.localAddress
1292       });
1293     }
1294     self.onSocket(conn);
1295   }
1296
1297   self._deferToConnect(null, null, function() {
1298     self._flush();
1299     self = null;
1300   });
1301
1302 }
1303 util.inherits(ClientRequest, OutgoingMessage);
1304
1305 exports.ClientRequest = ClientRequest;
1306
1307 ClientRequest.prototype._implicitHeader = function() {
1308   this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n',
1309                     this._renderHeaders());
1310 };
1311
1312 ClientRequest.prototype.abort = function() {
1313   if (this.socket) {
1314     // in-progress
1315     this.socket.destroy();
1316   } else {
1317     // haven't been assigned a socket yet.
1318     // this could be more efficient, it could
1319     // remove itself from the pending requests
1320     this._deferToConnect('destroy', []);
1321   }
1322 };
1323
1324
1325 function createHangUpError() {
1326   var error = new Error('socket hang up');
1327   error.code = 'ECONNRESET';
1328   return error;
1329 }
1330
1331 // Free the parser and also break any links that it
1332 // might have to any other things.
1333 // TODO: All parser data should be attached to a
1334 // single object, so that it can be easily cleaned
1335 // up by doing `parser.data = {}`, which should
1336 // be done in FreeList.free.  `parsers.free(parser)`
1337 // should be all that is needed.
1338 function freeParser(parser, req) {
1339   if (parser) {
1340     parser._headers = [];
1341     parser.onIncoming = null;
1342     if (parser.socket) {
1343       parser.socket.onend = null;
1344       parser.socket.ondata = null;
1345       parser.socket.parser = null;
1346     }
1347     parser.socket = null;
1348     parser.incoming = null;
1349     parsers.free(parser);
1350     parser = null;
1351   }
1352   if (req) {
1353     req.parser = null;
1354   }
1355 }
1356
1357
1358 function socketCloseListener() {
1359   var socket = this;
1360   var parser = socket.parser;
1361   var req = socket._httpMessage;
1362   debug('HTTP socket close');
1363   req.emit('close');
1364   if (req.res && req.res.readable) {
1365     // Socket closed before we emitted 'end' below.
1366     req.res.emit('aborted');
1367     var res = req.res;
1368     res.on('end', function() {
1369       res.emit('close');
1370     });
1371     res._readableState.onread(null, null);
1372   } else if (!req.res && !req._hadError) {
1373     // This socket error fired before we started to
1374     // receive a response. The error needs to
1375     // fire on the request.
1376     req.emit('error', createHangUpError());
1377   }
1378
1379   if (parser) {
1380     parser.finish();
1381     freeParser(parser, req);
1382   }
1383 }
1384
1385 function socketErrorListener(err) {
1386   var socket = this;
1387   var parser = socket.parser;
1388   var req = socket._httpMessage;
1389   debug('HTTP SOCKET ERROR: ' + err.message + '\n' + err.stack);
1390
1391   if (req) {
1392     req.emit('error', err);
1393     // For Safety. Some additional errors might fire later on
1394     // and we need to make sure we don't double-fire the error event.
1395     req._hadError = true;
1396   }
1397
1398   if (parser) {
1399     parser.finish();
1400     freeParser(parser, req);
1401   }
1402   socket.destroy();
1403 }
1404
1405 function socketOnEnd() {
1406   var socket = this;
1407   var req = this._httpMessage;
1408   var parser = this.parser;
1409
1410   if (!req.res) {
1411     // If we don't have a response then we know that the socket
1412     // ended prematurely and we need to emit an error on the request.
1413     req.emit('error', createHangUpError());
1414     req._hadError = true;
1415   }
1416   if (parser) {
1417     parser.finish();
1418     freeParser(parser, req);
1419   }
1420   socket.destroy();
1421 }
1422
1423 function socketOnData(d, start, end) {
1424   var socket = this;
1425   var req = this._httpMessage;
1426   var parser = this.parser;
1427
1428   var ret = parser.execute(d, start, end - start);
1429   if (ret instanceof Error) {
1430     debug('parse error');
1431     freeParser(parser, req);
1432     socket.destroy();
1433     req.emit('error', ret);
1434     req._hadError = true;
1435   } else if (parser.incoming && parser.incoming.upgrade) {
1436     // Upgrade or CONNECT
1437     var bytesParsed = ret;
1438     var res = parser.incoming;
1439     req.res = res;
1440
1441     socket.ondata = null;
1442     socket.onend = null;
1443     parser.finish();
1444
1445     // This is start + byteParsed
1446     var bodyHead = d.slice(start + bytesParsed, end);
1447
1448     var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
1449     if (req.listeners(eventName).length) {
1450       req.upgradeOrConnect = true;
1451
1452       // detach the socket
1453       socket.emit('agentRemove');
1454       socket.removeListener('close', socketCloseListener);
1455       socket.removeListener('error', socketErrorListener);
1456
1457       req.emit(eventName, res, socket, bodyHead);
1458       req.emit('close');
1459     } else {
1460       // Got Upgrade header or CONNECT method, but have no handler.
1461       socket.destroy();
1462     }
1463     freeParser(parser, req);
1464   } else if (parser.incoming && parser.incoming.complete &&
1465              // When the status code is 100 (Continue), the server will
1466              // send a final response after this client sends a request
1467              // body. So, we must not free the parser.
1468              parser.incoming.statusCode !== 100) {
1469     freeParser(parser, req);
1470   }
1471 }
1472
1473
1474 // client
1475 function parserOnIncomingClient(res, shouldKeepAlive) {
1476   var parser = this;
1477   var socket = this.socket;
1478   var req = socket._httpMessage;
1479
1480
1481   // propogate "domain" setting...
1482   if (req.domain && !res.domain) {
1483     debug('setting "res.domain"');
1484     res.domain = req.domain;
1485   }
1486
1487   debug('AGENT incoming response!');
1488
1489   if (req.res) {
1490     // We already have a response object, this means the server
1491     // sent a double response.
1492     socket.destroy();
1493     return;
1494   }
1495   req.res = res;
1496
1497   // Responses to CONNECT request is handled as Upgrade.
1498   if (req.method === 'CONNECT') {
1499     res.upgrade = true;
1500     return true; // skip body
1501   }
1502
1503   // Responses to HEAD requests are crazy.
1504   // HEAD responses aren't allowed to have an entity-body
1505   // but *can* have a content-length which actually corresponds
1506   // to the content-length of the entity-body had the request
1507   // been a GET.
1508   var isHeadResponse = req.method == 'HEAD';
1509   debug('AGENT isHeadResponse ' + isHeadResponse);
1510
1511   if (res.statusCode == 100) {
1512     // restart the parser, as this is a continue message.
1513     delete req.res; // Clear res so that we don't hit double-responses.
1514     req.emit('continue');
1515     return true;
1516   }
1517
1518   if (req.shouldKeepAlive && !shouldKeepAlive && !req.upgradeOrConnect) {
1519     // Server MUST respond with Connection:keep-alive for us to enable it.
1520     // If we've been upgraded (via WebSockets) we also shouldn't try to
1521     // keep the connection open.
1522     req.shouldKeepAlive = false;
1523   }
1524
1525
1526   DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
1527   COUNTER_HTTP_CLIENT_RESPONSE();
1528   req.res = res;
1529   res.req = req;
1530   var handled = req.emit('response', res);
1531   res.on('end', responseOnEnd);
1532
1533   // If the user did not listen for the 'response' event, then they
1534   // can't possibly read the data, so we .resume() it into the void
1535   // so that the socket doesn't hang there in a paused state.
1536   if (!handled)
1537     res.resume();
1538
1539   return isHeadResponse;
1540 }
1541
1542 // client
1543 function responseOnEnd() {
1544   var res = this;
1545   var req = res.req;
1546   var socket = req.socket;
1547
1548   if (!req.shouldKeepAlive) {
1549     if (socket.writable) {
1550       debug('AGENT socket.destroySoon()');
1551       socket.destroySoon();
1552     }
1553     assert(!socket.writable);
1554   } else {
1555     debug('AGENT socket keep-alive');
1556     if (req.timeoutCb) {
1557       socket.setTimeout(0, req.timeoutCb);
1558       req.timeoutCb = null;
1559     }
1560     socket.removeListener('close', socketCloseListener);
1561     socket.removeListener('error', socketErrorListener);
1562     socket.emit('free');
1563   }
1564 }
1565
1566 ClientRequest.prototype.onSocket = function(socket) {
1567   var req = this;
1568
1569   process.nextTick(function() {
1570     var parser = parsers.alloc();
1571     req.socket = socket;
1572     req.connection = socket;
1573     parser.reinitialize(HTTPParser.RESPONSE);
1574     parser.socket = socket;
1575     parser.incoming = null;
1576     req.parser = parser;
1577
1578     socket.parser = parser;
1579     socket._httpMessage = req;
1580
1581     // Setup "drain" propogation.
1582     httpSocketSetup(socket);
1583
1584     // Propagate headers limit from request object to parser
1585     if (typeof req.maxHeadersCount === 'number') {
1586       parser.maxHeaderPairs = req.maxHeadersCount << 1;
1587     } else {
1588       // Set default value because parser may be reused from FreeList
1589       parser.maxHeaderPairs = 2000;
1590     }
1591
1592     socket.on('error', socketErrorListener);
1593     socket.ondata = socketOnData;
1594     socket.onend = socketOnEnd;
1595     socket.on('close', socketCloseListener);
1596     parser.onIncoming = parserOnIncomingClient;
1597     req.emit('socket', socket);
1598   });
1599
1600 };
1601
1602 ClientRequest.prototype._deferToConnect = function(method, arguments_, cb) {
1603   // This function is for calls that need to happen once the socket is
1604   // connected and writable. It's an important promisy thing for all the socket
1605   // calls that happen either now (when a socket is assigned) or
1606   // in the future (when a socket gets assigned out of the pool and is
1607   // eventually writable).
1608   var self = this;
1609   var onSocket = function() {
1610     if (self.socket.writable) {
1611       if (method) {
1612         self.socket[method].apply(self.socket, arguments_);
1613       }
1614       if (cb) { cb(); }
1615     } else {
1616       self.socket.once('connect', function() {
1617         if (method) {
1618           self.socket[method].apply(self.socket, arguments_);
1619         }
1620         if (cb) { cb(); }
1621       });
1622     }
1623   }
1624   if (!self.socket) {
1625     self.once('socket', onSocket);
1626   } else {
1627     onSocket();
1628   }
1629 };
1630
1631 ClientRequest.prototype.setTimeout = function(msecs, callback) {
1632   if (callback) this.once('timeout', callback);
1633
1634   var self = this;
1635   function emitTimeout() {
1636     self.emit('timeout');
1637   }
1638
1639   if (this.socket && this.socket.writable) {
1640     if (this.timeoutCb)
1641       this.socket.setTimeout(0, this.timeoutCb);
1642     this.timeoutCb = emitTimeout;
1643     this.socket.setTimeout(msecs, emitTimeout);
1644     return;
1645   }
1646
1647   if (this.socket) {
1648     this.socket.once('connect', function() {
1649       this.setTimeout(msecs, emitTimeout);
1650     });
1651     return;
1652   }
1653
1654   this.once('socket', function(sock) {
1655     this.setTimeout(msecs, emitTimeout);
1656   });
1657 };
1658
1659 ClientRequest.prototype.setNoDelay = function() {
1660   this._deferToConnect('setNoDelay', arguments);
1661 };
1662 ClientRequest.prototype.setSocketKeepAlive = function() {
1663   this._deferToConnect('setKeepAlive', arguments);
1664 };
1665
1666 ClientRequest.prototype.clearTimeout = function(cb) {
1667   this.setTimeout(0, cb);
1668 };
1669
1670 exports.request = function(options, cb) {
1671   if (typeof options === 'string') {
1672     options = url.parse(options);
1673   }
1674
1675   if (options.protocol && options.protocol !== 'http:') {
1676     throw new Error('Protocol:' + options.protocol + ' not supported.');
1677   }
1678
1679   return new ClientRequest(options, cb);
1680 };
1681
1682 exports.get = function(options, cb) {
1683   var req = exports.request(options, cb);
1684   req.end();
1685   return req;
1686 };
1687
1688
1689 function ondrain() {
1690   if (this._httpMessage) this._httpMessage.emit('drain');
1691 }
1692
1693
1694 function httpSocketSetup(socket) {
1695   socket.removeListener('drain', ondrain);
1696   socket.on('drain', ondrain);
1697 }
1698
1699
1700 function Server(requestListener) {
1701   if (!(this instanceof Server)) return new Server(requestListener);
1702   net.Server.call(this, { allowHalfOpen: true });
1703
1704   if (requestListener) {
1705     this.addListener('request', requestListener);
1706   }
1707
1708   // Similar option to this. Too lazy to write my own docs.
1709   // http://www.squid-cache.org/Doc/config/half_closed_clients/
1710   // http://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
1711   this.httpAllowHalfOpen = false;
1712
1713   this.addListener('connection', connectionListener);
1714
1715   this.addListener('clientError', function(err, conn) {
1716     conn.destroy(err);
1717   });
1718 }
1719 util.inherits(Server, net.Server);
1720
1721
1722 exports.Server = Server;
1723
1724
1725 exports.createServer = function(requestListener) {
1726   return new Server(requestListener);
1727 };
1728
1729
1730 function connectionListener(socket) {
1731   var self = this;
1732   var outgoing = [];
1733   var incoming = [];
1734
1735   function abortIncoming() {
1736     while (incoming.length) {
1737       var req = incoming.shift();
1738       req.emit('aborted');
1739       req.emit('close');
1740     }
1741     // abort socket._httpMessage ?
1742   }
1743
1744   function serverSocketCloseListener() {
1745     debug('server socket close');
1746     // mark this parser as reusable
1747     freeParser(parser);
1748
1749     abortIncoming();
1750   }
1751
1752   debug('SERVER new http connection');
1753
1754   httpSocketSetup(socket);
1755
1756   socket.setTimeout(2 * 60 * 1000); // 2 minute timeout
1757   socket.once('timeout', function() {
1758     socket.destroy();
1759   });
1760
1761   var parser = parsers.alloc();
1762   parser.reinitialize(HTTPParser.REQUEST);
1763   parser.socket = socket;
1764   socket.parser = parser;
1765   parser.incoming = null;
1766
1767   // Propagate headers limit from server instance to parser
1768   if (typeof this.maxHeadersCount === 'number') {
1769     parser.maxHeaderPairs = this.maxHeadersCount << 1;
1770   } else {
1771     // Set default value because parser may be reused from FreeList
1772     parser.maxHeaderPairs = 2000;
1773   }
1774
1775   socket.addListener('error', function(e) {
1776     self.emit('clientError', e, this);
1777   });
1778
1779   socket.ondata = function(d, start, end) {
1780     var ret = parser.execute(d, start, end - start);
1781     if (ret instanceof Error) {
1782       debug('parse error');
1783       socket.destroy(ret);
1784     } else if (parser.incoming && parser.incoming.upgrade) {
1785       // Upgrade or CONNECT
1786       var bytesParsed = ret;
1787       var req = parser.incoming;
1788
1789       socket.ondata = null;
1790       socket.onend = null;
1791       socket.removeListener('close', serverSocketCloseListener);
1792       parser.finish();
1793       freeParser(parser, req);
1794
1795       // This is start + byteParsed
1796       var bodyHead = d.slice(start + bytesParsed, end);
1797
1798       var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
1799       if (self.listeners(eventName).length) {
1800         self.emit(eventName, req, req.socket, bodyHead);
1801       } else {
1802         // Got upgrade header or CONNECT method, but have no handler.
1803         socket.destroy();
1804       }
1805     }
1806   };
1807
1808   socket.onend = function() {
1809     var ret = parser.finish();
1810
1811     if (ret instanceof Error) {
1812       debug('parse error');
1813       socket.destroy(ret);
1814       return;
1815     }
1816
1817     if (!self.httpAllowHalfOpen) {
1818       abortIncoming();
1819       if (socket.writable) socket.end();
1820     } else if (outgoing.length) {
1821       outgoing[outgoing.length - 1]._last = true;
1822     } else if (socket._httpMessage) {
1823       socket._httpMessage._last = true;
1824     } else {
1825       if (socket.writable) socket.end();
1826     }
1827   };
1828
1829   socket.addListener('close', serverSocketCloseListener);
1830
1831   // The following callback is issued after the headers have been read on a
1832   // new message. In this callback we setup the response object and pass it
1833   // to the user.
1834   parser.onIncoming = function(req, shouldKeepAlive) {
1835     incoming.push(req);
1836
1837     var res = new ServerResponse(req);
1838
1839     res.shouldKeepAlive = shouldKeepAlive;
1840     DTRACE_HTTP_SERVER_REQUEST(req, socket);
1841     COUNTER_HTTP_SERVER_REQUEST();
1842
1843     if (socket._httpMessage) {
1844       // There are already pending outgoing res, append.
1845       outgoing.push(res);
1846     } else {
1847       res.assignSocket(socket);
1848     }
1849
1850     // When we're finished writing the response, check if this is the last
1851     // respose, if so destroy the socket.
1852     res.on('finish', function() {
1853       // Usually the first incoming element should be our request.  it may
1854       // be that in the case abortIncoming() was called that the incoming
1855       // array will be empty.
1856       assert(incoming.length == 0 || incoming[0] === req);
1857
1858       incoming.shift();
1859
1860       // if the user never called req.read(), and didn't pipe() or
1861       // .resume() or .on('data'), then we call req.resume() so that the
1862       // bytes will be pulled off the wire.
1863       if (!req._consuming)
1864         req.resume();
1865
1866       res.detachSocket(socket);
1867
1868       if (res._last) {
1869         socket.destroySoon();
1870       } else {
1871         // start sending the next message
1872         var m = outgoing.shift();
1873         if (m) {
1874           m.assignSocket(socket);
1875         }
1876       }
1877     });
1878
1879     if ('expect' in req.headers &&
1880         (req.httpVersionMajor == 1 && req.httpVersionMinor == 1) &&
1881         continueExpression.test(req.headers['expect'])) {
1882       res._expect_continue = true;
1883       if (self.listeners('checkContinue').length) {
1884         self.emit('checkContinue', req, res);
1885       } else {
1886         res.writeContinue();
1887         self.emit('request', req, res);
1888       }
1889     } else {
1890       self.emit('request', req, res);
1891     }
1892     return false; // Not a HEAD response. (Not even a response!)
1893   };
1894 }
1895 exports._connectionListener = connectionListener;
1896
1897 // Legacy Interface
1898
1899 function Client(port, host) {
1900   if (!(this instanceof Client)) return new Client(port, host);
1901   EventEmitter.call(this);
1902
1903   host = host || 'localhost';
1904   port = port || 80;
1905   this.host = host;
1906   this.port = port;
1907   this.agent = new Agent({ host: host, port: port, maxSockets: 1 });
1908 }
1909 util.inherits(Client, EventEmitter);
1910 Client.prototype.request = function(method, path, headers) {
1911   var self = this;
1912   var options = {};
1913   options.host = self.host;
1914   options.port = self.port;
1915   if (method[0] === '/') {
1916     headers = path;
1917     path = method;
1918     method = 'GET';
1919   }
1920   options.method = method;
1921   options.path = path;
1922   options.headers = headers;
1923   options.agent = self.agent;
1924   var c = new ClientRequest(options);
1925   c.on('error', function(e) {
1926     self.emit('error', e);
1927   });
1928   // The old Client interface emitted 'end' on socket end.
1929   // This doesn't map to how we want things to operate in the future
1930   // but it will get removed when we remove this legacy interface.
1931   c.on('socket', function(s) {
1932     s.on('end', function() {
1933       if (self._decoder) {
1934         var ret = self._decoder.end();
1935         if (ret)
1936           self.emit('data', ret);
1937       }
1938       self.emit('end');
1939     });
1940   });
1941   return c;
1942 };
1943
1944 exports.Client = util.deprecate(Client,
1945     'http.Client will be removed soon. Do not use it.');
1946
1947 exports.createClient = util.deprecate(function(port, host) {
1948   return new Client(port, host);
1949 }, 'http.createClient is deprecated. Use `http.request` instead.');