Possible Bug With ASP.NET MVC 3 Routing?

前端 未结 3 2223
猫巷女王i
猫巷女王i 2020-12-17 15:47

Normally i wouldn\'t put a title like this in the question, but i\'m pretty sure it\'s a bug (or by design?)

I created a brand new ASP.NET MVC 3 Web Application.

3条回答
  •  别那么骄傲
    2020-12-17 16:17

    This appears to be related to Cookieless Sessions in the ASP.NET pipeline. It strips that URL pattern inside CookielessHelper.cs (System.Web.Security) while processing the request:

        // This function is called for all requests -- it must be performant.
        //    In the common case (i.e. value not present in the URI, it must not
        //    look at the headers collection
        internal void RemoveCookielessValuesFromPath() 
        {
            // See if the path contains "/(XXXXX)/" 
            string   path      = _Context.Request.ClientFilePath.VirtualPathString; 
            // Optimize for the common case where there is no cookie
            if (path.IndexOf('(') == -1) { 
                return;
            }
            int      endPos    = path.LastIndexOf(")/", StringComparison.Ordinal);
            int      startPos  = (endPos > 2 ?  path.LastIndexOf("/(", endPos - 1, endPos, StringComparison.Ordinal) : -1); 
    
            if (startPos < 0) // pattern not found: common case, exit immediately 
                return; 
    
            if (_Headers == null) // Header should always be processed first 
                GetCookielessValuesFromHeader();
    
            // if the path contains a cookie, remove it
            if (IsValidHeader(path, startPos + 2, endPos)) 
            {
                // only set _Headers if not already set 
                if (_Headers == null) { 
                    _Headers = path.Substring(startPos + 2, endPos - startPos - 2);
                } 
                // Rewrite the path
                path = path.Substring(0, startPos) + path.Substring(endPos+1);
    
                // remove cookie from ClientFilePath 
                _Context.Request.ClientFilePath = VirtualPath.CreateAbsolute(path);
                // get and append query string to path if it exists 
                string rawUrl = _Context.Request.RawUrl; 
                int qsIndex = rawUrl.IndexOf('?');
                if (qsIndex > -1) { 
                    path = path + rawUrl.Substring(qsIndex);
                }
                // remove cookie from RawUrl
                _Context.Request.RawUrl = path; 
    
                if (!String.IsNullOrEmpty(_Headers)) { 
                    _Context.Request.ValidateCookielessHeaderIfRequiredByConfig(_Headers); // ensure that the path doesn't contain invalid chars 
                    _Context.Response.SetAppPathModifier("(" + _Headers + ")");
    
                    // For Cassini and scenarios where aspnet_filter.dll is not used,
                    // HttpRequest.FilePath also needs to have the cookie removed.
                    string filePath = _Context.Request.FilePath;
                    string newFilePath = _Context.Response.RemoveAppPathModifier(filePath); 
                    if (!Object.ReferenceEquals(filePath, newFilePath)) {
                        _Context.RewritePath(VirtualPath.CreateAbsolute(newFilePath), 
                                             _Context.Request.PathInfoObject, 
                                             null /*newQueryString*/,
                                             false /*setClientFilePath*/); 
                    }
                }
            }
        } 
    

    Your pattern matches this:

        ///////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////// 
        // Make sure sub-string if of the pattern: A(XXXX)N(XXXXX)P(XXXXX) and so on. 
        static private bool IsValidHeader(string path, int startPos, int endPos)
        { 
            if (endPos - startPos < 3) // Minimum len is "X()"
                return false;
    
            while (startPos <= endPos - 3) { // Each iteration deals with one "A(XXXX)" pattern 
    
                if (path[startPos] < 'A' || path[startPos] > 'Z') // Make sure pattern starts with a capital letter 
                    return false; 
    
                if (path[startPos + 1] != '(') // Make sure next char is '(' 
                    return false;
    
                startPos += 2;
                bool found = false; 
                for (; startPos < endPos; startPos++) { // Find the ending ')'
    
                    if (path[startPos] == ')') { // found it! 
                        startPos++; // Set position for the next pattern
                        found = true; 
                        break; // Break out of this for-loop.
                    }
    
                    if (path[startPos] == '/') { // Can't contain path separaters 
                        return false;
                    } 
                } 
                if (!found)  {
                    return false; // Ending ')' not found! 
                }
            }
    
            if (startPos < endPos) // All chars consumed? 
                return false;
    
            return true; 
        }
    

提交回复
热议问题