Error message when a client tries to open a Web site for the first time: "HTTP 400 - Bad Request" (909622)



The information in this article applies to:

  • Microsoft .NET Framework 2.0
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0


Important This article contains information about how to modify the registry. Make sure to back up the registry before you modify it. Make sure that you know how to restore the registry if a problem occurs. For more information about how to back up, restore, and modify the registry, click the following article number to view the article in the Microsoft Knowledge Base:

256986 Description of the Microsoft Windows registry

SYMPTOMS

Consider the following scenario. You run a Microsoft ASP.NET application on a Microsoft Windows Server 2003-based computer. The Microsoft .NET Framework is installed on the computer. A client tries to open the Web site for the first time. In this scenario, the client may receive an error message that is similar to the following:
HTTP 400 - Bad Request
This problem occurs when the cookieless attribute of the sessionState element in the configuration file is set to true.

CAUSE

This problem occurs because the request was sent to the Windows Server 2003-based computer through a proxy. The proxy may modify the header value for the URL from a relative value to a fully qualified value.

RESOLUTION

To resolve this problem, create a new ISAPI filter to remove the fully qualified URL from the URL header before the Aspnet_isapi.dll filter receives the request.

Create the new filter

To create the new filter, follow these steps:
  1. In Microsoft Visual Studio .NET 2003, create a new Microsoft Visual C++ MFC ISAPI Extension Dll project named cut_url.
  2. When the ISAPI Extension Wizard starts, click Object Settings.
  3. Make sure that you only select the Generate a filter object check box, and then click Notifications.
  4. Select the High option for Notification priority for the filter, and then click Finish.
  5. Modify the Cut_url.cpp code to look like the following:
    #include "stdafx.h"
    #include "cut_url.h"
    #include "windows.h"
    #include "httpfilt.h"
    
    
    char g_searchStr1[] = "http://";
    char g_searchStr2[] = "https://";
    
    BOOL WINAPI TerminateFilter(DWORD dwFlags)
    {
        return TRUE;
    }
    
    BOOL WINAPI GetFilterVersion( HTTP_FILTER_VERSION *pVer )
    {
        if (pVer == NULL)
            return FALSE;
    
        pVer->dwFlags = SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_PREPROC_HEADERS;
    
      return TRUE;
    }
    
    /*
        Returns a pointer to a truncated URL or NULL.
    */
    
    char*
    CutToRelativePath( 
        char* urlStr
        )
    {
        char*   returnPtr    = NULL;
        char*   strPtr       = NULL;
        
        strPtr = strstr(_strlwr(urlStr),_strlwr(g_searchStr1));
        if ( strPtr == NULL
            || strPtr != urlStr
            || urlStr[(int)(strPtr - urlStr) + 7] == '\0' )
        {
            strPtr = strstr(_strlwr(urlStr),_strlwr(g_searchStr2));
            if ( strPtr == NULL
                || strPtr != urlStr
                || urlStr[(int)(strPtr - urlStr) + 8] == '\0' )
            {
                return NULL;
            }
            else
            {
                strPtr += 8;
            }
        }
        else
        {
            strPtr += 7;
        }
    
        returnPtr = strchr( strPtr, '/' );
    
        if ( returnPtr == NULL 
            || urlStr[(int)(returnPtr - urlStr) + 1] == '\0' )
            // Perform the following action if nothing is found or if nothing exists after '/'.
            return NULL;
    
        return returnPtr;
    }
    
    
    DWORD 
    ModifyURL( 
        HTTP_FILTER_CONTEXT *pfc, 
        VOID* pvData
        )
    {
        DWORD   dwRet;
        char    chBuffer[1024];
        char*   pszUrl = chBuffer;
        DWORD   dwUrlLength;
        HTTP_FILTER_PREPROC_HEADERS *pfph = NULL;
    
        pfph = (HTTP_FILTER_PREPROC_HEADERS *) pvData;
    
        dwUrlLength = sizeof(chBuffer);
        if ( pfph->GetHeader( pfc, "url", pszUrl, &dwUrlLength ) == FALSE )
        {
            if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
            {
                // Note: We do not have to free the memory.
                pszUrl = (char*)pfc->AllocMem( pfc, dwUrlLength, 0 );
                if ( pszUrl == NULL )
                {
                    SetLastError( ERROR_OUTOFMEMORY );
                    return SF_STATUS_REQ_ERROR;
                }
                if ( pfph->GetHeader( pfc, "url", pszUrl, &dwUrlLength ) == FALSE )
                {
                    return SF_STATUS_REQ_ERROR;
                }
            }
            else
            {
                return SF_STATUS_REQ_ERROR;
            }
        }
    
        // Perform a quick test for the possible presence of a full URL.
        if ( strchr( pszUrl, ':' ) != NULL )
        {
            pszUrl = CutToRelativePath( pszUrl);
        }
        if ( pszUrl != NULL )
        {
            dwRet = pfph->SetHeader(pfc, "url", pszUrl);
            if ( dwRet == 0 )
                return SF_STATUS_REQ_ERROR;
        }
        return SF_STATUS_REQ_NEXT_NOTIFICATION;
    }
    
    DWORD WINAPI 
    HttpFilterProc( 
        HTTP_FILTER_CONTEXT *pfc, 
        DWORD notificationType, 
        VOID *pvData
        )
    {
        if ( notificationType == SF_NOTIFY_PREPROC_HEADERS )
            return ModifyURL(pfc, pvData);
        
        return SF_STATUS_REQ_NEXT_NOTIFICATION;
    }
    
  6. Replace the content of the Cut_url.def file with the following code example.
    LIBRARY "cut_url"	
    EXPORTS
        HttpFilterProc
        GetFilterVersion
        TerminateFilter
  7. Build a release version of the project, and then copy the generated DLL to the Drive:\Windows\System32\Inetsrv folder

Install the new filter

Warning Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall your operating system. Microsoft cannot guarantee that these problems can be solved. Modify the registry at your own risk.

To install the new ISAPI filter, follow these steps:
  1. You must update the registry key that specifies where filters are located. To do this, follow these steps:
    1. Click Start, click Run, type regedit, and then click OK.
    2. Locate and then click the following registry key:

      HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/W3SVC/Parameters/

    3. Right-click Filter DLLs, and then click Modify.

      Note If the Filter DLLs registry key does not exist, right-click Parmeters, point to New, click String Value, type Filter DLLs, and then press ENTER.
    4. Type Drive:\Windows\System32\inetsrv, and then click OK.

      Note Drive represents the hard disk on which Windows is installed.
    5. Exit Registry editor.
  2. Click Start, click Run, type Inetmgr.exe, and then click OK.
  3. Open the Properties dialog box for the Web site on which you want to install the filter.
  4. Click ISAPI Filters, and then click Add.
  5. Type cut_url in the Filter name box, type Drive:\Windows\System32\inetsrv\cut_url.dll in the Executable box, and then click OK.
  6. Click OK in the Properties dialog box.

    The new ISAPI filter is installed.

    Note Click Move up to move the custom DLL higher in the order than the Aspnet_isapi.dll filter.

STATUS

Microsoft has confirmed that this is a problem in the Microsoft products that are listed in the "Applies to" section.

Modification Type:MajorLast Reviewed:8/22/2006
Keywords:kbtshoot kberrmsg kbprb KB909622 kbAudDeveloper kbAudITPRO