Blame view

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