public UrlRequestConfiguration EnsureTrailingSlash()
        {
            var rule = new UrlRequestRule("<Not configured>", request =>
            {
                var result = new UrlRequestRuleResult();

                if (!request.ProcessedUrl.Path.EndsWith("/"))
                {
                    var uri = new UriBuilder(request.ProcessedUrl.Uri);
                    uri.Path += "/";
                    result.ProcessedUrl = uri;
                }

                return result;
            });

            Add(rule);

            return this;
        }
        public UrlRequestConfiguration CanonicalDomain(string domain)
        {
            var rule = new UrlRequestRule($"Canonical domain of {domain}", request =>
            {
                var result = new UrlRequestRuleResult();

                var canonicalDomainUri = new UriBuilder(request.ProcessedUrl.Uri)
                {
                    Host = domain.ToLower()
                };

                if (!request.ProcessedUrl.Equals(canonicalDomainUri))
                {
                    //request.ProcessedUrl.Host = lcDomain;
                    result.ProcessedUrl = canonicalDomainUri;
                }

                return result;
            });

            Add(rule);

            return this;
        }
        public UrlRequestConfiguration IgnoreFiles(IFileResolver fileResolver = null)
        {
            if (fileResolver == null)
            {
                fileResolver = new DefaultFileFileResolver();
            }

            var rule = new UrlRequestRule("Ignore files on disk", request =>
            {
                var result = new UrlRequestRuleResult();

                var path = VirtualPathUtility.ToAbsolute($"~{request.ProcessedUrl.Uri.AbsolutePath}");
                if (fileResolver.FileExists(path))
                {
                    result.StopProcessing = true;
                }
                return result;
            });

            Rules.Add(rule);

            return this;
        }
 internal void Add(UrlRequestRule rule)
 {
     Rules.Add(rule);
 }
        public UrlRequestConfiguration StripDefaultNames(string[] defaultFileNames)
        {
            var rule = new UrlRequestRule("Strip default file names (such as index.html)", request =>
            {
                var result = new UrlRequestRuleResult();

                // get a URL builder from processedUrl
                var uri = new UriBuilder(request.ProcessedUrl.Uri);

                var parts = uri.Path.Split('/').Skip(1).ToArray();
                var file = parts.LastOrDefault();

                if (defaultFileNames.Contains(file))
                {
                    var newUrl = String.Join("/", parts.Take(parts.Length - 1));
                    uri.Path = newUrl;

                    result.ProcessedUrl = uri;
                }

                return result;
            });

            Rules.Add(rule);

            return this;
        }
        public UrlRequestConfiguration LowerCaseUrl(CultureInfo cultureInfo = null)
        {
            if (cultureInfo == null) cultureInfo = CultureInfo.CurrentCulture;

            var rule = new UrlRequestRule("Make all the URL lower cased", request =>
            {
                var result = new UrlRequestRuleResult();

                // build a lowercase version of the URI
                var lcUri = new UriBuilder(request.ProcessedUrl.Uri)
                {
                    Host = request.ProcessedUrl.Host.ToLower(cultureInfo),
                    Path = request.ProcessedUrl.Path.ToLower(cultureInfo)
                };

                // if they are not the same, set the host/path
                if (!request.ProcessedUrl.Equals(lcUri))
                {
                    result.ProcessedUrl = lcUri;
                }

                return result;
            });

            Add(rule);

            return this;
        }