例
專案目的:根據從客戶端傳送到伺服器的請求傳送的訊息 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);