/// <summary>
 /// 匹配Host
 /// </summary>
 /// <param name="route">路由条目</param>
 /// <param name="request">请求</param>
 private static void BindHostParameters(Route route, Request request)
 {
     MatchToKeys(route, request, route.Compiled.HostRegex.Match(request.RouteUri.Host));
 }
Esempio n. 2
0
        /// <summary>
        /// 编译参数
        /// </summary>
        /// <param name="route">路由条目</param>
        /// <param name="uri">uri</param>
        /// <param name="isHost">是否是host</param>
        /// <returns>编译数据</returns>
        private static Hashtable CompilePattern(Route route, string uri, bool isHost)
        {
            int[] parametersIndex = null;

            var defaultSeparator = isHost ? "." : "/";

            //可选参数
            var optionalParameters = new List <string>(MatchParameters(route.Uri.FullPath, @"\{(\w+?)\?\}", ref parametersIndex));

            //所有参数
            var parameters = MatchParameters(uri, @"\{(\w+?)\}", ref parametersIndex);

            //已经被使用的变量名
            var variables = new List <string>();

            var tokens = new List <string[]>();

            var    pos = 0;
            string varName, precedingText, precedingChar, where, followingPattern, nextSeparator;
            bool   isSeparator;

            for (var i = 0; i < parameters.Length; i++)
            {
                varName = parameters[i];

                // 获取当前匹配的变量之前的静态文本
                precedingText = uri.Substring(pos, parametersIndex[i] - pos);
                pos           = parametersIndex[i] + parameters[i].Length + 2;

                precedingChar = precedingText.Length <= 0 ? string.Empty : precedingText.Substring(precedingText.Length - 1);

                isSeparator = string.Empty != precedingChar && SEPARATORS.Contains(precedingChar);

                if (IsMatch(@"^\d", varName))
                {
                    throw new DomainException(string.Format("variable name {0} cannot start with a digit in route pattern {1}. please use a different name.", varName, uri));
                }

                if (variables.Contains(varName))
                {
                    throw new DomainException(string.Format("route pattern {0} cannot reference variable name {1} more than once.", varName, uri));
                }

                if (varName.Length > VARIABLE_MAXIMUM_LENGTH)
                {
                    throw new DomainException(string.Format("variable name {0} cannot be longer than {1} characters in route pattern {2}. please use a shorter name.", varName, VARIABLE_MAXIMUM_LENGTH, uri));
                }

                if (isSeparator && precedingText != precedingChar)
                {
                    tokens.Add(new[] { "text", precedingText.Substring(0, precedingText.Length - precedingChar.Length) });
                }
                else if (!isSeparator && precedingText.Length > 0)
                {
                    tokens.Add(new[] { "text", precedingText });
                }

                //获取where的约束条件
                where = route.GetWhere(varName);

                if (where == null)
                {
                    //获取之后的内容
                    followingPattern = uri.Substring(pos);

                    //下一个分隔符
                    nextSeparator = FindNextSeparator(followingPattern);

                    where = string.Format(
                        "[^{0}{1}]+",
                        RegexQuote(defaultSeparator),
                        defaultSeparator != nextSeparator && nextSeparator != string.Empty ? RegexQuote(nextSeparator) : string.Empty
                        );
                }

                tokens.Add(new[] { "variable", isSeparator ? precedingChar : string.Empty, where, varName });
                variables.Add(varName);
            }

            //如果不是全部内容则追加入后续内容
            if (pos < uri.Length)
            {
                tokens.Add(new[] { "text", uri.Substring(pos) });
            }

            var firstOptional = int.MaxValue;

            if (!isHost)
            {
                string[] token;
                for (var i = tokens.Count - 1; i >= 0; --i)
                {
                    token = tokens[i];
                    if ("variable" == token[0] && optionalParameters.Contains(token[3]))
                    {
                        firstOptional = i;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            //计算并生成最终的表达式
            var regexp = string.Empty;

            for (int i = 0, nbToken = tokens.Count; i < nbToken; ++i)
            {
                regexp += ComputeRegexp(tokens, i, firstOptional);
            }
            regexp = '^' + regexp + "$";

            var hash = new Hashtable
            {
                { "staticPrefix", "text" == tokens[0][0] ? tokens[0][1] : string.Empty },
                { "regex", regexp },
                { "variables", variables.ToArray() }
            };

            tokens.Reverse();
            hash.Add("tokens", tokens.ToArray());

            return(hash);
        }
 /// <summary>
 /// 匹配路径
 /// </summary>
 /// <param name="route">路由条目</param>
 /// <param name="request">请求</param>
 private static void BindPathParameters(Route route, Request request)
 {
     MatchToKeys(route, request, route.Compiled.RouteRegex.Match(request.RouteUri.NoParamFullPath));
 }