Freigeben über


IHttpContext::CloneContext-Methode

Erstellt einen Klon des aktuellen Anforderungskontexts.

Syntax

virtual HRESULT CloneContext(  
   IN DWORD dwCloneFlags,  
   OUT IHttpContext** ppHttpContext  
) = 0;  

Parameter

dwCloneFlags
[IN] Eine DWORD , die die Klonflags enthält.

ppHttpContext
[OUT] Ein dereferenced-Zeiger auf einen IHttpContext.

Rückgabewert

HRESULT. Mögliches Werte (aber nicht die Einzigen) sind die in der folgenden Tabelle.

Wert BESCHREIBUNG
S_OK Gibt an, dass der Vorgang erfolgreich war.
ERROR_INVALID_PARAMETER Gibt an, dass ein angegebener Parameter ungültig war.
ERROR_NOT_ENOUGH_MEMORY Gibt an, dass nicht genügend Arbeitsspeicher zum Ausführen des Vorgangs vorhanden ist.

Bemerkungen

Die CloneContext -Methode erstellt einen Klon des aktuellen Anforderungskontexts. Sie können das Klonverhalten steuern, indem Sie die entsprechenden Flags im dwCloneFlags Parameter angeben. In der folgenden Tabelle sind die möglichen Werte für diese Flags aufgeführt.

Wert BESCHREIBUNG
CLONE_FLAG_BASICS Klonen Sie die URL, die Abfragezeichenfolge und die HTTP-Methode.
CLONE_FLAG_HEADERS Klonen Sie die Anforderungsheader.
CLONE_FLAG_ENTITY Klonen Sie den Entitätstext.
CLONE_FLAG_NO_PRECONDITION Fügen Sie keine "range"- und "if-"-Header für die Anforderung ein.
CLONE_FLAG_NO_DAV Fügen Sie keine WebDAV-Header für die Anforderung ein.

Nachdem Sie einen geklonten Kontext erstellt haben, können Sie den Klon wie den übergeordneten Kontext verwenden. Wenn Sie beispielsweise eine untergeordnete Anforderung für eine andere URL als die übergeordnete URL ausführen möchten, verwenden Sie die IHttpRequest::SetUrl-Methode für den geklonten Kontext, um die URL des geklonten Kontexts zu ändern, bevor Sie die IHttpContext::ExecuteRequest-Methode des übergeordneten Kontexts aufrufen.

Beispiel

Im folgenden Codebeispiel wird veranschaulicht, wie Sie ein HTTP-Modul erstellen, das die folgenden Aufgaben ausführt:

  1. Das Modul registriert sich für die RQ_MAP_PATH Benachrichtigung.

  2. Das Modul erstellt eine CHttpModule-Klasse , die die Methoden OnMapPath und OnAsyncCompletion enthält.

  3. Wenn ein Webclient eine URL anfordert, ruft IIS die -Methode des Moduls auf OnMapPath . Diese Methode führt die folgenden Tasks aus:

    1. Testet, ob die URL für die aktuelle Anforderung einen nachgestellten Schrägstrich aufweist oder mit /default.aspx endet. Wenn die URL mit einem element endet, verwendet das Modul die CloneContext -Methode, um einen Klon der aktuellen Anforderung zu erstellen.

    2. Ruft die Methode des Klons IHttpRequest::SetUrl auf, um die URL für den Klon auf /example/default.aspx festzulegen.

    3. Ruft die IHttpContext::ExecuteRequest -Methode auf, um die untergeordnete Anforderung auszuführen.

    4. Tests auf asynchrone Vervollständigung. Wenn die asynchrone Vervollständigung aussteht, gibt das Modul die Verarbeitung an die integrierte Anforderungsverarbeitungspipeline zurück. Andernfalls gibt das Modul den geklonten Kontext frei.

  4. Wenn eine asynchrone Vervollständigung erforderlich ist, ruft IIS die Methode des Moduls auf OnAsyncCompletion . Diese Methode gibt den geklonten Kontext frei.

  5. Das Modul entfernt die CHttpModule -Klasse aus dem Arbeitsspeicher und wird dann beendet.

#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>

// Create the module class.
class MyHttpModule : public CHttpModule
{

private:

    // Create a pointer for a child request.
    IHttpContext * m_pChildRequestContext;

public:

    MyHttpModule(void)
    {
        m_pChildRequestContext = NULL;
    }

