例
项目目的:根据从客户端发送到服务器的请求发送的消息 ID 下载特定文件。文件将在服务器上创建并传输到客户端。
在这里,我没有共享整个代码,但显示了必要的内容,目的是演示迁移所需的更改。
进行更改。我参考了现有的 afxisapi.h,afxisapi.inl 和 HttpExt.h,它们随 VS2005 一起提供。
-
使用 EXTENSION_CONTROL_BLOCK 而不是 CHttpServerContext。EXTENSION_CONTROL_BLOCK 是 IIS 和 ISAPI 扩展用于交换信息的主要结构。它包含有关新请求的所有信息。
-
从 MFC 扩展类中删除 CHttpServer 类的依赖项。如果在项目中使用它,请删除 http 命令解析消息映射。在 VS2005 之后,正在删除像 ON_PARSE_COMMAND,BEGIN_PARSE_MAP,END_PARSE_MAP 和 DEFAULT_PARSE_COMMAND 这样的宏。
-
在你之前从 CHttpSever 类派生的 MFC 扩展类中实现你自己的 GetExtensionVersion,TerminateExtension 和 HttpExtensionProc 函数。这些功能
-
GetExtensionVersion()
GetExtensionVersion 函数是 IIS 中的第一个入口点函数。此功能允许你的 ISAPI 扩展通过 IIS 注册其版本信息。
BOOL CISAPIExtension::GetExtensionVersion( HSE_VERSION_INFO* pVer )
{
ISAPIVERIFY(
::LoadString( AfxGetResourceHandle(),
IDS_SERVER,
sz,
HSE_MAX_EXT_DLL_NAME_LEN) );
_tcscpy_s( pVer->lpszExtensionDesc, ( strlen( sz ) + 1U ), sz )
}
HttpExtensionProc()
:HttpExtensionProc 函数是 IIS 调用的 ISAPI 扩展的主入口点。它公开了 IIS 用于访问扩展程序公开的功能的方法。从扩展控制块中提取请求信息并进行处理。
DWORD CISAPIExtension::HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK pECB)
{
try
{
if (strcmp(pECB->lpszMethod, "POST") == 0)
{
if (0 < pECB->cbTotalBytes)
{
unsigned long ulSize = pECB->cbTotalBytes;
char* lpszContent = new char[ulSize + 1];
if (NULL != lpszContent)
{
memcpy(lpszContent, pECB->lpbData, ulSize);
lpszContent[ulSize] = '\0';
std::string message_id;
// Extract Message id from lpszContent using string operation.
if(strcmp(pECB->lpszQueryString, "DownloadFile") == 0)
{
DownloadFileFunction(pECB, message_id));
}
delete[] lpszContent;
lpszContent = NULL;
}
}
}
}
catch (...)
{
}
return HSE_STATUS_SUCCESS;
}
- 使用 EXTENSION_CONTROL_BLOCK 的 ServerSupportFunction 而不是 CHttepServerContext 的 TransmitFile 函数。以前,
TransmitFile()
用于文件传输。 - 在 ServerSupportFunction 中使用 HSE_REQ_TRANSMIT_FILE 进行文件传输。
- 在 HSE_TF_INFO 结构中拉出传输文件信息。
- 创建一个将在异步 I / O 完成时调用的回调函数(AsyncIOCompletionFunction)。
void WINAPI AsyncIOCompletionFunction(
EXTENSION_CONTROL_BLOCK * pECB,
PVOID pContext,
DWORD cbIO,
DWORD dwError)
{
HSE_CUSTOM_ERROR_INFO* pErrorInfo = (HSE_CUSTOM_ERROR_INFO*)pContext;
DWORD dwIOStatus = dwError == NO_ERROR ?
HSE_STATUS_SUCCESS :
HSE_STATUS_ERROR;
if (NULL != pErrorInfo)
{
//
// log HTTP status code
//
pECB->dwHttpStatusCode = atoi(pErrorInfo->pszStatus);
delete pErrorInfo;
pErrorInfo = NULL;
}
pECB->ServerSupportFunction(
pECB->ConnID,
HSE_REQ_DONE_WITH_SESSION,
&dwIOStatus,
(LPDWORD)NULL,
(LPDWORD)NULL);
}
DownloadFileFunction()
的代码片段
HSE_TF_INFO pHSEInfo;
pHSEInfo.hFile = hFile;
pHSEInfo.dwFlags = HSE_IO_ASYNC;
pHSEInfo.pHead = (PVOID) pvHeader;
pHSEInfo.HeadLength = dwHeaderLen;
pHSEInfo.pContext = 0;
pHSEInfo.pTail = 0;
pHSEInfo.TailLength = 0;
pHSEInfo.BytesToWrite = 0;
pHSEInfo.Offset = 0;
pHSEInfo.pfnHseIO = AsyncIOCompletionFunction; // callback function that will be called on asynchronous I/O completion
pHSEInfo.pszStatusCode = LPCSTR("200 OK");
bResult = m_pCtxt->ServerSupportFunction(m_pCtxt->ConnID, HSE_REQ_TRANSMIT_FILE, &pHSEInfo, 0, 0);