| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 | /*! * on-headers * Copyright(c) 2014 Douglas Christopher Wilson * MIT Licensed */'use strict'/** * Module exports. * @public */module.exports = onHeadersvar http = require('http')// older node versions don't have appendHeadervar isAppendHeaderSupported = typeof http.ServerResponse.prototype.appendHeader === 'function'var set1dArray = isAppendHeaderSupported ? set1dArrayWithAppend : set1dArrayWithSet/** * Create a replacement writeHead method. * * @param {function} prevWriteHead * @param {function} listener * @private */function createWriteHead (prevWriteHead, listener) {  var fired = false  // return function with core name and argument list  return function writeHead (statusCode) {    // set headers from arguments    var args = setWriteHeadHeaders.apply(this, arguments)    // fire listener    if (!fired) {      fired = true      listener.call(this)      // pass-along an updated status code      if (typeof args[0] === 'number' && this.statusCode !== args[0]) {        args[0] = this.statusCode        args.length = 1      }    }    return prevWriteHead.apply(this, args)  }}/** * Execute a listener when a response is about to write headers. * * @param {object} res * @return {function} listener * @public */function onHeaders (res, listener) {  if (!res) {    throw new TypeError('argument res is required')  }  if (typeof listener !== 'function') {    throw new TypeError('argument listener must be a function')  }  res.writeHead = createWriteHead(res.writeHead, listener)}/** * Set headers contained in array on the response object. * * @param {object} res * @param {array} headers * @private */function setHeadersFromArray (res, headers) {  if (headers.length && Array.isArray(headers[0])) {    // 2D    set2dArray(res, headers)  } else {    // 1D    if (headers.length % 2 !== 0) {      throw new TypeError('headers array is malformed')    }    set1dArray(res, headers)  }}/** * Set headers contained in object on the response object. * * @param {object} res * @param {object} headers * @private */function setHeadersFromObject (res, headers) {  var keys = Object.keys(headers)  for (var i = 0; i < keys.length; i++) {    var k = keys[i]    if (k) res.setHeader(k, headers[k])  }}/** * Set headers and other properties on the response object. * * @param {number} statusCode * @private */function setWriteHeadHeaders (statusCode) {  var length = arguments.length  var headerIndex = length > 1 && typeof arguments[1] === 'string'    ? 2    : 1  var headers = length >= headerIndex + 1    ? arguments[headerIndex]    : undefined  this.statusCode = statusCode  if (Array.isArray(headers)) {    // handle array case    setHeadersFromArray(this, headers)  } else if (headers) {    // handle object case    setHeadersFromObject(this, headers)  }  // copy leading arguments  var args = new Array(Math.min(length, headerIndex))  for (var i = 0; i < args.length; i++) {    args[i] = arguments[i]  }  return args}function set2dArray (res, headers) {  var key  for (var i = 0; i < headers.length; i++) {    key = headers[i][0]    if (key) {      res.setHeader(key, headers[i][1])    }  }}function set1dArrayWithAppend (res, headers) {  for (var i = 0; i < headers.length; i += 2) {    res.removeHeader(headers[i])  }  var key  for (var j = 0; j < headers.length; j += 2) {    key = headers[j]    if (key) {      res.appendHeader(key, headers[j + 1])    }  }}function set1dArrayWithSet (res, headers) {  var key  for (var i = 0; i < headers.length; i += 2) {    key = headers[i]    if (key) {      res.setHeader(key, headers[i + 1])    }  }}
 |