PageRenderTime 63ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/node_modules/commonjs-everywhere/node/lib/http.js

https://github.com/flochtililoch/automate
JavaScript | 2115 lines | 1457 code | 340 blank | 318 comment | 357 complexity | c0fc369423153be411271a3c02227ea5 MD5 | raw file
Possible License(s): Apache-2.0, 0BSD, GPL-2.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause, BSD-2-Clause, WTFPL, MIT

Large files files are truncated, but you can click here to view the full file

  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. var util = require('util');
  22. var net = require('net');
  23. var Stream = require('stream');
  24. var timers = require('timers');
  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 debug;
  31. if (process.env.NODE_DEBUG && /http/.test(process.env.NODE_DEBUG)) {
  32. debug = function(x) { console.error('HTTP: %s', x); };
  33. } else {
  34. debug = function() { };
  35. }
  36. function readStart(socket) {
  37. if (!socket || !socket._handle || !socket._handle.readStart) return;
  38. socket._handle.readStart();
  39. }
  40. function readStop(socket) {
  41. if (!socket || !socket._handle || !socket._handle.readStop) return;
  42. socket._handle.readStop();
  43. }
  44. // Only called in the slow case where slow means
  45. // that the request headers were either fragmented
  46. // across multiple TCP packets or too large to be
  47. // processed in a single run. This method is also
  48. // called to process trailing HTTP headers.
  49. function parserOnHeaders(headers, url) {
  50. // Once we exceeded headers limit - stop collecting them
  51. if (this.maxHeaderPairs <= 0 ||
  52. this._headers.length < this.maxHeaderPairs) {
  53. this._headers = this._headers.concat(headers);
  54. }
  55. this._url += url;
  56. }
  57. // info.headers and info.url are set only if .onHeaders()
  58. // has not been called for this request.
  59. //
  60. // info.url is not set for response parsers but that's not
  61. // applicable here since all our parsers are request parsers.
  62. function parserOnHeadersComplete(info) {
  63. var parser = this;
  64. var headers = info.headers;
  65. var url = info.url;
  66. if (!headers) {
  67. headers = parser._headers;
  68. parser._headers = [];
  69. }
  70. if (!url) {
  71. url = parser._url;
  72. parser._url = '';
  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. var n = headers.length;
  80. // If parser.maxHeaderPairs <= 0 - assume that there're no limit
  81. if (parser.maxHeaderPairs > 0) {
  82. n = Math.min(n, parser.maxHeaderPairs);
  83. }
  84. for (var i = 0; i < n; i += 2) {
  85. var k = headers[i];
  86. var v = headers[i + 1];
  87. parser.incoming._addHeaderLine(k, v);
  88. }
  89. if (info.method) {
  90. // server only
  91. parser.incoming.method = info.method;
  92. } else {
  93. // client only
  94. parser.incoming.statusCode = info.statusCode;
  95. // CHECKME dead code? we're always a request parser
  96. }
  97. parser.incoming.upgrade = info.upgrade;
  98. var skipBody = false; // response to HEAD or CONNECT
  99. if (!info.upgrade) {
  100. // For upgraded connections and CONNECT method request,
  101. // we'll emit this after parser.execute
  102. // so that we can capture the first part of the new protocol
  103. skipBody = parser.onIncoming(parser.incoming, info.shouldKeepAlive);
  104. }
  105. return skipBody;
  106. }
  107. // XXX This is a mess.
  108. // TODO: http.Parser should be a Writable emits request/response events.
  109. function parserOnBody(b, start, len) {
  110. var parser = this;
  111. var stream = parser.incoming;
  112. // if the stream has already been removed, then drop it.
  113. if (!stream)
  114. return;
  115. var socket = stream.socket;
  116. // pretend this was the result of a stream._read call.
  117. if (len > 0 && !stream._dumped) {
  118. var slice = b.slice(start, start + len);
  119. var ret = stream.push(slice);
  120. if (!ret)
  121. readStop(socket);
  122. }
  123. }
  124. function parserOnMessageComplete() {
  125. var parser = this;
  126. var stream = parser.incoming;
  127. if (stream) {
  128. stream.complete = true;
  129. // Emit any trailing headers.
  130. var headers = parser._headers;
  131. if (headers) {
  132. for (var i = 0, n = headers.length; i < n; i += 2) {
  133. var k = headers[i];
  134. var v = headers[i + 1];
  135. parser.incoming._addHeaderLine(k, v);
  136. }
  137. parser._headers = [];
  138. parser._url = '';
  139. }
  140. if (!stream.upgrade)
  141. // For upgraded connections, also emit this after parser.execute
  142. stream.push(null);
  143. }
  144. if (stream && !parser.incoming._pendings.length) {
  145. // For emit end event
  146. stream.push(null);
  147. }
  148. if (parser.socket.readable) {
  149. // force to read the next incoming message
  150. readStart(parser.socket);
  151. }
  152. }
  153. var parsers = new FreeList('parsers', 1000, function() {
  154. var parser = new HTTPParser(HTTPParser.REQUEST);
  155. parser._headers = [];
  156. parser._url = '';
  157. // Only called in the slow case where slow means
  158. // that the request headers were either fragmented
  159. // across multiple TCP packets or too large to be
  160. // processed in a single run. This method is also
  161. // called to process trailing HTTP headers.
  162. parser.onHeaders = parserOnHeaders;
  163. parser.onHeadersComplete = parserOnHeadersComplete;
  164. parser.onBody = parserOnBody;
  165. parser.onMessageComplete = parserOnMessageComplete;
  166. return parser;
  167. });
  168. exports.parsers = parsers;
  169. var CRLF = '\r\n';
  170. var STATUS_CODES = exports.STATUS_CODES = {
  171. 100 : 'Continue',
  172. 101 : 'Switching Protocols',
  173. 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918
  174. 200 : 'OK',
  175. 201 : 'Created',
  176. 202 : 'Accepted',
  177. 203 : 'Non-Authoritative Information',
  178. 204 : 'No Content',
  179. 205 : 'Reset Content',
  180. 206 : 'Partial Content',
  181. 207 : 'Multi-Status', // RFC 4918
  182. 300 : 'Multiple Choices',
  183. 301 : 'Moved Permanently',
  184. 302 : 'Moved Temporarily',
  185. 303 : 'See Other',
  186. 304 : 'Not Modified',
  187. 305 : 'Use Proxy',
  188. 307 : 'Temporary Redirect',
  189. 400 : 'Bad Request',
  190. 401 : 'Unauthorized',
  191. 402 : 'Payment Required',
  192. 403 : 'Forbidden',
  193. 404 : 'Not Found',
  194. 405 : 'Method Not Allowed',
  195. 406 : 'Not Acceptable',
  196. 407 : 'Proxy Authentication Required',
  197. 408 : 'Request Time-out',
  198. 409 : 'Conflict',
  199. 410 : 'Gone',
  200. 411 : 'Length Required',
  201. 412 : 'Precondition Failed',
  202. 413 : 'Request Entity Too Large',
  203. 414 : 'Request-URI Too Large',
  204. 415 : 'Unsupported Media Type',
  205. 416 : 'Requested Range Not Satisfiable',
  206. 417 : 'Expectation Failed',
  207. 418 : 'I\'m a teapot', // RFC 2324
  208. 422 : 'Unprocessable Entity', // RFC 4918
  209. 423 : 'Locked', // RFC 4918
  210. 424 : 'Failed Dependency', // RFC 4918
  211. 425 : 'Unordered Collection', // RFC 4918
  212. 426 : 'Upgrade Required', // RFC 2817
  213. 428 : 'Precondition Required', // RFC 6585
  214. 429 : 'Too Many Requests', // RFC 6585
  215. 431 : 'Request Header Fields Too Large',// RFC 6585
  216. 500 : 'Internal Server Error',
  217. 501 : 'Not Implemented',
  218. 502 : 'Bad Gateway',
  219. 503 : 'Service Unavailable',
  220. 504 : 'Gateway Time-out',
  221. 505 : 'HTTP Version Not Supported',
  222. 506 : 'Variant Also Negotiates', // RFC 2295
  223. 507 : 'Insufficient Storage', // RFC 4918
  224. 509 : 'Bandwidth Limit Exceeded',
  225. 510 : 'Not Extended', // RFC 2774
  226. 511 : 'Network Authentication Required' // RFC 6585
  227. };
  228. var connectionExpression = /Connection/i;
  229. var transferEncodingExpression = /Transfer-Encoding/i;
  230. var closeExpression = /close/i;
  231. var chunkExpression = /chunk/i;
  232. var contentLengthExpression = /Content-Length/i;
  233. var dateExpression = /Date/i;
  234. var expectExpression = /Expect/i;
  235. var continueExpression = /100-continue/i;
  236. var dateCache;
  237. function utcDate() {
  238. if (!dateCache) {
  239. var d = new Date();
  240. dateCache = d.toUTCString();
  241. timers.enroll(utcDate, 1000 - d.getMilliseconds());
  242. timers._unrefActive(utcDate);
  243. }
  244. return dateCache;
  245. }
  246. utcDate._onTimeout = function() {
  247. dateCache = undefined;
  248. };
  249. /* Abstract base class for ServerRequest and ClientResponse. */
  250. function IncomingMessage(socket) {
  251. Stream.Readable.call(this);
  252. // XXX This implementation is kind of all over the place
  253. // When the parser emits body chunks, they go in this list.
  254. // _read() pulls them out, and when it finds EOF, it ends.
  255. this.socket = socket;
  256. this.connection = socket;
  257. this.httpVersion = null;
  258. this.complete = false;
  259. this.headers = {};
  260. this.trailers = {};
  261. this.readable = true;
  262. this._pendings = [];
  263. this._pendingIndex = 0;
  264. // request (server) only
  265. this.url = '';
  266. this.method = null;
  267. // response (client) only
  268. this.statusCode = null;
  269. this.client = this.socket;
  270. // flag for backwards compatibility grossness.
  271. this._consuming = false;
  272. // flag for when we decide that this message cannot possibly be
  273. // read by the user, so there's no point continuing to handle it.
  274. this._dumped = false;
  275. }
  276. util.inherits(IncomingMessage, Stream.Readable);
  277. exports.IncomingMessage = IncomingMessage;
  278. IncomingMessage.prototype.setTimeout = function(msecs, callback) {
  279. if (callback)
  280. this.on('timeout', callback);
  281. this.socket.setTimeout(msecs);
  282. };
  283. IncomingMessage.prototype.read = function(n) {
  284. this._consuming = true;
  285. this.read = Stream.Readable.prototype.read;
  286. return this.read(n);
  287. };
  288. IncomingMessage.prototype._read = function(n) {
  289. // We actually do almost nothing here, because the parserOnBody
  290. // function fills up our internal buffer directly. However, we
  291. // do need to unpause the underlying socket so that it flows.
  292. if (!this.socket.readable)
  293. this.push(null);
  294. else
  295. readStart(this.socket);
  296. };
  297. // It's possible that the socket will be destroyed, and removed from
  298. // any messages, before ever calling this. In that case, just skip
  299. // it, since something else is destroying this connection anyway.
  300. IncomingMessage.prototype.destroy = function(error) {
  301. if (this.socket)
  302. this.socket.destroy(error);
  303. };
  304. // Add the given (field, value) pair to the message
  305. //
  306. // Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
  307. // same header with a ', ' if the header in question supports specification of
  308. // multiple values this way. If not, we declare the first instance the winner
  309. // and drop the second. Extended header fields (those beginning with 'x-') are
  310. // always joined.
  311. IncomingMessage.prototype._addHeaderLine = function(field, value) {
  312. var dest = this.complete ? this.trailers : this.headers;
  313. field = field.toLowerCase();
  314. switch (field) {
  315. // Array headers:
  316. case 'set-cookie':
  317. if (dest[field] !== undefined) {
  318. dest[field].push(value);
  319. } else {
  320. dest[field] = [value];
  321. }
  322. break;
  323. // Comma separate. Maybe make these arrays?
  324. case 'accept':
  325. case 'accept-charset':
  326. case 'accept-encoding':
  327. case 'accept-language':
  328. case 'connection':
  329. case 'cookie':
  330. case 'pragma':
  331. case 'link':
  332. case 'www-authenticate':
  333. case 'proxy-authenticate':
  334. case 'sec-websocket-extensions':
  335. case 'sec-websocket-protocol':
  336. if (dest[field] !== undefined) {
  337. dest[field] += ', ' + value;
  338. } else {
  339. dest[field] = value;
  340. }
  341. break;
  342. default:
  343. if (field.slice(0, 2) == 'x-') {
  344. // except for x-
  345. if (dest[field] !== undefined) {
  346. dest[field] += ', ' + value;
  347. } else {
  348. dest[field] = value;
  349. }
  350. } else {
  351. // drop duplicates
  352. if (dest[field] === undefined) dest[field] = value;
  353. }
  354. break;
  355. }
  356. };
  357. // Call this instead of resume() if we want to just
  358. // dump all the data to /dev/null
  359. IncomingMessage.prototype._dump = function() {
  360. if (!this._dumped) {
  361. this._dumped = true;
  362. if (this.socket.parser) this.socket.parser.incoming = null;
  363. this.push(null);
  364. readStart(this.socket);
  365. this.read();
  366. }
  367. };
  368. function OutgoingMessage() {
  369. Stream.call(this);
  370. this.output = [];
  371. this.outputEncodings = [];
  372. this.writable = true;
  373. this._last = false;
  374. this.chunkedEncoding = false;
  375. this.shouldKeepAlive = true;
  376. this.useChunkedEncodingByDefault = true;
  377. this.sendDate = false;
  378. this._hasBody = true;
  379. this._trailer = '';
  380. this.finished = false;
  381. this._hangupClose = false;
  382. this.socket = null;
  383. this.connection = null;
  384. }
  385. util.inherits(OutgoingMessage, Stream);
  386. exports.OutgoingMessage = OutgoingMessage;
  387. OutgoingMessage.prototype.setTimeout = function(msecs, callback) {
  388. if (callback)
  389. this.on('timeout', callback);
  390. if (!this.socket) {
  391. this.once('socket', function(socket) {
  392. socket.setTimeout(msecs);
  393. });
  394. } else
  395. this.socket.setTimeout(msecs);
  396. };
  397. // It's possible that the socket will be destroyed, and removed from
  398. // any messages, before ever calling this. In that case, just skip
  399. // it, since something else is destroying this connection anyway.
  400. OutgoingMessage.prototype.destroy = function(error) {
  401. if (this.socket)
  402. this.socket.destroy(error);
  403. else
  404. this.once('socket', function(socket) {
  405. socket.destroy(error);
  406. });
  407. };
  408. // This abstract either writing directly to the socket or buffering it.
  409. OutgoingMessage.prototype._send = function(data, encoding) {
  410. // This is a shameful hack to get the headers and first body chunk onto
  411. // the same packet. Future versions of Node are going to take care of
  412. // this at a lower level and in a more general way.
  413. if (!this._headerSent) {
  414. if (typeof data === 'string') {
  415. data = this._header + data;
  416. } else {
  417. this.output.unshift(this._header);
  418. this.outputEncodings.unshift('ascii');
  419. }
  420. this._headerSent = true;
  421. }
  422. return this._writeRaw(data, encoding);
  423. };
  424. OutgoingMessage.prototype._writeRaw = function(data, encoding) {
  425. if (data.length === 0) {
  426. return true;
  427. }
  428. if (this.connection &&
  429. this.connection._httpMessage === this &&
  430. this.connection.writable &&
  431. !this.connection.destroyed) {
  432. // There might be pending data in the this.output buffer.
  433. while (this.output.length) {
  434. if (!this.connection.writable) {
  435. this._buffer(data, encoding);
  436. return false;
  437. }
  438. var c = this.output.shift();
  439. var e = this.outputEncodings.shift();
  440. this.connection.write(c, e);
  441. }
  442. // Directly write to socket.
  443. return this.connection.write(data, encoding);
  444. } else if (this.connection && this.connection.destroyed) {
  445. // The socket was destroyed. If we're still trying to write to it,
  446. // then we haven't gotten the 'close' event yet.
  447. return false;
  448. } else {
  449. // buffer, as long as we're not destroyed.
  450. this._buffer(data, encoding);
  451. return false;
  452. }
  453. };
  454. OutgoingMessage.prototype._buffer = function(data, encoding) {
  455. if (data.length === 0) return;
  456. var length = this.output.length;
  457. if (length === 0 || typeof data != 'string') {
  458. this.output.push(data);
  459. this.outputEncodings.push(encoding);
  460. return false;
  461. }
  462. var lastEncoding = this.outputEncodings[length - 1];
  463. var lastData = this.output[length - 1];
  464. if ((encoding && lastEncoding === encoding) ||
  465. (!encoding && data.constructor === lastData.constructor)) {
  466. this.output[length - 1] = lastData + data;
  467. return false;
  468. }
  469. this.output.push(data);
  470. this.outputEncodings.push(encoding);
  471. return false;
  472. };
  473. OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
  474. // firstLine in the case of request is: 'GET /index.html HTTP/1.1\r\n'
  475. // in the case of response it is: 'HTTP/1.1 200 OK\r\n'
  476. var state = {
  477. sentConnectionHeader: false,
  478. sentContentLengthHeader: false,
  479. sentTransferEncodingHeader: false,
  480. sentDateHeader: false,
  481. sentExpect: false,
  482. messageHeader: firstLine
  483. };
  484. var field, value;
  485. var self = this;
  486. if (headers) {
  487. var keys = Object.keys(headers);
  488. var isArray = (Array.isArray(headers));
  489. var field, value;
  490. for (var i = 0, l = keys.length; i < l; i++) {
  491. var key = keys[i];
  492. if (isArray) {
  493. field = headers[key][0];
  494. value = headers[key][1];
  495. } else {
  496. field = key;
  497. value = headers[key];
  498. }
  499. if (Array.isArray(value)) {
  500. for (var j = 0; j < value.length; j++) {
  501. storeHeader(this, state, field, value[j]);
  502. }
  503. } else {
  504. storeHeader(this, state, field, value);
  505. }
  506. }
  507. }
  508. // Date header
  509. if (this.sendDate == true && state.sentDateHeader == false) {
  510. state.messageHeader += 'Date: ' + utcDate() + CRLF;
  511. }
  512. // Force the connection to close when the response is a 204 No Content or
  513. // a 304 Not Modified and the user has set a "Transfer-Encoding: chunked"
  514. // header.
  515. //
  516. // RFC 2616 mandates that 204 and 304 responses MUST NOT have a body but
  517. // node.js used to send out a zero chunk anyway to accommodate clients
  518. // that don't have special handling for those responses.
  519. //
  520. // It was pointed out that this might confuse reverse proxies to the point
  521. // of creating security liabilities, so suppress the zero chunk and force
  522. // the connection to close.
  523. var statusCode = this.statusCode;
  524. if ((statusCode == 204 || statusCode === 304) &&
  525. this.chunkedEncoding === true) {
  526. debug(statusCode + ' response should not use chunked encoding,' +
  527. ' closing connection.');
  528. this.chunkedEncoding = false;
  529. this.shouldKeepAlive = false;
  530. }
  531. // keep-alive logic
  532. if (state.sentConnectionHeader === false) {
  533. var shouldSendKeepAlive = this.shouldKeepAlive &&
  534. (state.sentContentLengthHeader ||
  535. this.useChunkedEncodingByDefault ||
  536. this.agent);
  537. if (shouldSendKeepAlive) {
  538. state.messageHeader += 'Connection: keep-alive\r\n';
  539. } else {
  540. this._last = true;
  541. state.messageHeader += 'Connection: close\r\n';
  542. }
  543. }
  544. if (state.sentContentLengthHeader == false &&
  545. state.sentTransferEncodingHeader == false) {
  546. if (this._hasBody) {
  547. if (this.useChunkedEncodingByDefault) {
  548. state.messageHeader += 'Transfer-Encoding: chunked\r\n';
  549. this.chunkedEncoding = true;
  550. } else {
  551. this._last = true;
  552. }
  553. } else {
  554. // Make sure we don't end the 0\r\n\r\n at the end of the message.
  555. this.chunkedEncoding = false;
  556. }
  557. }
  558. this._header = state.messageHeader + CRLF;
  559. this._headerSent = false;
  560. // wait until the first body chunk, or close(), is sent to flush,
  561. // UNLESS we're sending Expect: 100-continue.
  562. if (state.sentExpect) this._send('');
  563. };
  564. function storeHeader(self, state, field, value) {
  565. // Protect against response splitting. The if statement is there to
  566. // minimize the performance impact in the common case.
  567. if (/[\r\n]/.test(value))
  568. value = value.replace(/[\r\n]+[ \t]*/g, '');
  569. state.messageHeader += field + ': ' + value + CRLF;
  570. if (connectionExpression.test(field)) {
  571. state.sentConnectionHeader = true;
  572. if (closeExpression.test(value)) {
  573. self._last = true;
  574. } else {
  575. self.shouldKeepAlive = true;
  576. }
  577. } else if (transferEncodingExpression.test(field)) {
  578. state.sentTransferEncodingHeader = true;
  579. if (chunkExpression.test(value)) self.chunkedEncoding = true;
  580. } else if (contentLengthExpression.test(field)) {
  581. state.sentContentLengthHeader = true;
  582. } else if (dateExpression.test(field)) {
  583. state.sentDateHeader = true;
  584. } else if (expectExpression.test(field)) {
  585. state.sentExpect = true;
  586. }
  587. }
  588. OutgoingMessage.prototype.setHeader = function(name, value) {
  589. if (arguments.length < 2) {
  590. throw new Error('`name` and `value` are required for setHeader().');
  591. }
  592. if (this._header) {
  593. throw new Error('Can\'t set headers after they are sent.');
  594. }
  595. var key = name.toLowerCase();
  596. this._headers = this._headers || {};
  597. this._headerNames = this._headerNames || {};
  598. this._headers[key] = value;
  599. this._headerNames[key] = name;
  600. };
  601. OutgoingMessage.prototype.getHeader = function(name) {
  602. if (arguments.length < 1) {
  603. throw new Error('`name` is required for getHeader().');
  604. }
  605. if (!this._headers) return;
  606. var key = name.toLowerCase();
  607. return this._headers[key];
  608. };
  609. OutgoingMessage.prototype.removeHeader = function(name) {
  610. if (arguments.length < 1) {
  611. throw new Error('`name` is required for removeHeader().');
  612. }
  613. if (this._header) {
  614. throw new Error('Can\'t remove headers after they are sent.');
  615. }
  616. if (!this._headers) return;
  617. var key = name.toLowerCase();
  618. delete this._headers[key];
  619. delete this._headerNames[key];
  620. };
  621. OutgoingMessage.prototype._renderHeaders = function() {
  622. if (this._header) {
  623. throw new Error('Can\'t render headers after they are sent to the client.');
  624. }
  625. if (!this._headers) return {};
  626. var headers = {};
  627. var keys = Object.keys(this._headers);
  628. for (var i = 0, l = keys.length; i < l; i++) {
  629. var key = keys[i];
  630. headers[this._headerNames[key]] = this._headers[key];
  631. }
  632. return headers;
  633. };
  634. Object.defineProperty(OutgoingMessage.prototype, 'headersSent', {
  635. configurable: true,
  636. enumerable: true,
  637. get: function() { return !!this._header; }
  638. });
  639. OutgoingMessage.prototype.write = function(chunk, encoding) {
  640. if (!this._header) {
  641. this._implicitHeader();
  642. }
  643. if (!this._hasBody) {
  644. debug('This type of response MUST NOT have a body. ' +
  645. 'Ignoring write() calls.');
  646. return true;
  647. }
  648. if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk)) {
  649. throw new TypeError('first argument must be a string or Buffer');
  650. }
  651. // If we get an empty string or buffer, then just do nothing, and
  652. // signal the user to keep writing.
  653. if (chunk.length === 0) return true;
  654. // TODO(bnoordhuis) Temporary optimization hack, remove in v0.11. We only
  655. // want to convert the buffer when we're sending:
  656. //
  657. // a) Transfer-Encoding chunks, because it lets us pack the chunk header
  658. // and the chunk into a single write(), or
  659. //
  660. // b) the first chunk of a fixed-length request, because it lets us pack
  661. // the request headers and the chunk into a single write().
  662. //
  663. // Converting to strings is expensive, CPU-wise, but reducing the number
  664. // of write() calls more than makes up for that because we're dramatically
  665. // reducing the number of TCP roundtrips.
  666. if (chunk instanceof Buffer && (this.chunkedEncoding || !this._headerSent)) {
  667. chunk = chunk.toString('binary');
  668. encoding = 'binary';
  669. }
  670. var len, ret;
  671. if (this.chunkedEncoding) {
  672. if (typeof(chunk) === 'string' &&
  673. encoding !== 'hex' &&
  674. encoding !== 'base64') {
  675. len = Buffer.byteLength(chunk, encoding);
  676. chunk = len.toString(16) + CRLF + chunk + CRLF;
  677. ret = this._send(chunk, encoding);
  678. } else {
  679. // buffer, or a non-toString-friendly encoding
  680. len = chunk.length;
  681. this._send(len.toString(16) + CRLF);
  682. this._send(chunk, encoding);
  683. ret = this._send(CRLF);
  684. }
  685. } else {
  686. ret = this._send(chunk, encoding);
  687. }
  688. debug('write ret = ' + ret);
  689. return ret;
  690. };
  691. OutgoingMessage.prototype.addTrailers = function(headers) {
  692. this._trailer = '';
  693. var keys = Object.keys(headers);
  694. var isArray = (Array.isArray(headers));
  695. var field, value;
  696. for (var i = 0, l = keys.length; i < l; i++) {
  697. var key = keys[i];
  698. if (isArray) {
  699. field = headers[key][0];
  700. value = headers[key][1];
  701. } else {
  702. field = key;
  703. value = headers[key];
  704. }
  705. this._trailer += field + ': ' + value + CRLF;
  706. }
  707. };
  708. var zero_chunk_buf = new Buffer('\r\n0\r\n');
  709. var crlf_buf = new Buffer('\r\n');
  710. OutgoingMessage.prototype.end = function(data, encoding) {
  711. if (this.finished) {
  712. return false;
  713. }
  714. if (!this._header) {
  715. this._implicitHeader();
  716. }
  717. if (data && !this._hasBody) {
  718. debug('This type of response MUST NOT have a body. ' +
  719. 'Ignoring data passed to end().');
  720. data = false;
  721. }
  722. var ret;
  723. var hot = this._headerSent === false &&
  724. (data && data.length > 0) &&
  725. this.output.length === 0 &&
  726. this.connection &&
  727. this.connection.writable &&
  728. this.connection._httpMessage === this;
  729. // The benefits of the hot-path optimization below start to fall
  730. // off when the buffer size gets up near 128KB, because the cost
  731. // of the copy is more than the cost of the extra write() call.
  732. // Switch to the write/end method at that point. Heuristics and
  733. // magic numbers are awful, but slow http responses are worse.
  734. if (hot && Buffer.isBuffer(data) && data.length > 120 * 1024)
  735. hot = false;
  736. if (hot) {
  737. // Hot path. They're doing
  738. // res.writeHead();
  739. // res.end(blah);
  740. // HACKY.
  741. if (typeof data === 'string') {
  742. if (this.chunkedEncoding) {
  743. var l = Buffer.byteLength(data, encoding).toString(16);
  744. ret = this.connection.write(this._header + l + CRLF +
  745. data + '\r\n0\r\n' +
  746. this._trailer + '\r\n', encoding);
  747. } else {
  748. ret = this.connection.write(this._header + data, encoding);
  749. }
  750. } else if (Buffer.isBuffer(data)) {
  751. if (this.chunkedEncoding) {
  752. var chunk_size = data.length.toString(16);
  753. // Skip expensive Buffer.byteLength() calls; only ISO-8859-1 characters
  754. // are allowed in HTTP headers. Therefore:
  755. //
  756. // this._header.length == Buffer.byteLength(this._header.length)
  757. // this._trailer.length == Buffer.byteLength(this._trailer.length)
  758. //
  759. var header_len = this._header.length;
  760. var chunk_size_len = chunk_size.length;
  761. var data_len = data.length;
  762. var trailer_len = this._trailer.length;
  763. var len = header_len +
  764. chunk_size_len +
  765. 2 + // '\r\n'.length
  766. data_len +
  767. 5 + // '\r\n0\r\n'.length
  768. trailer_len +
  769. 2; // '\r\n'.length
  770. var buf = new Buffer(len);
  771. var off = 0;
  772. buf.write(this._header, off, header_len, 'ascii');
  773. off += header_len;
  774. buf.write(chunk_size, off, chunk_size_len, 'ascii');
  775. off += chunk_size_len;
  776. crlf_buf.copy(buf, off);
  777. off += 2;
  778. data.copy(buf, off);
  779. off += data_len;
  780. zero_chunk_buf.copy(buf, off);
  781. off += 5;
  782. if (trailer_len > 0) {
  783. buf.write(this._trailer, off, trailer_len, 'ascii');
  784. off += trailer_len;
  785. }
  786. crlf_buf.copy(buf, off);
  787. ret = this.connection.write(buf);
  788. } else {
  789. var header_len = this._header.length;
  790. var buf = new Buffer(header_len + data.length);
  791. buf.write(this._header, 0, header_len, 'ascii');
  792. data.copy(buf, header_len);
  793. ret = this.connection.write(buf);
  794. }
  795. } else {
  796. throw new TypeError('first argument must be a string or Buffer');
  797. }
  798. this._headerSent = true;
  799. } else if (data) {
  800. // Normal body write.
  801. ret = this.write(data, encoding);
  802. }
  803. if (!hot) {
  804. if (this.chunkedEncoding) {
  805. ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
  806. } else {
  807. // Force a flush, HACK.
  808. ret = this._send('');
  809. }
  810. }
  811. this.finished = true;
  812. // There is the first message on the outgoing queue, and we've sent
  813. // everything to the socket.
  814. debug('outgoing message end.');
  815. if (this.output.length === 0 && this.connection._httpMessage === this) {
  816. this._finish();
  817. }
  818. return ret;
  819. };
  820. OutgoingMessage.prototype._finish = function() {
  821. assert(this.connection);
  822. if (this instanceof ServerResponse) {
  823. DTRACE_HTTP_SERVER_RESPONSE(this.connection);
  824. COUNTER_HTTP_SERVER_RESPONSE();
  825. } else {
  826. assert(this instanceof ClientRequest);
  827. DTRACE_HTTP_CLIENT_REQUEST(this, this.connection);
  828. COUNTER_HTTP_CLIENT_REQUEST();
  829. }
  830. this.emit('finish');
  831. };
  832. OutgoingMessage.prototype._flush = function() {
  833. // This logic is probably a bit confusing. Let me explain a bit:
  834. //
  835. // In both HTTP servers and clients it is possible to queue up several
  836. // outgoing messages. This is easiest to imagine in the case of a client.
  837. // Take the following situation:
  838. //
  839. // req1 = client.request('GET', '/');
  840. // req2 = client.request('POST', '/');
  841. //
  842. // When the user does
  843. //
  844. // req2.write('hello world\n');
  845. //
  846. // it's possible that the first request has not been completely flushed to
  847. // the socket yet. Thus the outgoing messages need to be prepared to queue
  848. // up data internally before sending it on further to the socket's queue.
  849. //
  850. // This function, outgoingFlush(), is called by both the Server and Client
  851. // to attempt to flush any pending messages out to the socket.
  852. if (!this.socket) return;
  853. var ret;
  854. while (this.output.length) {
  855. if (!this.socket.writable) return; // XXX Necessary?
  856. var data = this.output.shift();
  857. var encoding = this.outputEncodings.shift();
  858. ret = this.socket.write(data, encoding);
  859. }
  860. if (this.finished) {
  861. // This is a queue to the server or client to bring in the next this.
  862. this._finish();
  863. } else if (ret) {
  864. // This is necessary to prevent https from breaking
  865. this.emit('drain');
  866. }
  867. };
  868. function ServerResponse(req) {
  869. OutgoingMessage.call(this);
  870. if (req.method === 'HEAD') this._hasBody = false;
  871. this.sendDate = true;
  872. if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
  873. this.useChunkedEncodingByDefault = chunkExpression.test(req.headers.te);
  874. this.shouldKeepAlive = false;
  875. }
  876. }
  877. util.inherits(ServerResponse, OutgoingMessage);
  878. exports.ServerResponse = ServerResponse;
  879. ServerResponse.prototype.statusCode = 200;
  880. function onServerResponseClose() {
  881. // EventEmitter.emit makes a copy of the 'close' listeners array before
  882. // calling the listeners. detachSocket() unregisters onServerResponseClose
  883. // but if detachSocket() is called, directly or indirectly, by a 'close'
  884. // listener, onServerResponseClose is still in that copy of the listeners
  885. // array. That is, in the example below, b still gets called even though
  886. // it's been removed by a:
  887. //
  888. // var obj = new events.EventEmitter;
  889. // obj.on('event', a);
  890. // obj.on('event', b);
  891. // function a() { obj.removeListener('event', b) }
  892. // function b() { throw "BAM!" }
  893. // obj.emit('event'); // throws
  894. //
  895. // Ergo, we need to deal with stale 'close' events and handle the case
  896. // where the ServerResponse object has already been deconstructed.
  897. // Fortunately, that requires only a single if check. :-)
  898. if (this._httpMessage) this._httpMessage.emit('close');
  899. }
  900. ServerResponse.prototype.assignSocket = function(socket) {
  901. assert(!socket._httpMessage);
  902. socket._httpMessage = this;
  903. socket.on('close', onServerResponseClose);
  904. this.socket = socket;
  905. this.connection = socket;
  906. this.emit('socket', socket);
  907. this._flush();
  908. };
  909. ServerResponse.prototype.detachSocket = function(socket) {
  910. assert(socket._httpMessage == this);
  911. socket.removeListener('close', onServerResponseClose);
  912. socket._httpMessage = null;
  913. this.socket = this.connection = null;
  914. };
  915. ServerResponse.prototype.writeContinue = function() {
  916. this._writeRaw('HTTP/1.1 100 Continue' + CRLF + CRLF, 'ascii');
  917. this._sent100 = true;
  918. };
  919. ServerResponse.prototype._implicitHeader = function() {
  920. this.writeHead(this.statusCode);
  921. };
  922. ServerResponse.prototype.writeHead = function(statusCode) {
  923. var reasonPhrase, headers, headerIndex;
  924. if (typeof arguments[1] == 'string') {
  925. reasonPhrase = arguments[1];
  926. headerIndex = 2;
  927. } else {
  928. reasonPhrase = STATUS_CODES[statusCode] || 'unknown';
  929. headerIndex = 1;
  930. }
  931. this.statusCode = statusCode;
  932. var obj = arguments[headerIndex];
  933. if (obj && this._headers) {
  934. // Slow-case: when progressive API and header fields are passed.
  935. headers = this._renderHeaders();
  936. if (Array.isArray(obj)) {
  937. // handle array case
  938. // TODO: remove when array is no longer accepted
  939. var field;
  940. for (var i = 0, len = obj.length; i < len; ++i) {
  941. field = obj[i][0];
  942. if (headers[field] !== undefined) {
  943. obj.push([field, headers[field]]);
  944. }
  945. }
  946. headers = obj;
  947. } else {
  948. // handle object case
  949. var keys = Object.keys(obj);
  950. for (var i = 0; i < keys.length; i++) {
  951. var k = keys[i];
  952. if (k) headers[k] = obj[k];
  953. }
  954. }
  955. } else if (this._headers) {
  956. // only progressive api is used
  957. headers = this._renderHeaders();
  958. } else {
  959. // only writeHead() called
  960. headers = obj;
  961. }
  962. var statusLine = 'HTTP/1.1 ' + statusCode.toString() + ' ' +
  963. reasonPhrase + CRLF;
  964. if (statusCode === 204 || statusCode === 304 ||
  965. (100 <= statusCode && statusCode <= 199)) {
  966. // RFC 2616, 10.2.5:
  967. // The 204 response MUST NOT include a message-body, and thus is always
  968. // terminated by the first empty line after the header fields.
  969. // RFC 2616, 10.3.5:
  970. // The 304 response MUST NOT contain a message-body, and thus is always
  971. // terminated by the first empty line after the header fields.
  972. // RFC 2616, 10.1 Informational 1xx:
  973. // This class of status code indicates a provisional response,
  974. // consisting only of the Status-Line and optional headers, and is
  975. // terminated by an empty line.
  976. this._hasBody = false;
  977. }
  978. // don't keep alive connections where the client expects 100 Continue
  979. // but we sent a final status; they may put extra bytes on the wire.
  980. if (this._expect_continue && !this._sent100) {
  981. this.shouldKeepAlive = false;
  982. }
  983. this._storeHeader(statusLine, headers);
  984. };
  985. ServerResponse.prototype.writeHeader = function() {
  986. this.writeHead.apply(this, arguments);
  987. };
  988. // New Agent code.
  989. // The largest departure from the previous implementation is that
  990. // an Agent instance holds connections for a variable number of host:ports.
  991. // Surprisingly, this is still API compatible as far as third parties are
  992. // concerned. The only code that really notices the difference is the
  993. // request object.
  994. // Another departure is that all code related to HTTP parsing is in
  995. // ClientRequest.onSocket(). The Agent is now *strictly*
  996. // concerned with managing a connection pool.
  997. function Agent(options) {
  998. EventEmitter.call(this);
  999. var self = this;
  1000. self.options = options || {};
  1001. self.requests = {};
  1002. self.sockets = {};
  1003. self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets;
  1004. self.on('free', function(socket, host, port, localAddress) {
  1005. var name = host + ':' + port;
  1006. if (localAddress) {
  1007. name += ':' + localAddress;
  1008. }
  1009. if (!socket.destroyed &&
  1010. self.requests[name] && self.requests[name].length) {
  1011. self.requests[name].shift().onSocket(socket);
  1012. if (self.requests[name].length === 0) {
  1013. // don't leak
  1014. delete self.requests[name];
  1015. }
  1016. } else {
  1017. // If there are no pending requests just destroy the
  1018. // socket and it will get removed from the pool. This
  1019. // gets us out of timeout issues and allows us to
  1020. // default to Connection:keep-alive.
  1021. socket.destroy();
  1022. }
  1023. });
  1024. self.createConnection = net.createConnection;
  1025. }
  1026. util.inherits(Agent, EventEmitter);
  1027. exports.Agent = Agent;
  1028. Agent.defaultMaxSockets = 5;
  1029. Agent.prototype.defaultPort = 80;
  1030. Agent.prototype.addRequest = function(req, host, port, localAddress) {
  1031. var name = host + ':' + port;
  1032. if (localAddress) {
  1033. name += ':' + localAddress;
  1034. }
  1035. if (!this.sockets[name]) {
  1036. this.sockets[name] = [];
  1037. }
  1038. if (this.sockets[name].length < this.maxSockets) {
  1039. // If we are under maxSockets create a new one.
  1040. req.onSocket(this.createSocket(name, host, port, localAddress, req));
  1041. } else {
  1042. // We are over limit so we'll add it to the queue.
  1043. if (!this.requests[name]) {
  1044. this.requests[name] = [];
  1045. }
  1046. this.requests[name].push(req);
  1047. }
  1048. };
  1049. Agent.prototype.createSocket = function(name, host, port, localAddress, req) {
  1050. var self = this;
  1051. var options = util._extend({}, self.options);
  1052. options.port = port;
  1053. options.host = host;
  1054. options.localAddress = localAddress;
  1055. options.servername = host;
  1056. if (req) {
  1057. var hostHeader = req.getHeader('host');
  1058. if (hostHeader) {
  1059. options.servername = hostHeader.replace(/:.*$/, '');
  1060. }
  1061. }
  1062. var s = self.createConnection(options);
  1063. if (!self.sockets[name]) {
  1064. self.sockets[name] = [];
  1065. }
  1066. this.sockets[name].push(s);
  1067. var onFree = function() {
  1068. self.emit('free', s, host, port, localAddress);
  1069. }
  1070. s.on('free', onFree);
  1071. var onClose = function(err) {
  1072. // This is the only place where sockets get removed from the Agent.
  1073. // If you want to remove a socket from the pool, just close it.
  1074. // All socket errors end in a close event anyway.
  1075. self.removeSocket(s, name, host, port, localAddress);
  1076. }
  1077. s.on('close', onClose);
  1078. var onRemove = function() {
  1079. // We need this function for cases like HTTP 'upgrade'
  1080. // (defined by WebSockets) where we need to remove a socket from the pool
  1081. // because it'll be locked up indefinitely
  1082. self.removeSocket(s, name, host, port, localAddress);
  1083. s.removeListener('close', onClose);
  1084. s.removeListener('free', onFree);
  1085. s.removeListener('agentRemove', onRemove);
  1086. }
  1087. s.on('agentRemove', onRemove);
  1088. return s;
  1089. };
  1090. Agent.prototype.removeSocket = function(s, name, host, port, localAddress) {
  1091. if (this.sockets[name]) {
  1092. var index = this.sockets[name].indexOf(s);
  1093. if (index !== -1) {
  1094. this.sockets[name].splice(index, 1);
  1095. if (this.sockets[name].length === 0) {
  1096. // don't leak
  1097. delete this.sockets[name];
  1098. }
  1099. }
  1100. }
  1101. if (this.requests[name] && this.requests[name].length) {
  1102. var req = this.requests[name][0];
  1103. // If we have pending requests and a socket gets closed a new one
  1104. this.createSocket(name, host, port, localAddress, req).emit('free');
  1105. }
  1106. };
  1107. var globalAgent = new Agent();
  1108. exports.globalAgent = globalAgent;
  1109. function ClientRequest(options, cb) {
  1110. var self = this;
  1111. OutgoingMessage.call(self);
  1112. self.agent = options.agent === undefined ? globalAgent : options.agent;
  1113. var defaultPort = options.defaultPort || 80;
  1114. var port = options.port || defaultPort;
  1115. var host = options.hostname || options.host || 'localhost';
  1116. if (options.setHost === undefined) {
  1117. var setHost = true;
  1118. }
  1119. self.socketPath = options.socketPath;
  1120. var method = self.method = (options.method || 'GET').toUpperCase();
  1121. self.path = options.path || '/';
  1122. if (cb) {
  1123. self.once('response', cb);
  1124. }
  1125. if (!Array.isArray(options.headers)) {
  1126. if (options.headers) {
  1127. var keys = Object.keys(options.headers);
  1128. for (var i = 0, l = keys.length; i < l; i++) {
  1129. var key = keys[i];
  1130. self.setHeader(key, options.headers[key]);
  1131. }
  1132. }
  1133. if (host && !this.getHeader('host') && setHost) {
  1134. var hostHeader = host;
  1135. if (port && +port !== defaultPort) {
  1136. hostHeader += ':' + port;
  1137. }
  1138. this.setHeader('Host', hostHeader);
  1139. }
  1140. }
  1141. if (options.auth && !this.getHeader('Authorization')) {
  1142. //basic auth
  1143. this.setHeader('Authorization', 'Basic ' +
  1144. new Buffer(options.auth).toString('base64'));
  1145. }
  1146. if (method === 'GET' || method === 'HEAD' || method === 'CONNECT') {
  1147. self.useChunkedEncodingByDefault = false;
  1148. } else {
  1149. self.useChunkedEncodingByDefault = true;
  1150. }
  1151. if (Array.isArray(options.headers)) {
  1152. self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
  1153. options.headers);
  1154. } else if (self.getHeader('expect')) {
  1155. self._storeHeader(self.method + ' ' + self.path + ' HTTP/1.1\r\n',
  1156. self._renderHeaders());
  1157. }
  1158. if (self.socketPath) {
  1159. self._last = true;
  1160. self.shouldKeepAlive = false;
  1161. if (options.createConnection) {
  1162. self.onSocket(options.createConnection(self.socketPath));
  1163. } else {
  1164. self.onSocket(net.createConnection(self.socketPath));
  1165. }
  1166. } else if (self.agent) {
  1167. // If there is an agent we should default to Connection:keep-alive.
  1168. self._last = false;
  1169. self.shouldKeepAlive = true;
  1170. self.agent.addRequest(self, host, port, options.localAddress);
  1171. } else {
  1172. // No agent, default to Connection:close.
  1173. self._last = true;
  1174. self.shouldKeepAlive = false;
  1175. if (options.createConnection) {
  1176. options.port = port;
  1177. options.host = host;
  1178. var conn = options.createConnection(options);
  1179. } else {
  1180. var conn = net.createConnection({
  1181. port: port,
  1182. host: host,
  1183. localAddress: options.localAddress
  1184. });
  1185. }
  1186. self.onSocket(conn);
  1187. }
  1188. self._deferToConnect(null, null, function() {
  1189. self._flush();
  1190. self = null;
  1191. });
  1192. }
  1193. util.inherits(ClientRequest, OutgoingMessage);
  1194. exports.ClientRequest = ClientRequest;
  1195. ClientRequest.prototype._implicitHeader = function() {
  1196. this._storeHeader(this.method + ' ' + this.path + ' HTTP/1.1\r\n',
  1197. this._renderHeaders());
  1198. };
  1199. ClientRequest.prototype.abort = function() {
  1200. // If we're aborting, we don't care about any more response data.
  1201. if (this.res)
  1202. this.res._dump();
  1203. else
  1204. this.once('response', function(res) {
  1205. res._dump();
  1206. });
  1207. if (this.socket) {
  1208. // in-progress
  1209. this.socket.destroy();
  1210. } else {
  1211. // haven't been assigned a socket yet.
  1212. // this could be more efficient, it could
  1213. // remove itself from the pending requests
  1214. this._deferToConnect('destroy', []);
  1215. }
  1216. };
  1217. function createHangUpError() {
  1218. var error = new Error('socket hang up');
  1219. error.code = 'ECONNRESET';
  1220. return error;
  1221. }
  1222. // Free the parser and also break any links that it
  1223. // might have to any other things.
  1224. // TODO: All parser data should be attached to a
  1225. // single object, so that it can be easily cleaned
  1226. // up by doing `parser.data = {}`, which should
  1227. // be done in FreeList.free. `parsers.free(parser)`
  1228. // should be all that is needed.
  1229. function freeParser(parser, req) {
  1230. if (parser) {
  1231. parser._headers = [];
  1232. parser.onIncoming = null;
  1233. if (parser.socket) {
  1234. parser.socket.onend = null;
  1235. parser.socket.ondata = null;
  1236. parser.socket.parser = null;
  1237. }
  1238. parser.socket = null;
  1239. parser.incoming = null;
  1240. parsers.free(parser);
  1241. parser = null;
  1242. }
  1243. if (req) {
  1244. req.parser = null;
  1245. }
  1246. }
  1247. function socketCloseListener() {
  1248. var socket = this;
  1249. var parser = socket.parser;
  1250. var req = socket._httpMessage;
  1251. debug('HTTP socket close');
  1252. req.emit('close');
  1253. if (req.res && req.res.readable) {
  1254. // Socket closed before we emitted 'end' below.
  1255. req.res.emit('aborted');
  1256. var res = req.res;
  1257. res.on('end', function() {
  1258. res.emit('close');
  1259. });
  1260. res.push(null);
  1261. } else if (!req.res && !req._hadError) {
  1262. // This socket error fired before we started to
  1263. // receive a response. The error needs to
  1264. // fire on the request.
  1265. req.emit('error', createHangUpError());
  1266. req._hadError = true;
  1267. }
  1268. // Too bad. That output wasn't getting written.
  1269. // This is pretty terrible that it doesn't raise an error.
  1270. // Fixed better in v0.10
  1271. if (req.output)
  1272. req.output.length = 0;
  1273. if (req.outputEncodings)
  1274. req.outputEncodings.length = 0;
  1275. if (parser) {
  1276. parser.finish();
  1277. freeParser(parser, req);
  1278. }
  1279. }
  1280. function socketErrorListener(err) {
  1281. var socket = this;
  1282. var parser = socket.parser;
  1283. var req = socket._httpMessage;
  1284. debug('HTTP SOCKET ERROR: ' + err.message + '\n' + err.stack);
  1285. if (req) {
  1286. req.emit('error', err);
  1287. // For Safety. Some additional errors might fire later on
  1288. // and we need to make sure we don't double-fire the error event.
  1289. req._hadError = true;
  1290. }
  1291. if (parser) {
  1292. parser.finish();
  1293. freeParser(parser, req);
  1294. }
  1295. socket.destroy();
  1296. }
  1297. function socketOnEnd() {
  1298. var socket = this;
  1299. var req = this._httpMessage;
  1300. var parser = this.parser;
  1301. if (!req.res) {
  1302. // If we don't have a response then we know that the socket
  1303. // ended prematurely and we need to emit an error on the request.
  1304. req.emit('error', createHangUpError());
  1305. req._hadError = true;
  1306. }
  1307. if (parser) {
  1308. parser.finish();
  1309. freeParser(parser, req);
  1310. }
  1311. socket.destroy();
  1312. }
  1313. function socketOnData(d, start, end) {
  1314. var socket = this;
  1315. var req = this._httpMessage;
  1316. var parser = this.parser;
  1317. var ret = parser.execute(d, start, end - start);
  1318. if (ret instanceof Error) {
  1319. debug('parse error');
  1320. freeParser(parser, req);
  1321. socket.destroy();
  1322. req.emit('error', ret);
  1323. req._hadError = true;
  1324. } else if (parser.incoming && parser.incoming.upgrade) {
  1325. // Upgrade or CONNECT
  1326. var bytesParsed = ret;
  1327. var res = parser.incoming;
  1328. req.res = res;
  1329. socket.ondata = null;
  1330. socket.onend = null;
  1331. parser.finish();
  1332. // This is start + byteParsed
  1333. var bodyHead = d.slice(start + bytesParsed, end);
  1334. var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
  1335. if (EventEmitter.listenerCount(req, eventName) > 0) {
  1336. req.upgradeOrConnect = true;
  1337. // detach the socket
  1338. socket.emit('agentRemove');
  1339. socket.removeListener('close', socketCloseListener);
  1340. socket.removeListener('error', socketErrorListener);
  1341. req.emit(eventName, res, socket, bodyHead);
  1342. req.emit('close');
  1343. } else {
  1344. // Got Upgrade header or CONNECT method, but have no handler.
  1345. socket.destroy();
  1346. }
  1347. freeParser(parser, req);
  1348. } else if (parser.incoming && parser.incoming.complete &&
  1349. // When the status code is 100 (Continue), the server will
  1350. // send a final response after this client sends a request
  1351. // body. So, we must not free the parser.
  1352. parser.incoming.statusCode !== 100) {
  1353. freeParser(parser, req);
  1354. }
  1355. }
  1356. // client
  1357. function parserOnIncomingClient(res, shouldKeepAlive) {
  1358. var parser = this;
  1359. var socket = this.socket;
  1360. var req = socket._httpMessage;
  1361. // propogate "domain" setting...
  1362. if (req.domain && !res.domain) {
  1363. debug('setting "res.domain"');
  1364. res.domain = req.domain;
  1365. }
  1366. debug('AGENT incoming response!');
  1367. if (req.res) {
  1368. // We already have a response object, this means the server
  1369. // sent a double response.
  1370. socket.destroy();
  1371. return;
  1372. }
  1373. req.res = res;
  1374. // Responses to CONNECT request is handled as Upgrade.
  1375. if (req.method === 'CONNECT') {
  1376. res.upgrade = true;
  1377. return true; // skip body
  1378. }
  1379. // Responses to HEAD requests are crazy.
  1380. // HEAD responses aren't allowed to have an entity-body
  1381. // but *can* have a content-length which actually corresponds
  1382. // to the content-length of the entity-body had the request
  1383. // been a GET.
  1384. var isHeadResponse = req.method == 'HEAD';
  1385. debug('AGENT isHeadResponse ' + isHeadResponse);
  1386. if (res.statusCode == 100) {
  1387. // restart the parser, as this is a continue message.
  1388. delete req.res; // Clear res so that we don't hit double-responses.
  1389. req.emit('continue');
  1390. return true;
  1391. }
  1392. if (req.shouldKeepAlive && !shouldKeepAlive && !req.upgradeOrConnect) {
  1393. // Server MUST respond with Connection:keep-alive for us to enable it.
  1394. // If we've been upgraded (via WebSockets) we also shouldn't try to
  1395. // keep the connection open.
  1396. req.shouldKeepAlive = false;
  1397. }
  1398. DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
  1399. COUNTER_HTTP_CLIENT_RESPONSE();
  1400. req.res = res;
  1401. res.req = req;
  1402. // add our listener first, so that we guarantee socket cleanup
  1403. res.on('end', responseOnEnd);
  1404. var handled = req.emit('response', res);
  1405. // If the user did not listen for the 'response' event, then they
  1406. // can't possibly read the data, so we ._dump() it into the void
  1407. // so that the socket doesn't hang there in a paused state.
  1408. if (!handled)
  1409. res._dump();
  1410. return isHeadResponse;
  1411. }
  1412. // client
  1413. function responseOnEnd() {
  1414. var res = this;
  1415. var req = res.req;
  1416. var socket = req.socket;
  1417. if (!req.shouldKeepAlive) {
  1418. if (socket.writable) {
  1419. debug('AGENT socket.destroySoon()');
  1420. socket.destroySoon();
  1421. }
  1422. assert(!socket.writable);
  1423. } else {
  1424. debug('AGENT socket keep-alive');
  1425. if (req.timeoutCb) {
  1426. socket.setTimeout(0, req.timeoutCb);
  1427. req.timeoutCb = null;
  1428. }
  1429. socket.removeListener('close', socketCloseListener);
  1430. socket.removeListener('error', socketErrorListener);
  1431. // Mark this socket as available, AFTER user-added end
  1432. // handlers have a chance to run.
  1433. process.nextTick(function() {
  1434. socket.emit('free');
  1435. });
  1436. }
  1437. }
  1438. ClientRequest.prototype.onSocket = function(socket) {
  1439. var req = this;
  1440. process.nextTick(function() {
  1441. var parser = parsers.alloc();
  1442. req.socket = socket;
  1443. req.connection = socket;
  1444. parser.reinitialize(HTTPParser.RESPONSE);
  1445. parser.socket = socket;
  1446. parser.incoming = null;
  1447. req.parser = parser;
  1448. socket.parser = parser;
  1449. socket._httpMessage = req;
  1450. // Setup "drain" propogation.
  1451. httpSocketSetup(socket);
  1452. // Propagate headers limit from request object to parser
  1453. if (typeof req.maxHeadersCount === 'number') {
  1454. parser.maxHeaderPairs = req.maxHeadersCount << 1;
  1455. } else {
  1456. // Set default value because parser may be reused from FreeList
  1457. parser.maxHeaderPairs = 2000;
  1458. }
  1459. socket.on('error', socketErrorListener);
  1460. socket.ondata = socketOnData;
  1461. socket.onend = socketOnEnd;
  1462. socket.on('close', socketCloseListener);
  1463. parser.onIncoming = parserOnIncomingClient;
  1464. req.emit('socket', sock

Large files files are truncated, but you can click here to view the full file