Пример #1
0
        /// <summary>
        /// Cleans identifiers from an absolute path, and optionally removes the provided prefix
        /// </summary>
        /// <param name="absolutePath">The path to clean</param>
        /// <param name="virtualPathToRemove">The optional virtual path to remove from the front of the path</param>
        /// <returns>The cleaned path</returns>
        public static string GetCleanUriPath(string absolutePath, string virtualPathToRemove)
        {
            if (string.IsNullOrWhiteSpace(absolutePath) || (absolutePath.Length == 1 && absolutePath[0] == '/'))
            {
                return(absolutePath);
            }

            if (!string.IsNullOrEmpty(virtualPathToRemove) && string.Equals(absolutePath, virtualPathToRemove))
            {
                return("/");
            }

            // If the virtual path is "/" then we're hosted at the root, so nothing to remove
            // If not, it will be of the form "/myapp", so remove whole thing
            // Make sure we only remove _whole_ segment i.e. /myapp/controller, but not /myappcontroller
            var hasPrefix = !string.IsNullOrEmpty(virtualPathToRemove) &&
                            virtualPathToRemove != "/" &&
                            virtualPathToRemove[0] == '/' &&
                            absolutePath.StartsWith(virtualPathToRemove, StringComparison.OrdinalIgnoreCase) &&
                            absolutePath.Length > virtualPathToRemove.Length &&
                            absolutePath[virtualPathToRemove.Length] == '/';

            // Sanitized url will be at worse as long as the original, minus a removed virtual path
            var maxLength = absolutePath.Length - (hasPrefix ? virtualPathToRemove.Length : 0);
            var sb        = StringBuilderCache.Acquire(maxLength);

            int previousIndex = hasPrefix ? virtualPathToRemove.Length : 0;
            int index;
            int segmentLength;
            int indexOfFileExtension = 0;

            do
            {
                index = absolutePath.IndexOf('/', previousIndex);

                if (index == -1)
                {
                    // Last segment
                    // Is this a filename with an extension?
                    if (absolutePath.Length > previousIndex &&
                        (indexOfFileExtension = absolutePath.LastIndexOf('.')) != -1 &&
                        indexOfFileExtension > previousIndex)
                    {
                        // Only try and clean the filename, excluding the file extension
                        segmentLength = indexOfFileExtension - previousIndex;
                    }
                    else
                    {
                        segmentLength = absolutePath.Length - previousIndex;
                    }
                }
                else
                {
                    segmentLength = index - previousIndex;
                }

                if (IsIdentifierSegment(absolutePath, previousIndex, segmentLength))
                {
                    sb.Append('?');
                }
                else
                {
                    sb.Append(absolutePath, previousIndex, segmentLength);
                }

                if (index == -1)
                {
                    if (segmentLength > 0 && indexOfFileExtension > previousIndex)
                    {
                        // add the file extension
                        sb.Append(absolutePath, indexOfFileExtension, absolutePath.Length - indexOfFileExtension);
                    }
                }
                else
                {
                    sb.Append('/');
                }

                previousIndex = index + 1;
            }while (index != -1);

            return(StringBuilderCache.GetStringAndRelease(sb));
        }