IHttpServer::GetFileInfo 方法

返回特定文件路径的 IHttpFileInfo 接口。

语法

virtual HRESULT GetFileInfo(  
   IN PCWSTR pszPhysicalPath,  
   IN HANDLE hUserToken,  
   IN PSID pSid,  
   IN PCWSTR pszVrPath,  
   IN HANDLE hVrToken,  
   IN BOOL fCache,  
   OUT IHttpFileInfo** ppFileInfo,  
   IN IHttpTraceContext* pHttpTraceContext = NULL  
) = 0;  

parameters

pszPhysicalPath
[IN]指向包含文件的物理路径的字符串的指针。

hUserToken
[IN]包含 HANDLE 模拟用户的令牌的 ;否则为 NULL。

pSid
[IN]指向包含模拟用户安全 ID 的 SID) (安全标识符的指针;否则为 NULL。

pszVrPath
[IN]指向字符串的指针,该字符串包含用于注册更改通知的虚拟路径;否则为 NULL。

hVrToken
[IN]一个 HANDLE ,其中包含用于注册更改通知的模拟令牌;否则为 NULL。

fCache
[IN] true 指示应缓存文件;否则为 false

ppFileInfo
[OUT]指向 IHttpFileInfo 接口的取消引用指针。

pHttpTraceContext
[IN]指向可选 IHttpTraceContext 接口的 指针。

返回值

HRESULT。 可能的值包括(但并不限于)下表中的项。

定义
S_OK 指示操作成功。
E_FAIL 指示对 的调用 GetFileInfo 是在模块主机终止时发出的。

备注

方法 IHttpServer::GetFileInfo 为特定路径创建 IHttpFileInfo 接口。 此方法不同于 IHttpContext::GetFileInfo 方法,后者返回 IHttpFileInfo IIS 在请求上下文中正在处理的文件的接口。

pszPhysicalPath创建接口需要 IHttpFileInfoppFileInfo 参数。 pszPhysicalPath参数指定文件的路径,参数ppFileInfo定义 IIS 将使用相应IHttpFileInfo接口填充的指针。

pszVrPathhVrToken 参数是可选的,如果不使用它们,则应将其设置为 NULL。 这些参数分别指定在模块注册更改通知时使用的虚拟路径和模拟令牌 (,例如,通过将 参数设置为 fCachetrue) 来请求缓存。

注意

其他配置设置可能会阻止 IIS 缓存文件,即使你为 参数指定 true 也是如此 fCache

hUserTokenpSid 参数也是可选的,如果不使用它们,则应将它们设置为 NULL。 这些参数分别指定模拟用户的令牌和 SID。 剩余的可选参数 pHttpTraceContext指定用于跟踪的 IHttpTraceContext 接口。

示例

下面的代码示例演示如何创建执行以下任务的 HTTP 模块:

  1. 注册 RQ_BEGIN_REQUEST 通知。

  2. 创建包含 OnBeginRequest 方法的 CHttpModule 类。 当客户端请求文件时, OnBeginRequest 方法将执行以下任务:

    1. 使用 IHttpContext::MapPath 方法将路径映射到相对 URL。

    2. IHttpFileInfo使用 方法创建文件路径的IHttpServer::GetFileInfo接口。

    3. 使用 IHttpFileInfo::GetETag 方法检索文件的实体标记。

    4. 使用 IHttpResponse::WriteEntityChunks 方法将实体标记返回到客户端。

  3. 从内存中删除 类, CHttpModule 然后退出。

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

// Create a pointer for the global server interface.
IHttpServer * g_pHttpServer = NULL;

// Create the module class.
class MyHttpModule : public CHttpModule
{
public:
    REQUEST_NOTIFICATION_STATUS
    OnBeginRequest(
        IN IHttpContext * pHttpContext,
        IN IHttpEventProvider * pProvider
    )
    {
        UNREFERENCED_PARAMETER( pProvider );

        HRESULT hr;

        PWSTR wszUrl = L"/example/default.asp";
        WCHAR wszPhysicalPath[1024] = L"";
        DWORD cbPhysicalPath = 1024;

        pHttpContext->MapPath(wszUrl,wszPhysicalPath,&cbPhysicalPath);

        if (NULL != wszPhysicalPath)
        {
            IHttpFileInfo * pHttpFileInfo;
            hr = g_pHttpServer->GetFileInfo(wszPhysicalPath,
                NULL,NULL,wszUrl,NULL,TRUE,&pHttpFileInfo);
            if (NULL != pHttpFileInfo)
            {
                // Create a buffer for the Etag.
                USHORT cchETag;
                // Retrieve the Etag.
                PCSTR pszETag = pHttpFileInfo->GetETag(&cchETag);
                //Test for an error.
                if (NULL != pszETag)
                {
                    // Clear the existing response.
                    pHttpContext->GetResponse()->Clear();
                    // Set the MIME type to plain text.
                    pHttpContext->GetResponse()->SetHeader(
                        HttpHeaderContentType,"text/plain",
                        (USHORT)strlen("text/plain"),TRUE);
                    // Return the Etag to the client.
                    WriteResponseMessage(pHttpContext,
                        "ETag: ",pszETag);
                    // End additional processing.
                    return RQ_NOTIFICATION_FINISH_REQUEST;
                }
            }
        }

        // Return processing to the pipeline.
        return RQ_NOTIFICATION_CONTINUE;
    }
private:

    // Create a utility method that inserts a name/value pair into the response.
    HRESULT WriteResponseMessage(
        IHttpContext * pHttpContext,
        PCSTR pszName,
        PCSTR pszValue
    )
    {
        // Create an HRESULT to receive return values from methods.
        HRESULT hr;
        
        // Create a data chunk. (Defined in the Http.h file.)
        HTTP_DATA_CHUNK dataChunk;
        // Set the chunk to a chunk in memory.
        dataChunk.DataChunkType = HttpDataChunkFromMemory;
        // Buffer for bytes written of data chunk.
        DWORD cbSent;

        // Set the chunk to the first buffer.
        dataChunk.FromMemory.pBuffer =
            (PVOID) pszName;
        // Set the chunk size to the first buffer size.
        dataChunk.FromMemory.BufferLength =
            (USHORT) strlen(pszName);
        // Insert the data chunk into the response.
        hr = pHttpContext->GetResponse()->WriteEntityChunks(
            &dataChunk,1,FALSE,TRUE,&cbSent);
        // Test for an error.
        if (FAILED(hr))
        {
            // Return the error status.
            return hr;
        }

        // Set the chunk to the second buffer.
        dataChunk.FromMemory.pBuffer =
            (PVOID) pszValue;
        // Set the chunk size to the second buffer size.
        dataChunk.FromMemory.BufferLength =
            (USHORT) strlen(pszValue);
        // Insert the data chunk into the response.
        hr = pHttpContext->GetResponse()->WriteEntityChunks(
            &dataChunk,1,FALSE,TRUE,&cbSent);
        // Test for an error.
        if (FAILED(hr))
        {
            // Return the error status.
            return hr;
        }

        // Return a success status.
        return S_OK;
    }
};

// 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 the factory 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 );

    // Store the pointer for the global server interface.
    g_pHttpServer = pGlobalInfo;

    // Set the request notifications and exit.
    return pModuleInfo->SetRequestNotifications(
        new MyHttpModuleFactory,
        RQ_BEGIN_REQUEST,
        0
    );
}

有关如何创建和部署本机 DLL 模块的详细信息,请参阅 演练:使用本机代码创建 Request-Level HTTP 模块

可以选择使用调用约定编译代码, __stdcall (/Gz) 而不是为每个函数显式声明调用约定。

要求

类型 说明
客户端 - Windows Vista 上的 IIS 7.0
- Windows 7 上的 IIS 7.5
- Windows 8 上的 IIS 8.0
- Windows 10 上的 IIS 10.0
服务器 - Windows Server 2008 上的 IIS 7.0
- Windows Server 2008 R2 上的 IIS 7.5
- Windows Server 2012 上的 IIS 8.0
- Windows Server 2012 R2 上的 IIS 8.5
- Windows Server 2016 上的 IIS 10.0
产品 - 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

另请参阅

IHttpServer 接口
IHttpContext::GetFileInfo 方法