    REQUEST_NOTIFICATION_STATUS
    OnMapPath(
        IN IHttpContext * pHttpContext,
        IN IMapPathProvider * pProvider
    )
    {
        UNREFERENCED_PARAMETER( pProvider );

        HRESULT hr;
        BOOL fCompletionExpected;

        // Retrieve a pointer to the URL.
        PCWSTR pwszUrl = pProvider->GetUrl();

        // Only process requests for the root.
        if (0 == wcscmp(pwszUrl,L"/") || 0 == wcscmp(pwszUrl,L"/default.aspx"))
        {            
            // Clone the current context.
            hr = pHttpContext->CloneContext(
                CLONE_FLAG_BASICS, &m_pChildRequestContext );
            
            // Test for a failure.
            if (FAILED(hr))
            {
                goto Failure;
            }
            
            // Test for an error.
            if ( NULL != m_pChildRequestContext )
            {
                // Set the URL for the child request.
                hr = m_pChildRequestContext->GetRequest()->SetUrl(
                    "/example/default.aspx",
                    (DWORD)strlen("/example/default.aspx"),false);
            
                // Test for a failure.
                if (FAILED(hr))
                {
                    goto Failure;
                }
                
                // Execute the child request.
                hr = pHttpContext->ExecuteRequest(
                    TRUE, m_pChildRequestContext,
                    0, NULL, &fCompletionExpected );
                
                // Test for a failure.
                if (FAILED(hr))
                {
                    goto Failure;
                }
                
                // Test for pending asynchronous operations.
                if (fCompletionExpected)
                {
                    return RQ_NOTIFICATION_PENDING;
                }

            }

 Failure:
            // Test for a child request.
            if (NULL != m_pChildRequestContext)
            {
                // Release the child request.
                m_pChildRequestContext->ReleaseClonedContext();
                m_pChildRequestContext = NULL;
            }
        }
        
        // Return processing to the pipeline.
        return RQ_NOTIFICATION_CONTINUE;
    }
    
    REQUEST_NOTIFICATION_STATUS
        OnAsyncCompletion(
        IN IHttpContext * pHttpContext,
        IN DWORD dwNotification,
        IN BOOL fPostNotification,
        IN IHttpEventProvider * pProvider,
        IN IHttpCompletionInfo * pCompletionInfo
        )
    {
        // Test for a child request.
        if (NULL != m_pChildRequestContext)
        {
            // Release the child request.
            m_pChildRequestContext->ReleaseClonedContext();
            m_pChildRequestContext = NULL;
        }
        // Return processing to the pipeline.
        return RQ_NOTIFICATION_CONTINUE;
    }

};

// Create the module's class factory.
class MyHttpModuleFactory : public IHttpModuleFactory
{
public:
    HRESULT
    GetHttpModule(
        OUT CHttpModule ** ppModule, 
        IN IModuleAllocator * pAllocator
    )
    {
        UNREFERENCED_PARAMETER( pAllocator );

        // Create a new instance.
        MyHttpModule * pModule = new MyHttpModule;

        // Test for an error.
        if (!pModule)
        {
            // Return an error if we cannot create the instance.
            return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
        }
        else
        {
            // Return a pointer to the module.
            *ppModule = pModule;
            pModule = NULL;
            // Return a success status.
            return S_OK;
        }            
    }

    void Terminate()
    {
        // Remove the class from memory.
        delete this;
    }
};

// Create the module's exported registration function.
HRESULT
__stdcall
RegisterModule(
    DWORD dwServerVersion,
    IHttpModuleRegistrationInfo * pModuleInfo,
    IHttpServer * pGlobalInfo
)
{
    UNREFERENCED_PARAMETER( dwServerVersion );
    UNREFERENCED_PARAMETER( pGlobalInfo );

    return pModuleInfo->SetRequestNotifications(
        new MyHttpModuleFactory,
        RQ_MAP_PATH,
        0
    );
}

Ihr Modul muss die Funktion RegisterModule exportieren. Sie können diese Funktion exportieren, indem Sie eine Moduldefinitionsdatei (.def) für Ihr Projekt erstellen, oder Sie können das Modul mithilfe des /EXPORT:RegisterModule Switches kompilieren. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Erstellen eines Request-Level HTTP-Moduls mithilfe von nativem Code.

Sie können den Code optional kompilieren, indem Sie die __stdcall (/Gz) aufrufende Konvention verwenden, anstatt die aufrufende Konvention für jede Funktion explizit zu deklarieren.

Anforderungen

type BESCHREIBUNG
Client – IIS 7.0 unter Windows Vista
– IIS 7.5 unter Windows 7
– IIS 8.0 unter Windows 8
– IIS 10.0 auf Windows 10
Server – IIS 7.0 unter Windows Server 2008
– IIS 7.5 unter Windows Server 2008 R2
– IIS 8.0 unter Windows Server 2012
– IIS 8.5 unter Windows Server 2012 R2
– IIS 10.0 auf Windows Server 2016
Produkt – IIS 7.0, IIS 7.5, IIS 8.0, IIS 8.5, IIS 10.0
- IIS Express 7.5, IIS Express 8.0, IIS Express 10.0
Header Httpserv.h

Weitere Informationen

IHttpContext-Schnittstelle
IHttpContext::ExecuteRequest-Methode
IHttpContext::ReleaseClonedContext-Methode