index.js 1.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 = req.connection.remoteAddress
  26. var addrs = [socketAddr].concat(proxyAddrs)
  27. // return all addresses
  28. return addrs
  29. }
  30. /**
  31. * Parse the X-Forwarded-For header.
  32. *
  33. * @param {string} header
  34. * @private
  35. */
  36. function parse (header) {
  37. var end = header.length
  38. var list = []
  39. var start = header.length
  40. // gather addresses, backwards
  41. for (var i = header.length - 1; i >= 0; i--) {
  42. switch (header.charCodeAt(i)) {
  43. case 0x20: /* */
  44. if (start === end) {
  45. start = end = i
  46. }
  47. break
  48. case 0x2c: /* , */
  49. if (start !== end) {
  50. list.push(header.substring(start, end))
  51. }
  52. start = end = i
  53. break
  54. default:
  55. start = i
  56. break
  57. }
  58. }
  59. // final address
  60. if (start !== end) {
  61. list.push(header.substring(start, end))
  62. }
  63. return list
  64. }