utils.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. var fs = require('fs'),
  2. url = require('url'),
  3. stream = require('stream');
  4. function resolve_url(href, base) {
  5. if (url.URL)
  6. return new url.URL(href, base);
  7. // older Node version (< v6.13)
  8. return base ? url.resolve(base, href) : href;
  9. }
  10. function host_and_ports_match(url1, url2) {
  11. if (url1.indexOf('http') < 0) url1 = 'http://' + url1;
  12. if (url2.indexOf('http') < 0) url2 = 'http://' + url2;
  13. var a = url.parse(url1), b = url.parse(url2);
  14. return a.host == b.host
  15. && String(a.port || (a.protocol == 'https:' ? 443 : 80))
  16. == String(b.port || (b.protocol == 'https:' ? 443 : 80));
  17. }
  18. // returns false if a no_proxy host or pattern matches given url
  19. function should_proxy_to(uri) {
  20. var no_proxy = get_env_var(['NO_PROXY'], true);
  21. if (!no_proxy) return true;
  22. // previous (naive, simple) strategy
  23. // var host, hosts = no_proxy.split(',');
  24. // for (var i in hosts) {
  25. // host = hosts[i];
  26. // if (host_and_ports_match(host, uri)) {
  27. // return false;
  28. // }
  29. // }
  30. var pattern, pattern_list = no_proxy.split(/[\s,]+/);
  31. for (var i in pattern_list) {
  32. pattern = pattern_list[i];
  33. if (pattern.trim().length == 0) continue;
  34. // replace leading dot by asterisk, escape dots and finally replace asterisk by .*
  35. var regex = new RegExp(pattern.replace(/^\./, "*").replace(/[.]/g, '\\$&').replace(/\*/g, '.*'))
  36. if (uri.match(regex)) return false;
  37. }
  38. return true;
  39. }
  40. function get_env_var(keys, try_lower) {
  41. var val, i = -1, env = process.env;
  42. while (!val && i < keys.length-1) {
  43. val = env[keys[++i]];
  44. if (!val && try_lower) {
  45. val = env[keys[i].toLowerCase()];
  46. }
  47. }
  48. return val;
  49. }
  50. function parse_content_type(header) {
  51. if (!header || header === '') return {};
  52. var found, charset = 'utf8', arr = header.split(';');
  53. if (arr.length > 1 && (found = arr[1].match(/charset=(.+)/)))
  54. charset = found[1];
  55. return { type: arr[0], charset: charset };
  56. }
  57. function is_stream(obj) {
  58. return typeof obj.pipe === 'function';
  59. }
  60. function get_stream_length(stream, given_length, cb) {
  61. if (given_length > 0)
  62. return cb(given_length);
  63. if (stream.end !== void 0 && stream.end !== Infinity && stream.start !== void 0)
  64. return cb((stream.end + 1) - (stream.start || 0));
  65. fs.stat(stream.path, function(err, stat) {
  66. cb(stat ? stat.size - (stream.start || 0) : null);
  67. });
  68. }
  69. function pump_streams(streams, cb) {
  70. if (stream.pipeline)
  71. return stream.pipeline.apply(null, streams.concat(cb));
  72. var tmp = streams.shift();
  73. while (streams.length) {
  74. tmp = tmp.pipe(streams.shift());
  75. tmp.once('error', function(e) {
  76. cb && cb(e);
  77. cb = null;
  78. })
  79. }
  80. }
  81. module.exports = {
  82. resolve_url: resolve_url,
  83. get_env_var: get_env_var,
  84. host_and_ports_match: host_and_ports_match,
  85. should_proxy_to: should_proxy_to,
  86. parse_content_type: parse_content_type,
  87. is_stream: is_stream,
  88. get_stream_length: get_stream_length,
  89. pump_streams: pump_streams
  90. }