web-outgoing.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. var url = require('url'),
  2. common = require('../common');
  3. var redirectRegex = /^201|30(1|2|7|8)$/;
  4. /*!
  5. * Array of passes.
  6. *
  7. * A `pass` is just a function that is executed on `req, res, options`
  8. * so that you can easily add new checks while still keeping the base
  9. * flexible.
  10. */
  11. module.exports = { // <--
  12. /**
  13. * If is a HTTP 1.0 request, remove chunk headers
  14. *
  15. * @param {ClientRequest} Req Request object
  16. * @param {IncomingMessage} Res Response object
  17. * @param {proxyResponse} Res Response object from the proxy request
  18. *
  19. * @api private
  20. */
  21. removeChunked: function removeChunked(req, res, proxyRes) {
  22. if (req.httpVersion === '1.0') {
  23. delete proxyRes.headers['transfer-encoding'];
  24. }
  25. },
  26. /**
  27. * If is a HTTP 1.0 request, set the correct connection header
  28. * or if connection header not present, then use `keep-alive`
  29. *
  30. * @param {ClientRequest} Req Request object
  31. * @param {IncomingMessage} Res Response object
  32. * @param {proxyResponse} Res Response object from the proxy request
  33. *
  34. * @api private
  35. */
  36. setConnection: function setConnection(req, res, proxyRes) {
  37. if (req.httpVersion === '1.0') {
  38. proxyRes.headers.connection = req.headers.connection || 'close';
  39. } else if (req.httpVersion !== '2.0' && !proxyRes.headers.connection) {
  40. proxyRes.headers.connection = req.headers.connection || 'keep-alive';
  41. }
  42. },
  43. setRedirectHostRewrite: function setRedirectHostRewrite(req, res, proxyRes, options) {
  44. if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite)
  45. && proxyRes.headers['location']
  46. && redirectRegex.test(proxyRes.statusCode)) {
  47. var target = url.parse(options.target);
  48. var u = url.parse(proxyRes.headers['location']);
  49. // make sure the redirected host matches the target host before rewriting
  50. if (target.host != u.host) {
  51. return;
  52. }
  53. if (options.hostRewrite) {
  54. u.host = options.hostRewrite;
  55. } else if (options.autoRewrite) {
  56. u.host = req.headers['host'];
  57. }
  58. if (options.protocolRewrite) {
  59. u.protocol = options.protocolRewrite;
  60. }
  61. proxyRes.headers['location'] = u.format();
  62. }
  63. },
  64. /**
  65. * Copy headers from proxyResponse to response
  66. * set each header in response object.
  67. *
  68. * @param {ClientRequest} Req Request object
  69. * @param {IncomingMessage} Res Response object
  70. * @param {proxyResponse} Res Response object from the proxy request
  71. * @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain
  72. *
  73. * @api private
  74. */
  75. writeHeaders: function writeHeaders(req, res, proxyRes, options) {
  76. var rewriteCookieDomainConfig = options.cookieDomainRewrite,
  77. rewriteCookiePathConfig = options.cookiePathRewrite,
  78. preserveHeaderKeyCase = options.preserveHeaderKeyCase,
  79. rawHeaderKeyMap,
  80. setHeader = function(key, header) {
  81. if (header == undefined) return;
  82. if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
  83. header = common.rewriteCookieProperty(header, rewriteCookieDomainConfig, 'domain');
  84. }
  85. if (rewriteCookiePathConfig && key.toLowerCase() === 'set-cookie') {
  86. header = common.rewriteCookieProperty(header, rewriteCookiePathConfig, 'path');
  87. }
  88. res.setHeader(String(key).trim(), header);
  89. };
  90. if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
  91. rewriteCookieDomainConfig = { '*': rewriteCookieDomainConfig };
  92. }
  93. if (typeof rewriteCookiePathConfig === 'string') { //also test for ''
  94. rewriteCookiePathConfig = { '*': rewriteCookiePathConfig };
  95. }
  96. // message.rawHeaders is added in: v0.11.6
  97. // https://nodejs.org/api/http.html#http_message_rawheaders
  98. if (preserveHeaderKeyCase && proxyRes.rawHeaders != undefined) {
  99. rawHeaderKeyMap = {};
  100. for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) {
  101. var key = proxyRes.rawHeaders[i];
  102. rawHeaderKeyMap[key.toLowerCase()] = key;
  103. }
  104. }
  105. Object.keys(proxyRes.headers).forEach(function(key) {
  106. var header = proxyRes.headers[key];
  107. if (preserveHeaderKeyCase && rawHeaderKeyMap) {
  108. key = rawHeaderKeyMap[key] || key;
  109. }
  110. setHeader(key, header);
  111. });
  112. },
  113. /**
  114. * Set the statusCode from the proxyResponse
  115. *
  116. * @param {ClientRequest} Req Request object
  117. * @param {IncomingMessage} Res Response object
  118. * @param {proxyResponse} Res Response object from the proxy request
  119. *
  120. * @api private
  121. */
  122. writeStatusCode: function writeStatusCode(req, res, proxyRes) {
  123. // From Node.js docs: response.writeHead(statusCode[, statusMessage][, headers])
  124. if(proxyRes.statusMessage) {
  125. res.statusCode = proxyRes.statusCode;
  126. res.statusMessage = proxyRes.statusMessage;
  127. } else {
  128. res.statusCode = proxyRes.statusCode;
  129. }
  130. }
  131. };