index.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*!
  2. * forwarded
  3. * Copyright(c) 2014-2017 Douglas Christopher Wilson
  4. * MIT Licensed
  5. */
  6. 'use strict'
  7. /**
  8. * Module exports.
  9. * @public
  10. */
  11. module.exports = forwarded
  12. /**
  13. * Get all addresses in the request, using the `X-Forwarded-For` header.
  14. *
  15. * @param {object} req
  16. * @return {array}
  17. * @public
  18. */
  19. function forwarded (req) {
  20. if (!req) {
  21. throw new TypeError('argument req is required')
  22. }
  23. // simple header parsing
  24. var proxyAddrs = parse(req.headers['x-forwarded-for'] || '')
  25. var socketAddr = getSocketAddr(req)
  26. var addrs = [socketAddr].concat(proxyAddrs)
  27. // return all addresses
  28. return addrs
  29. }
  30. /**
  31. * Get the socket address for a request.
  32. *
  33. * @param {object} req
  34. * @return {string}
  35. * @private
  36. */
  37. function getSocketAddr (req) {
  38. return req.socket
  39. ? req.socket.remoteAddress
  40. : req.connection.remoteAddress
  41. }
  42. /**
  43. * Parse the X-Forwarded-For header.
  44. *
  45. * @param {string} header
  46. * @private
  47. */
  48. function parse (header) {
  49. var end = header.length
  50. var list = []
  51. var start = header.length
  52. // gather addresses, backwards
  53. for (var i = header.length - 1; i >= 0; i--) {
  54. switch (header.charCodeAt(i)) {
  55. case 0x20: /* */
  56. if (start === end) {
  57. start = end = i
  58. }
  59. break
  60. case 0x2c: /* , */
  61. if (start !== end) {
  62. list.push(header.substring(start, end))
  63. }
  64. start = end = i
  65. break
  66. default:
  67. start = i
  68. break
  69. }
  70. }
  71. // final address
  72. if (start !== end) {
  73. list.push(header.substring(start, end))
  74. }
  75. return list
  76. }