Code coverage report for lib/_http_incoming.js

Statements: 97.56% (80 / 82)      Branches: 90.24% (37 / 41)      Functions: 83.33% (10 / 12)      Lines: 97.56% (80 / 82)      Ignored: none     

All files » lib/ » _http_incoming.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191    173 173   173 6187 5015   173   173 164 164   173       173 3812           3812 3812   3812 3812 3812 3812 3812 3812 3812 3812   3812   3812     3812 3812     3812 3812 3812     3812       3812   173     173   173                     173 4 4 4 4       173 3730 3730 3730       173       2407 2403             173 2 2       173 7596 3785 3785 2 2   3783 3783     3785 16396 16396 16396 16396 16396                         173 16396 16396     11 5   6   11                                     4722 4708 4722       11663 35   11628               173 3052 3052 3052          
(function () { 'use strict';
 
const util = require('util');
const Stream = require('stream');
 
function readStart(socket) {
  if (socket && !socket._paused && socket.readable)
    socket.resume();
}
exports.readStart = readStart;
 
function readStop(socket) {
  Eif (socket)
    socket.pause();
}
exports.readStop = readStop;
 
 
/* Abstract base class for ServerRequest and ClientResponse. */
function IncomingMessage(socket) {
  Stream.Readable.call(this);
 
  // XXX This implementation is kind of all over the place
  // When the parser emits body chunks, they go in this list.
  // _read() pulls them out, and when it finds EOF, it ends.
 
  this.socket = socket;
  this.connection = socket;
 
  this.httpVersionMajor = null;
  this.httpVersionMinor = null;
  this.httpVersion = null;
  this.complete = false;
  this.headers = {};
  this.rawHeaders = [];
  this.trailers = {};
  this.rawTrailers = [];
 
  this.readable = true;
 
  this.upgrade = null;
 
  // request (server) only
  this.url = '';
  this.method = null;
 
  // response (client) only
  this.statusCode = null;
  this.statusMessage = null;
  this._client = socket; // deprecated
 
  // flag for backwards compatibility grossness.
  this._consuming = false;
 
  // flag for when we decide that this message cannot possibly be
  // read by the user, so there's no point continuing to handle it.
  this._dumped = false;
}
util.inherits(IncomingMessage, Stream.Readable);
 
 
exports.IncomingMessage = IncomingMessage;
 
Object.defineProperty(IncomingMessage.prototype, 'client', {
  configurable: true,
  enumerable: true,
  get: util.deprecate(function() {
    return this._client;
  }, 'client is deprecated, use socket or connection instead'),
  set: util.deprecate(function(val) {
    this._client = val;
  }, 'client is deprecated, use socket or connection instead')
});
 
IncomingMessage.prototype.setTimeout = function(msecs, callback) {
  Eif (callback)
    this.on('timeout', callback);
  this.socket.setTimeout(msecs);
  return this;
};
 
 
IncomingMessage.prototype.read = function(n) {
  this._consuming = true;
  this.read = Stream.Readable.prototype.read;
  return this.read(n);
};
 
 
IncomingMessage.prototype._read = function(n) {
  // We actually do almost nothing here, because the parserOnBody
  // function fills up our internal buffer directly.  However, we
  // do need to unpause the underlying socket so that it flows.
  if (this.socket.readable)
    readStart(this.socket);
};
 
 
// It's possible that the socket will be destroyed, and removed from
// any messages, before ever calling this.  In that case, just skip
// it, since something else is destroying this connection anyway.
IncomingMessage.prototype.destroy = function(error) {
  Eif (this.socket)
    this.socket.destroy(error);
};
 
 
IncomingMessage.prototype._addHeaderLines = function(headers, n) {
  if (headers && headers.length) {
    var raw, dest;
    if (this.complete) {
      raw = this.rawTrailers;
      dest = this.trailers;
    } else {
      raw = this.rawHeaders;
      dest = this.headers;
    }
 
    for (var i = 0; i < n; i += 2) {
      var k = headers[i];
      var v = headers[i + 1];
      raw.push(k);
      raw.push(v);
      this._addHeaderLine(k, v, dest);
    }
  }
};
 
 
// Add the given (field, value) pair to the message
//
// Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
// same header with a ', ' if the header in question supports specification of
// multiple values this way. If not, we declare the first instance the winner
// and drop the second. Extended header fields (those beginning with 'x-') are
// always joined.
IncomingMessage.prototype._addHeaderLine = function(field, value, dest) {
  field = field.toLowerCase();
  switch (field) {
    // Array headers:
    case 'set-cookie':
      if (dest[field] !== undefined) {
        dest[field].push(value);
      } else {
        dest[field] = [value];
      }
      break;
 
    /* eslint-disable max-len */
    // list is taken from:
    // https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
    /* eslint-enable max-len */
    case 'content-type':
    case 'content-length':
    case 'user-agent':
    case 'referer':
    case 'host':
    case 'authorization':
    case 'proxy-authorization':
    case 'if-modified-since':
    case 'if-unmodified-since':
    case 'from':
    case 'location':
    case 'max-forwards':
      // drop duplicates
      if (dest[field] === undefined)
        dest[field] = value;
      break;
 
    default:
      // make comma-separated list
      if (dest[field] !== undefined) {
        dest[field] += ', ' + value;
      } else {
        dest[field] = value;
      }
  }
};
 
 
// Call this instead of resume() if we want to just
// dump all the data to /dev/null
IncomingMessage.prototype._dump = function() {
  Eif (!this._dumped) {
    this._dumped = true;
    this.resume();
  }
};
 
}());