Blame view

node_modules/http-proxy-middleware/lib/context-matcher.js 2.11 KB
ce4c83ff   wxy   初始提交
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
  var _ = require('lodash')
  var url = require('url')
  var isGlob = require('is-glob')
  var micromatch = require('micromatch')
  var ERRORS = require('./errors')
  
  module.exports = {
    match: matchContext
  }
  
  function matchContext (context, uri, req) {
    // single path
    if (isStringPath(context)) {
      return matchSingleStringPath(context, uri)
    }
  
    // single glob path
    if (isGlobPath(context)) {
      return matchSingleGlobPath(context, uri)
    }
  
    // multi path
    if (Array.isArray(context)) {
      if (context.every(isStringPath)) {
        return matchMultiPath(context, uri)
      }
      if (context.every(isGlobPath)) {
        return matchMultiGlobPath(context, uri)
      }
  
      throw new Error(ERRORS.ERR_CONTEXT_MATCHER_INVALID_ARRAY)
    }
  
    // custom matching
    if (_.isFunction(context)) {
      var pathname = getUrlPathName(uri)
      return context(pathname, req)
    }
  
    throw new Error(ERRORS.ERR_CONTEXT_MATCHER_GENERIC)
  }
  
  /**
   * @param  {String} context '/api'
   * @param  {String} uri     'http://example.org/api/b/c/d.html'
   * @return {Boolean}
   */
  function matchSingleStringPath (context, uri) {
    var pathname = getUrlPathName(uri)
    return pathname.indexOf(context) === 0
  }
  
  function matchSingleGlobPath (pattern, uri) {
    var pathname = getUrlPathName(uri)
    var matches = micromatch(pathname, pattern)
    return matches && (matches.length > 0)
  }
  
  function matchMultiGlobPath (patternList, uri) {
    return matchSingleGlobPath(patternList, uri)
  }
  
  /**
   * @param  {String} contextList ['/api', '/ajax']
   * @param  {String} uri     'http://example.org/api/b/c/d.html'
   * @return {Boolean}
   */
  function matchMultiPath (contextList, uri) {
    for (var i = 0; i < contextList.length; i++) {
      var context = contextList[i]
      if (matchSingleStringPath(context, uri)) {
        return true
      }
    }
    return false
  }
  
  /**
   * Parses URI and returns RFC 3986 path
   *
   * @param  {String} uri from req.url
   * @return {String}     RFC 3986 path
   */
  function getUrlPathName (uri) {
    return uri && url.parse(uri).pathname
  }
  
  function isStringPath (context) {
    return _.isString(context) && !isGlob(context)
  }
  
  function isGlobPath (context) {
    return isGlob(context)
  }