Ejemplo n.º 1
0
        /// <summary>
        /// Remove action associated with path and method<br/>
        /// 删除路径和方法关联的Action函数<br/>
        /// </summary>
        public bool Remove(string path, string method)
        {
            var basePath = ParsePath(path, out var regex, out var parameters);

            if (regex == null)
            {
                // Normal action
                var key = Pair.Create(basePath, method);
                return(Actions.TryRemove(key, out var _));
            }
            else
            {
                // Regex action
                RegexActionsLock.EnterReadLock();
                try
                {
                    var pattern = regex.ToString();
                    return(RegexActions.TryGetValue(basePath, out var descriptors) &&
                           descriptors.RemoveAll(d => d.Method == method && d.Regex.ToString() == pattern) > 0);
                }
                finally
                {
                    RegexActionsLock.ExitReadLock();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Associate action with path and method<br/>
        /// 设置路径和方法关联的Action函数<br/>
        /// </summary>
        public void Set(string path, string method, Func <IActionResult> action, bool overrideExists)
        {
            // Parse path
            var basePath = ParsePath(path, out var pattern, out var parameters);
            // Duplicate check
            var key = Pair.Create(basePath, method);

            if (!overrideExists)
            {
                bool duplicated = false;
                if (pattern == null)
                {
                    // No expression found, just check the key
                    duplicated = Actions.ContainsKey(key);
                }
                else
                {
                    // Check if there any descriptor have same method and regex
                    RegexActionsLock.EnterReadLock();
                    try {
                        duplicated = RegexActions.TryGetValue(basePath, out var descriptors) &&
                                     descriptors.Any(d => d.Method == method && d.Pattern == pattern);
                    } finally {
                        RegexActionsLock.ExitReadLock();
                    }
                }
                if (duplicated)
                {
                    throw new ArgumentException(
                              $"Action for method '{method}' and path '{path}' already registered, " +
                              "please use option `overrideExists` if you want to replace it");
                }
            }
            // Register action
            if (pattern == null)
            {
                // Normal action
                Actions[key] = action;
            }
            else
            {
                // Regex action
                RegexActionsLock.EnterWriteLock();
                try {
                    if (!RegexActions.TryGetValue(basePath, out var descriptors))
                    {
                        descriptors            = new List <RegexActionDescriptor>();
                        RegexActions[basePath] = descriptors;
                    }
                    // Sort descriptors by pattern length descending
                    var regex = new Regex(pattern);
                    descriptors.Add(new RegexActionDescriptor(method, pattern, regex, parameters, action));
                    descriptors.Sort((x, y) => y.Pattern.Length - x.Pattern.Length);
                } finally {
                    RegexActionsLock.ExitWriteLock();
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get action associated with path and method<br/>
        /// 获取路径和方法关联的Action函数<br/>
        /// </summary>
        public Func <IActionResult> Get(string path, string method)
        {
            // Search normal action
            var key = Pair.Create(path, method);

            if (Actions.TryGetValue(key, out var action))
            {
                return(action);
            }
            // Search regex action
            // Matching from the lonest base path, for example:
            //	rules: "get/some/{id}", "get/{id}"
            //	"get/some/1" matches "get/some/{id}"
            //	"get/1" matches "get/{id}"
            RegexActionsLock.EnterReadLock();
            try
            {
                var nodes = RegexActions.Travel(path, false).Where(a => a.HasValue).Reverse();
                foreach (var node in nodes)
                {
                    foreach (var descriptor in node.Value)
                    {
                        // Check method first because all methods are using the same list
                        if (descriptor.Method != method)
                        {
                            continue;
                        }
                        // Match pattern, descriptors should be sorted by pattern length descennding
                        var match = descriptor.Regex.Match(path);
                        if (!match.Success)
                        {
                            continue;
                        }
                        // Set custom parameters to request
                        var request = HttpManager.CurrentContext.Request;
                        for (var i = 0; i < descriptor.Parameters.Count; ++i)
                        {
                            var name  = descriptor.Parameters[i];
                            var value = match.Groups[i + 1].Value;
                            request.CustomParameters[name] = value;
                        }
                        return(descriptor.Action);
                    }
                }
            }
            finally
            {
                RegexActionsLock.ExitReadLock();
            }
            return(null);
        }