📄 httpisapi.cpp
字号:
CopyMemory(lpBuffer, pClient->m_Request.m_pRawRequest, dwSize);
((BYTE*) lpBuffer)[dwSize] = '\0';
*lpdwBufferSize = dwSize;
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
bSuccess = FALSE;
}
}
else if (strcmpi(lpszVariableName, "HTTP_VERSION") == 0)
{
char szVersion[10];
sprintf(szVersion, "%d.%d", HIWORD(pClient->m_Request.m_dwHttpVersion), LOWORD(pClient->m_Request.m_dwHttpVersion));
DWORD dwSize = strlen(szVersion) + 1;
if (*lpdwBufferSize >= dwSize)
{
strcpy((char*) lpBuffer, szVersion);
*lpdwBufferSize = dwSize;
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
bSuccess = FALSE;
}
}
else if (_strnicmp(lpszVariableName, "HTTP_", 5) == 0)
{
CString sKey(lpszVariableName);
sKey = sKey.Right(sKey.GetLength() - 5);
sKey.MakeUpper();
CString sValue;
if (pClient->m_Request.m_HeaderMap.Lookup(sKey, sValue))
{
char* szValue = T2A((LPTSTR) (LPCTSTR) sValue);
DWORD dwSize = strlen(szValue) + 1;
if (*lpdwBufferSize >= dwSize)
{
strcpy((char*) lpBuffer, szValue);
*lpdwBufferSize = dwSize;
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
bSuccess = FALSE;
}
}
else
{
SetLastError(ERROR_NO_DATA);
bSuccess = FALSE;
}
}
else
{
SetLastError(ERROR_INVALID_INDEX);
bSuccess = FALSE;
}
return bSuccess;
}
BOOL CHttpISAPI::ReadClient(HCONN hConn, LPVOID /*lpvBuffer*/, LPDWORD lpdwSize)
{
//nothing to read, so set the value
*lpdwSize = 0;
//Validate our parameters
CHttpClient* pClient = (CHttpClient*) hConn;
if (pClient == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//We do not support reading from the client, since we supply all of the data in the EXTENSION_CONTROL_BLOCK
SetLastError(ERROR_NO_DATA);
return FALSE;
}
BOOL CHttpISAPI::WriteClient(HCONN hConn, LPVOID Buffer, LPDWORD lpdwBytes, DWORD dwSync)
{
//Validate our parameters
CHttpClient* pClient = (CHttpClient*) hConn;
if ((pClient == NULL) || (dwSync == HSE_IO_ASYNC))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ASSERT(pClient->m_pServer);
CHttpServerSettings* pSettings = pClient->m_pServer->GetSettings();
ASSERT(pSettings);
//Assume the worst
BOOL bSuccess = FALSE;
try
{
#ifdef W3MFC_SSL_SUPPORT
pClient->m_Socket.SendWithRetry(Buffer, *lpdwBytes, pSettings->m_dwWritableTimeout, pClient->m_SSL);
#else
pClient->m_Socket.SendWithRetry(Buffer, *lpdwBytes, pSettings->m_dwWritableTimeout);
#endif
pClient->m_dwDataSentViaWriteClient += *lpdwBytes;
bSuccess = TRUE;
}
catch(CWSocketException* pEx)
{
//Report the error
CString sError;
sError.Format(_T("CHttpISAPI::WriteClient, Failed to send to socket, error:%d"), pEx->m_nError);
pClient->m_pServer->OnError(sError);
//Allow callers to see what the error was
SetLastError(pEx->m_nError);
pEx->Delete();
}
return bSuccess;
}
BOOL CHttpISAPI::ServerSupportFunction(HCONN hConn, DWORD dwHSERRequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType)
{
USES_CONVERSION;
//Validate our parameters
CHttpClient* pClient = (CHttpClient*) hConn;
if (pClient == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ASSERT(pClient->m_pServer);
CHttpServerSettings* pSettings = pClient->m_pServer->GetSettings();
ASSERT(pSettings);
//Assume the best
BOOL bSuccess = TRUE;
switch (dwHSERRequest)
{
case HSE_REQ_CLOSE_CONNECTION:
{
//We support this function but do a NOOP since
//the connection will be closed when HttpExtensionProc
//returns normally
break;
}
case HSE_REQ_GET_IMPERSONATION_TOKEN:
{
if (pClient->m_Request.m_hImpersonation)
*((HANDLE*) lpvBuffer) = pClient->m_Request.m_hImpersonation;
else
{
SetLastError(ERROR_NO_DATA);
bSuccess = FALSE;
}
break;
}
case HSE_REQ_GET_SSPI_INFO:
{
#ifndef W3MFC_NO_SSPI_SUPPORT
CopyMemory(((CtxtHandle*) lpvBuffer), &pClient->m_Request.m_hImpersonation, sizeof(CtxtHandle));
CopyMemory(((CredHandle*) lpdwDataType), pClient->m_pServer->GetCredentialHandle(), sizeof(CredHandle));
#else
SetLastError(ERROR_NO_DATA);
bSuccess = FALSE;
#endif
break;
}
case HSE_REQ_IS_KEEP_CONN:
{
*((BOOL*) lpvBuffer) = pClient->m_bResponseKeepAlive;
break;
}
case HSE_REQ_MAP_URL_TO_PATH:
{
LPSTR pszURL = (LPSTR) lpvBuffer;
HSE_URL_MAPEX_INFO* pUMI = (HSE_URL_MAPEX_INFO*) lpdwDataType;
pUMI->dwFlags = 0;
CString sURL(pszURL);
BOOL bDirectory = FALSE;
CHttpDirectory* pDirectory = NULL;
CString sLocalFile;
CString sPathInfo;
if (pClient->MapURLToLocalFilename(sURL, sLocalFile, sPathInfo, bDirectory, pDirectory, pUMI->cchMatchingURL, pUMI->cchMatchingPath))
{
LPSTR pszLocalFile = T2A((LPTSTR) (LPCTSTR) sLocalFile);
DWORD dwSize = strlen(pszLocalFile) + 1;
if (*lpdwSize >= dwSize)
{
strcpy(pszURL, pszLocalFile);
if (!pDirectory->GetScript())
pUMI->dwFlags |= HSE_URL_FLAGS_READ;
else
{
pUMI->dwFlags |= HSE_URL_FLAGS_EXECUTE;
pUMI->dwFlags |= HSE_URL_FLAGS_SCRIPT;
}
if (pDirectory->GetWritable())
pUMI->dwFlags |= HSE_URL_FLAGS_WRITE;
#ifdef W3MFC_SSL_SUPPORT
if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
pUMI->dwFlags |= HSE_URL_FLAGS_SSL;
#endif
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
bSuccess = FALSE;
}
}
else
{
SetLastError(ERROR_NO_DATA);
bSuccess = FALSE;
}
break;
}
case HSE_REQ_MAP_URL_TO_PATH_EX:
{
LPSTR pszURL = (LPSTR) lpvBuffer;
HSE_URL_MAPEX_INFO* pUMI = (HSE_URL_MAPEX_INFO*) lpdwDataType;
pUMI->dwFlags = 0;
CString sURL(pszURL);
BOOL bDirectory = FALSE;
CHttpDirectory* pDirectory = NULL;
CString sLocalFile;
CString sPathInfo;
if (pClient->MapURLToLocalFilename(sURL, sLocalFile, sPathInfo, bDirectory, pDirectory, pUMI->cchMatchingURL, pUMI->cchMatchingPath))
{
LPSTR pszLocalFile = T2A((LPTSTR) (LPCTSTR) sLocalFile);
strcpy(pUMI->lpszPath, pszLocalFile);
if (!pDirectory->GetScript())
pUMI->dwFlags |= HSE_URL_FLAGS_READ;
else
{
pUMI->dwFlags |= HSE_URL_FLAGS_EXECUTE;
pUMI->dwFlags |= HSE_URL_FLAGS_SCRIPT;
}
if (pDirectory->GetWritable())
pUMI->dwFlags |= HSE_URL_FLAGS_WRITE;
#ifdef W3MFC_SSL_SUPPORT
if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
pUMI->dwFlags |= HSE_URL_FLAGS_SSL;
#endif
}
else
{
SetLastError(ERROR_NO_DATA);
bSuccess = FALSE;
}
break;
}
case HSE_REQ_SEND_URL:
case HSE_REQ_SEND_URL_REDIRECT_RESP:
{
LPSTR pszURL = (LPSTR) lpvBuffer;
pClient->ReturnRedirectMessage(pszURL);
pClient->m_nHttpStatusCodeSent = 302;
break;
}
case HSE_REQ_SEND_RESPONSE_HEADER:
{
LPSTR pszStatusString = (LPSTR) lpvBuffer;
LPSTR pszExtraHeaders = (LPSTR) lpdwDataType;
CHttpResponseHeader responseHdr;
if (pszStatusString && strlen(pszStatusString))
{
responseHdr.AddStatus(pszStatusString);
pClient->m_nHttpStatusCodeSent = atoi(pszStatusString);
}
else
{
responseHdr.AddStatusCode(200);
pClient->m_nHttpStatusCodeSent = 200;
}
SYSTEMTIME stCurTime;
::GetSystemTime(&stCurTime);
responseHdr.AddDate(stCurTime);
responseHdr.AddServer(pSettings->m_sServerName);
responseHdr.AddW3MfcAllowFields(pSettings->m_bAllowDeleteRequest);
if (pszExtraHeaders && strlen(pszExtraHeaders))
responseHdr.AddExtraHeaders(pszExtraHeaders);
pClient->m_bResponseKeepAlive = FALSE;
responseHdr.SetAddEntitySeparator(FALSE);
//Send the header
pClient->TransmitBuffer(pClient->m_Socket, responseHdr, NULL, 0, pSettings->m_dwWritableTimeout);
break;
}
case HSE_REQ_SEND_RESPONSE_HEADER_EX:
{
HSE_SEND_HEADER_EX_INFO* pHeader = (HSE_SEND_HEADER_EX_INFO*) lpvBuffer;
CHttpResponseHeader responseHdr;
if (pHeader->pszStatus && strlen(pHeader->pszStatus))
{
responseHdr.AddStatus(pHeader->pszStatus);
pClient->m_nHttpStatusCodeSent = atoi(pHeader->pszStatus);
}
else
{
responseHdr.AddStatusCode(200);
pClient->m_nHttpStatusCodeSent = 200;
}
SYSTEMTIME stCurTime;
::GetSystemTime(&stCurTime);
responseHdr.AddDate(stCurTime);
responseHdr.AddServer(pSettings->m_sServerName);
responseHdr.AddW3MfcAllowFields(pSettings->m_bAllowDeleteRequest);
if (pHeader->pszHeader && strlen(pHeader->pszHeader))
responseHdr.AddExtraHeaders(pHeader->pszHeader);
if (pHeader->fKeepConn)
responseHdr.AddKeepAlive();
pClient->m_bResponseKeepAlive = pHeader->fKeepConn;
responseHdr.SetAddEntitySeparator(FALSE);
//Send the header
pClient->TransmitBuffer(pClient->m_Socket, responseHdr, NULL, 0, pSettings->m_dwWritableTimeout);
break;
}
case HSE_REQ_TRANSMIT_FILE:
{
#ifdef W3MFC_SSL_SUPPORT
BOOL bAvailable = (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE);
#else
BOOL bAvailable = TRUE;
#endif
if (bAvailable)
{
CHttpResponseHeader responseHdr;
SYSTEMTIME stCurTime;
::GetSystemTime(&stCurTime);
responseHdr.AddDate(stCurTime);
responseHdr.AddServer(pSettings->m_sServerName);
responseHdr.AddW3MfcAllowFields(pSettings->m_bAllowDeleteRequest);
pClient->m_bResponseKeepAlive = FALSE;
HSE_TF_INFO* pInfo = (HSE_TF_INFO*) lpvBuffer;
bSuccess = pClient->TransmitFile(pClient->m_Socket, responseHdr, pInfo);
}
else
{
SetLastError(ERROR_INVALID_INDEX);
bSuccess = FALSE;
}
break;
}
default:
{
//Report the error
CString sError;
sError.Format(_T("CHttpISAPI::ServerSupportFunction, An invalid HSERequest value was specified %s, HSERequest:%d"), pClient->m_Request.m_sURL, dwHSERRequest);
pClient->m_pServer->OnError(sError);
SetLastError(ERROR_INVALID_INDEX);
bSuccess = FALSE;
break;
}
}
return bSuccess;
}
void CHttpISAPI::ReportHttpExtensionProcError(CHttpClient* pClient, CHttpISAPIExtension& extension, DWORD dwError)
{
//Validate our parameters
ASSERT(pClient);
ASSERT(pClient->m_pServer);
//Report the error
CString sError;
sError.Format(_T("CHttpISAPI::ReportHTTPExtensionProcError, Failed calling the function HttpExtensionProc in the ISAPI extension %s, error:%d"), extension.m_sPath, dwError);
pClient->m_pServer->OnError(sError);
}
BOOL CHttpISAPI::CallHttpExtensionProc(CHttpClient* pClient, CHttpISAPIExtension& extension)
{
USES_CONVERSION;
//Validate our parameters
ASSERT(extension.m_lpHttpExtensionProc);
ASSERT(pClient);
ASSERT(pClient->m_pServer);
//Assume the worst
BOOL bSuccess = FALSE;
__try
{
//Setup the structure
EXTENSION_CONTROL_BLOCK ecb;
ecb.cbSize = sizeof(EXTENSION_CONTROL_BLOCK);
ecb.dwVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
ecb.ConnID = (HCONN) pClient;
ecb.dwHttpStatusCode = 200;
strcpy(ecb.lpszLogData, "");
ecb.lpszMethod = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sVerb);
ecb.lpszQueryString = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRawExtra);
ecb.lpszPathInfo = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sPathInfo);
ecb.lpszPathTranslated = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sLocalFile);
ecb.cbTotalBytes = pClient->m_Request.m_dwRawEntitySize;
ecb.cbAvailable = ecb.cbTotalBytes;
ecb.lpbData = pClient->m_Request.m_pRawEntity;
ecb.lpszContentType = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sContentType);
ecb.GetServerVariable = GetServerVariable;
ecb.WriteClient = WriteClient;
ecb.ReadClient = ReadClient;
ecb.ServerSupportFunction = ServerSupportFunction;
//Finally call the function with the structure
DWORD dwSuccess = extension.m_lpHttpExtensionProc(&ecb);
bSuccess = (dwSuccess == HSE_STATUS_SUCCESS);
if (dwSuccess == HSE_STATUS_SUCCESS_AND_KEEP_CONN)
{
pClient->m_bResponseKeepAlive = TRUE;
bSuccess = TRUE;
}
if (!bSuccess)
ReportHttpExtensionProcError(pClient, extension, dwSuccess);
}
__except(1)
{
bSuccess = FALSE;
}
return bSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -