HttpISAPI.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:37k
源码类别:

CA认证

开发平台:

Visual C++

  1. /*
  2. Module : HttpISAPI.cpp
  3. Purpose: Implementation for the CHttpISAPI class
  4. Created: PJN / 21-02-2003
  5. History: PJN / 22-02-2004 1. Fixed a memory leak in CHttpISAPI::CachedLoad. Thanks to "mori" for
  6.                           reporting and suggesting the fix for this bug.
  7. Copyright (c) 2003 - 2005 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)
  8. All rights reserved.
  9. Copyright / Usage Details:
  10. You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
  11. when your product is released in binary form. You are allowed to modify the source code in any way you want 
  12. except you cannot modify the copyright details at the top of each module. If you want to distribute source 
  13. code with your application, then you are only allowed to distribute versions released by the author. This is 
  14. to maintain a single distribution point for the source code. 
  15. */
  16. //////////////// Includes ////////////////////////////////////////////
  17. #include "stdafx.h"
  18. #include "HttpISAPI.h"
  19. #include "HttpClient.h"
  20. //////////////// Macros / Defines ////////////////////////////////////
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #ifndef HSE_REQ_CLOSE_CONNECTION
  27. #define HSE_REQ_CLOSE_CONNECTION                 (HSE_REQ_END_RESERVED+17)
  28. #endif
  29. //////////////// Implementation //////////////////////////////////////
  30. CHttpISAPIExtension::CHttpISAPIExtension()
  31. {
  32.   m_hDLL = NULL;
  33.   m_lpGetExtensionVersion = NULL;
  34.   m_lpHttpExtensionProc = NULL;
  35.   m_lpTerminateExtension = NULL;
  36. }
  37. CHttpISAPIExtension::~CHttpISAPIExtension()
  38. {
  39.   if (m_hDLL)
  40.   {
  41.     //Call the terminate function (if it exists)
  42.     if (m_lpTerminateExtension)
  43.       CallTerminateExtension();
  44.       
  45.     //Finally free up the library
  46.     FreeLibrary(m_hDLL);
  47.   }
  48. }
  49. BOOL CHttpISAPIExtension::CallGetExtensionVersion(HSE_VERSION_INFO* phseVerInfo)
  50. {
  51.   //Validate our parameters
  52.   ASSERT(m_lpGetExtensionVersion);
  53.   //Assume the worst
  54.   BOOL bSuccess = FALSE;
  55.   __try
  56.   {
  57.     bSuccess = m_lpGetExtensionVersion(phseVerInfo);
  58.   }
  59.   __except(1)
  60.   {
  61.     bSuccess = FALSE;
  62.   }
  63.   return bSuccess;
  64. }
  65. BOOL CHttpISAPIExtension::CallTerminateExtension()
  66. {
  67.   ASSERT(m_lpTerminateExtension);
  68.   //Assume the worst
  69.   BOOL bSuccess = FALSE;
  70.   __try
  71.   {
  72.     bSuccess = m_lpTerminateExtension(HSE_TERM_MUST_UNLOAD);
  73.   }
  74.   __except(1)
  75.   {
  76.     bSuccess = FALSE;
  77.   }
  78.   return bSuccess;
  79. }
  80. CHttpISAPI::CHttpISAPI(int nISAPIHashTableSize) : m_mapExtensions(nISAPIHashTableSize)
  81. {
  82.   m_pServer = NULL;
  83. }
  84. CHttpISAPI::~CHttpISAPI()
  85. {
  86.   FreeMapEntries();
  87. }
  88. void CHttpISAPI::SetServer(CHttpServer* pServer)
  89. {
  90.   m_pServer = pServer;
  91. }
  92. void CHttpISAPI::FreeMapEntries()
  93. {
  94.   //Prevent the hash table from being manipulated
  95.   //by multiple threads at the one time
  96.   CSingleLock sl(&m_CS, TRUE);
  97.   //Remove all the entries in the hash table
  98.   for (POSITION pos = m_mapExtensions.GetStartPosition(); pos != NULL; )
  99.   {
  100.     CHttpISAPIExtension* pEntry = NULL;
  101.     CString sKey;
  102.     m_mapExtensions.GetNextAssoc(pos, sKey, (void*&) pEntry);
  103.     if (pEntry)
  104.       delete pEntry;
  105.   }
  106.   m_mapExtensions.RemoveAll();
  107. }
  108. BOOL CHttpISAPI::UncachedLoad(const CString& sPath, CHttpISAPIExtension& extension)
  109. {
  110.   //Validate our parameters
  111.   ASSERT(m_pServer);
  112.   //What will be the return value
  113.   BOOL bSuccess = FALSE;
  114.  
  115.   //Load up the DLL
  116.   ASSERT(extension.m_hDLL == NULL);
  117.   extension.m_sPath = sPath;
  118.   extension.m_hDLL = LoadLibraryEx(sPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  119.   if (extension.m_hDLL)
  120.   {
  121.     //Get the "GetExtensionVersion" function
  122.     extension.m_lpGetExtensionVersion = (CHttpISAPIExtension::LPGETEXTENSIONVERSION) GetProcAddress(extension.m_hDLL, "GetExtensionVersion");
  123.     if (extension.m_lpGetExtensionVersion == NULL)    
  124.     {
  125.       //Report the error that we could not find the function
  126.       CString sError;
  127.       sError.Format(_T("CHttpISAPI::UncachedLoad, Could not find entry point GetExtensionVersion in dll %s"), sPath);
  128.       m_pServer->OnError(sError);
  129.     }
  130.     //Get the HttpExtensionProc function
  131.     extension.m_lpHttpExtensionProc = (CHttpISAPIExtension::LPHTTPEXTENSIONPROC) GetProcAddress(extension.m_hDLL, "HttpExtensionProc");
  132.     if (extension.m_lpHttpExtensionProc == NULL)    
  133.     {
  134.       //Report the error that we could not find the function
  135.       CString sError;
  136.       sError.Format(_T("CHttpISAPI::UncachedLoad, Could not find entry point HttpExtensionProc in dll %s"), sPath);
  137.       m_pServer->OnError(sError);
  138.     }
  139.     if (extension.m_lpGetExtensionVersion && extension.m_lpHttpExtensionProc)
  140.     {
  141.       //Now find the optional "TerminateExtension" function (if initialisation succeeded)
  142.       extension.m_lpTerminateExtension = (CHttpISAPIExtension::LPTERMINATEEXTENSION) GetProcAddress(extension.m_hDLL, "TerminateExtension");
  143.       //Also call the GetExtensionVersion function
  144.       HSE_VERSION_INFO hseVerInfo;
  145.       CString sError;
  146.       bSuccess = extension.CallGetExtensionVersion(&hseVerInfo);
  147.       if (!bSuccess)
  148.       {
  149.         //Report the error that we could not call the GetExtensionVersion function
  150.         sError.Format(_T("CHttpISAPI::UncachedLoad, Failed in call to GetExtensionVersion in dll %s, error:%d"), sPath, GetLastError());
  151.         m_pServer->OnError(sError);
  152.       }
  153.     }
  154.   }
  155.   else
  156.   {
  157.     //Report the error that we could not find the function
  158.     DWORD dwError = GetLastError();
  159.     CString sError;
  160.     sError.Format(_T("CHttpISAPI::UncachedLoad, Could not load the dll %s, error:%d"), sPath, dwError);
  161.     m_pServer->OnError(sError);
  162.   }
  163.   return bSuccess;
  164. }
  165. CHttpISAPIExtension* CHttpISAPI::CachedLoad(const CString& sPath)
  166. {
  167.   //Validate our parameters
  168.   ASSERT(m_pServer);
  169.   CHttpServerSettings* pSettings = m_pServer->GetSettings();
  170.   ASSERT(pSettings);
  171.   ASSERT(pSettings->m_bCacheISAPI);
  172.   //Look up in the hash table case insensitively
  173.   CString sKey(sPath);
  174.   sKey.MakeUpper(); 
  175.   //What will be the return value
  176.   CHttpISAPIExtension* pExtension = NULL;
  177.   //Prevent the hash table from being manipulated
  178.   //by multiple threads at the one time
  179.   CSingleLock sl(&m_CS, TRUE);
  180.   //try looking it up in the cache first
  181.   if (!m_mapExtensions.Lookup(sKey, (void*&) pExtension))
  182.   {
  183.     //Only created if not found in hash
  184.     pExtension = new CHttpISAPIExtension;
  185.  
  186.     //Call the other Load method to do most of the work
  187.     if (!UncachedLoad(sPath, *pExtension))
  188.     {
  189.       delete pExtension;
  190.       pExtension = NULL;
  191.     }
  192.     else
  193.     {
  194.       //Add it to the hash if caching is enabled
  195.       m_mapExtensions.SetAt(sKey, pExtension);
  196.     }
  197.   }
  198.   return pExtension;
  199. }
  200. BOOL CHttpISAPI::GetServerVariable(HCONN hConn, LPSTR lpszVariableName, void* lpBuffer, DWORD* lpdwBufferSize)
  201. {
  202.   USES_CONVERSION;
  203.   //Validate our parameters
  204.   CHttpClient* pClient = (CHttpClient*) hConn;
  205.   if (pClient == NULL)
  206.   {
  207.     SetLastError(ERROR_INVALID_PARAMETER);
  208.     return FALSE;
  209.   }  
  210.   ASSERT(pClient->m_pServer);
  211.   CHttpServerSettings* pSettings = pClient->m_pServer->GetSettings();
  212.   ASSERT(pSettings);
  213.   //Assume the best
  214.   BOOL bSuccess = TRUE;
  215.   if (strcmpi(lpszVariableName, "SERVER_PORT") == 0)
  216.   {
  217.     char szPort[10];
  218.     sprintf(szPort, "%d", pSettings->m_nPort);
  219.     DWORD dwSize = strlen(szPort) + 1;
  220.     if (*lpdwBufferSize >= dwSize)
  221.     {
  222.       strcpy((char*) lpBuffer, szPort);
  223.       *lpdwBufferSize = dwSize;
  224.     }
  225.     else
  226.     { 
  227.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  228.       bSuccess = FALSE;
  229.     }
  230.   }
  231.   else if (strcmpi(lpszVariableName, "SERVER_PORT_SECURE") == 0)
  232.   {
  233.   #ifdef W3MFC_SSL_SUPPORT
  234.     if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  235.     {
  236.       char szSecure[10];
  237.       sprintf(szSecure, "%d", pSettings->m_nPort);
  238.       DWORD dwSize = strlen(szSecure) + 1;
  239.       if (*lpdwBufferSize >= dwSize)
  240.       {
  241.         strcpy((char*) lpBuffer, szSecure);
  242.         *lpdwBufferSize = dwSize;
  243.       }
  244.       else
  245.       { 
  246.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  247.         bSuccess = FALSE;
  248.       }
  249.     }
  250.     else
  251.     {
  252.       SetLastError(ERROR_NO_DATA);
  253.       bSuccess = FALSE;
  254.     }
  255.   #else
  256.     SetLastError(ERROR_NO_DATA);
  257.     bSuccess = FALSE;
  258.   #endif
  259.   }
  260.   else if (strcmpi(lpszVariableName, "SERVER_PROTOCOL") == 0)
  261.   {
  262.     char szProtocol[10];
  263.   #ifdef W3MFC_SSL_SUPPORT
  264.     if (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE)
  265.       strcpy(szProtocol, "HTTP/1.0");
  266.     else
  267.       strcpy(szProtocol, "HTTPS/1.0");
  268.   #else
  269.     strcpy(szProtocol, "HTTP/1.0");
  270.   #endif
  271.     DWORD dwSize = strlen(szProtocol) + 1;
  272.     if (*lpdwBufferSize >= dwSize)
  273.     {
  274.       strcpy((char*) lpBuffer, szProtocol);
  275.       *lpdwBufferSize = dwSize;
  276.     }
  277.     else
  278.     { 
  279.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  280.       bSuccess = FALSE;
  281.     }
  282.   }
  283.   else if (strcmpi(lpszVariableName, "SERVER_SOFTWARE") == 0)
  284.   {
  285.     char* szSoftware = T2A((LPTSTR) (LPCTSTR) pSettings->m_sServerName);
  286.     DWORD dwSize = strlen(szSoftware) + 1;
  287.     if (*lpdwBufferSize >= dwSize)
  288.     {
  289.       strcpy((char*) lpBuffer, szSoftware);
  290.       *lpdwBufferSize = dwSize;
  291.     }
  292.     else
  293.     { 
  294.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  295.       bSuccess = FALSE;
  296.     }
  297.   }
  298.   else if (strcmpi(lpszVariableName, "URL") == 0)
  299.   {
  300.     char* szURL = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sURL);
  301.     DWORD dwSize = strlen(szURL) + 1;
  302.     if (*lpdwBufferSize >= dwSize)
  303.     {
  304.       strcpy((char*) lpBuffer, szURL);
  305.       *lpdwBufferSize = dwSize;
  306.     }
  307.     else
  308.     { 
  309.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  310.       bSuccess = FALSE;
  311.     }
  312.   }
  313.   else if (strcmpi(lpszVariableName, "QUERY_STRING") == 0)
  314.   {
  315.     char* szQueryString = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRawExtra);
  316.     DWORD dwSize = strlen(szQueryString) + 1;
  317.     if (*lpdwBufferSize >= dwSize)
  318.     {
  319.       strcpy((char*) lpBuffer, szQueryString);
  320.       *lpdwBufferSize = dwSize;
  321.     }
  322.     else
  323.     { 
  324.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  325.       bSuccess = FALSE;
  326.     }
  327.   }
  328.   else if (strcmpi(lpszVariableName, "PATH_INFO") == 0)
  329.   {
  330.     char* szPathInfo = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sPathInfo);
  331.     DWORD dwSize = strlen(szPathInfo) + 1;
  332.     if (*lpdwBufferSize >= dwSize)
  333.     {
  334.       strcpy((char*) lpBuffer, szPathInfo);
  335.       *lpdwBufferSize = dwSize;
  336.     }
  337.     else
  338.     { 
  339.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  340.       bSuccess = FALSE;
  341.     }
  342.   }
  343.   else if (strcmpi(lpszVariableName, "REMOTE_ADDR") == 0)
  344.   {
  345.     char szRemote[20];
  346.     sprintf(szRemote, "%d.%d.%d.%d", pClient->m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b1,
  347.                pClient->m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b2, pClient->m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b3,
  348.                pClient->m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b4);
  349.     DWORD dwSize = strlen(szRemote) + 1;
  350.     if (*lpdwBufferSize >= dwSize)
  351.     {
  352.       strcpy((char*) lpBuffer, szRemote);
  353.       *lpdwBufferSize = dwSize;
  354.     }
  355.     else
  356.     { 
  357.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  358.       bSuccess = FALSE;
  359.     }
  360.   }
  361.   else if (strcmpi(lpszVariableName, "REMOTE_HOST") == 0)
  362.   {
  363.     if (pClient->m_Request.m_sRemoteHost.GetLength())
  364.     {
  365.       char* szRemoteHost = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRemoteHost);
  366.       DWORD dwSize = strlen(szRemoteHost) + 1;
  367.       if (*lpdwBufferSize >= dwSize)
  368.       {
  369.         strcpy((char*) lpBuffer, szRemoteHost);
  370.         *lpdwBufferSize = dwSize;
  371.       }
  372.       else
  373.       { 
  374.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  375.         bSuccess = FALSE;
  376.       }
  377.     }
  378.     else
  379.     {
  380.       //just return the IP address if the remote host string is empty
  381.       return GetServerVariable(hConn, "REMOTE_ADDR", lpBuffer, lpdwBufferSize);
  382.     }
  383.   }
  384.   else if ((strcmpi(lpszVariableName, "REMOTE_USER") == 0) ||
  385.            (strcmpi(lpszVariableName, "AUTH_USER") == 0))
  386.   {
  387.     char* szUser = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sUsername);
  388.     DWORD dwSize = strlen(szUser) + 1;
  389.     if (*lpdwBufferSize >= dwSize)
  390.     {
  391.       strcpy((char*) lpBuffer, szUser);
  392.       *lpdwBufferSize = dwSize;
  393.     }
  394.     else
  395.     { 
  396.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  397.       bSuccess = FALSE;
  398.     }
  399.   }
  400.   else if (strcmpi(lpszVariableName, "REQUEST_METHOD") == 0)
  401.   {
  402.     char* szVerb = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sVerb);
  403.     DWORD dwSize = strlen(szVerb) + 1;
  404.     if (*lpdwBufferSize >= dwSize)
  405.     {
  406.       strcpy((char*) lpBuffer, szVerb);
  407.       *lpdwBufferSize = dwSize;
  408.     }
  409.     else
  410.     { 
  411.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  412.       bSuccess = FALSE;
  413.     }
  414.   }
  415.   else if (strcmpi(lpszVariableName, "SERVER_NAME") == 0)
  416.   {
  417.     char* szServerName = NULL;
  418.     char szHostName[256];
  419.     if (pSettings->m_sBindAddress.GetLength())
  420.       szServerName = T2A((LPTSTR) (LPCTSTR) pSettings->m_sBindAddress);
  421.     else
  422.     {
  423.       if (gethostname(szHostName, 256) == 0)
  424.         szServerName = szHostName; 
  425.       else
  426.         szServerName = "";
  427.     }
  428.     DWORD dwSize = strlen(szServerName) + 1;
  429.     if (*lpdwBufferSize >= dwSize)
  430.     {
  431.       strcpy((char*) lpBuffer, szServerName);
  432.       *lpdwBufferSize = dwSize;
  433.     }
  434.     else
  435.     { 
  436.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  437.       bSuccess = FALSE;
  438.     }
  439.   }
  440.   else if (strcmpi(lpszVariableName, "HTTPS") == 0)
  441.   {
  442.     char szHTTPS[10];
  443.   #ifdef W3MFC_SSL_SUPPORT
  444.     if (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE)
  445.       strcpy(szHTTPS, "off");
  446.     else
  447.       strcpy(szHTTPS, "on");
  448.   #else
  449.     strcpy(szHTTPS, "off");
  450.   #endif
  451.     DWORD dwSize = strlen(szHTTPS) + 1;
  452.     if (*lpdwBufferSize >= dwSize)
  453.     {
  454.       strcpy((char*) lpBuffer, szHTTPS);
  455.       *lpdwBufferSize = dwSize;
  456.     }
  457.     else
  458.     { 
  459.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  460.       bSuccess = FALSE;
  461.     }
  462.   }
  463.   else if (strcmpi(lpszVariableName, "AUTH_TYPE") == 0)
  464.   {
  465.     char szType[10];
  466.     if (pClient->m_Request.m_AuthorizationType == CHttpRequest::HTTP_AUTHORIZATION_PLAINTEXT)
  467.       strcpy(szType, "Basic");
  468.     else if (pClient->m_Request.m_AuthorizationType == CHttpRequest::HTTP_AUTHORIZATION_NTLM)
  469.       strcpy(szType, "NTLM");
  470.     else
  471.       strcpy(szType, "");
  472.     DWORD dwSize = strlen(szType) + 1;
  473.     if (*lpdwBufferSize >= dwSize)
  474.     {
  475.       strcpy((char*) lpBuffer, szType);
  476.       *lpdwBufferSize = dwSize;
  477.     }
  478.     else
  479.     { 
  480.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  481.       bSuccess = FALSE;
  482.     }
  483.   }
  484.   else if ((strcmpi(lpszVariableName, "AUTH_PASSWORD") == 0) ||
  485.            (strcmpi(lpszVariableName, "REMOTE_PASSWORD") == 0))
  486.   {
  487.     if (pClient->m_Request.m_sPassword.GetLength())
  488.     {
  489.       char* szPassword = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sPassword);
  490.       DWORD dwSize = strlen(szPassword) + 1;
  491.       if (*lpdwBufferSize >= dwSize)
  492.       {
  493.         strcpy((char*) lpBuffer, szPassword);
  494.         *lpdwBufferSize = dwSize;
  495.       }
  496.       else
  497.       { 
  498.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  499.         bSuccess = FALSE;
  500.       }
  501.     }
  502.     else
  503.     {
  504.       SetLastError(ERROR_NO_DATA);
  505.       bSuccess = FALSE;
  506.     }
  507.   }
  508.   else if (strcmpi(lpszVariableName, "AUTH_REALM") == 0)
  509.   {
  510.     if (pClient->m_Request.m_AuthorizationType == CHttpRequest::HTTP_AUTHORIZATION_PLAINTEXT)
  511.     {
  512.       char* szRealm = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sURL);
  513.       DWORD dwSize = strlen(szRealm) + 1;
  514.       if (*lpdwBufferSize >= dwSize)
  515.       {
  516.         strcpy((char*) lpBuffer, szRealm);
  517.         *lpdwBufferSize = dwSize;
  518.       }
  519.       else
  520.       { 
  521.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  522.         bSuccess = FALSE;
  523.       }
  524.     }
  525.     else
  526.     {
  527.       SetLastError(ERROR_NO_DATA);
  528.       bSuccess = FALSE;
  529.     }
  530.   }
  531.   else if (strcmpi(lpszVariableName, "CONTENT_LENGTH") == 0)
  532.   {
  533.     if (pClient->m_Request.m_nContentLength)
  534.     {
  535.       char szContentLength[10];
  536.       sprintf(szContentLength, "%d", pClient->m_Request.m_nContentLength);
  537.       DWORD dwSize = strlen(szContentLength) + 1;
  538.       if (*lpdwBufferSize >= dwSize)
  539.       {
  540.         strcpy((char*) lpBuffer, szContentLength);
  541.         *lpdwBufferSize = dwSize;
  542.       }
  543.       else
  544.       { 
  545.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  546.         bSuccess = FALSE;
  547.       }
  548.     }
  549.     else
  550.     {
  551.       SetLastError(ERROR_NO_DATA);
  552.       bSuccess = FALSE;
  553.     }
  554.   }
  555.   else if (strcmpi(lpszVariableName, "CONTENT_TYPE") == 0)
  556.   {
  557.     if (pClient->m_Request.m_sContentType.GetLength())
  558.     {
  559.       char* szContentType = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sContentType);
  560.       DWORD dwSize = strlen(szContentType) + 1;
  561.       if (*lpdwBufferSize >= dwSize)
  562.       {
  563.         strcpy((char*) lpBuffer, szContentType);
  564.         *lpdwBufferSize = dwSize;
  565.       }
  566.       else
  567.       { 
  568.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  569.         bSuccess = FALSE;
  570.       }
  571.     }
  572.     else
  573.     {
  574.       SetLastError(ERROR_NO_DATA);
  575.       bSuccess = FALSE;
  576.     }
  577.   }
  578.   else if (strcmpi(lpszVariableName, "LOGON_USER") == 0)
  579.   {
  580.     if (pClient->m_Request.m_bLoggedOn)
  581.     {
  582.       char* szUser = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sUsername);
  583.       DWORD dwSize = strlen(szUser) + 1;
  584.       if (*lpdwBufferSize >= dwSize)
  585.       {
  586.         strcpy((char*) lpBuffer, szUser);
  587.         *lpdwBufferSize = dwSize;
  588.       }
  589.       else
  590.       { 
  591.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  592.         bSuccess = FALSE;
  593.       }
  594.     }
  595.     else if (pSettings->m_sUsername.GetLength())
  596.     {
  597.       char* szUser = T2A((LPTSTR) (LPCTSTR) pSettings->m_sUsername);
  598.       DWORD dwSize = strlen(szUser) + 1;
  599.       if (*lpdwBufferSize >= dwSize)
  600.       {
  601.         strcpy((char*) lpBuffer, szUser);
  602.         *lpdwBufferSize = dwSize;
  603.       }
  604.       else
  605.       { 
  606.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  607.         bSuccess = FALSE;
  608.       }
  609.     }
  610.     else
  611.     {
  612.       SetLastError(ERROR_NO_DATA);
  613.       bSuccess = FALSE;
  614.     }
  615.   }
  616.   else if ((strcmpi(lpszVariableName, "HTTPS_SERVER_SUBJECT") == 0) ||
  617.            (strcmpi(lpszVariableName, "CERT_SERVER_SUBJECT") == 0))
  618.   {
  619.     char* szSubject = NULL;
  620.     if (pClient->GetCertIssuerServerVariable(szSubject))
  621.     {
  622.       DWORD dwSize = strlen(szSubject) + 1;
  623.       if (*lpdwBufferSize >= dwSize)
  624.       {
  625.         strcpy((char*) lpBuffer, szSubject);
  626.         *lpdwBufferSize = dwSize;
  627.       }
  628.       else
  629.       { 
  630.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  631.         bSuccess = FALSE;
  632.       }
  633.     }
  634.     else
  635.     {
  636.       SetLastError(ERROR_NO_DATA);
  637.       bSuccess = FALSE;
  638.     }
  639.   }
  640.   else if ((strcmpi(lpszVariableName, "HTTPS_SERVER_ISSUER") == 0) ||
  641.            (strcmpi(lpszVariableName, "CERT_SERVER_ISSUER") == 0))
  642.   { 
  643.     char* szIssuer = NULL;
  644.     if (pClient->GetCertIssuerServerVariable(szIssuer))
  645.     {
  646.       DWORD dwSize = strlen(szIssuer) + 1;
  647.       if (*lpdwBufferSize >= dwSize)
  648.       {
  649.         strcpy((char*) lpBuffer, szIssuer);
  650.         *lpdwBufferSize = dwSize;
  651.       }
  652.       else
  653.       { 
  654.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  655.         bSuccess = FALSE;
  656.       }
  657.     }
  658.     else
  659.     {
  660.       SetLastError(ERROR_NO_DATA);
  661.       bSuccess = FALSE;
  662.     }
  663.   }
  664.   else if (strcmpi(lpszVariableName, "CERT_SERIALNUMBER") == 0)
  665.   {
  666.     long nSerialNumber = 0;
  667.     if (pClient->GetCertSerialNumberServerVariable(nSerialNumber))
  668.     {
  669.       char szSerialNumber[10];
  670.       sprintf(szSerialNumber, "%d", nSerialNumber);
  671.       DWORD dwSize = strlen(szSerialNumber) + 1;
  672.       if (*lpdwBufferSize >= dwSize)
  673.       {
  674.         strcpy((char*) lpBuffer, szSerialNumber);
  675.         *lpdwBufferSize = dwSize;
  676.       }
  677.       else
  678.       { 
  679.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  680.         bSuccess = FALSE;
  681.       }
  682.     }
  683.     else
  684.     {
  685.       SetLastError(ERROR_NO_DATA);
  686.       bSuccess = FALSE;
  687.     }
  688.   }
  689.   else if ((strcmpi(lpszVariableName, "HTTPS_SECRETKEYSIZE") == 0) ||
  690.            (strcmpi(lpszVariableName, "CERT_SECRETKEYSIZE") == 0))
  691.   {
  692.     int nBits = 0;
  693.     if (pClient->GetServerKeySizeServerVariable(nBits))
  694.     {
  695.       char szBits[10];
  696.       sprintf(szBits, "%d", nBits);
  697.       DWORD dwSize = strlen(szBits) + 1;
  698.       if (*lpdwBufferSize >= dwSize)
  699.       {
  700.         strcpy((char*) lpBuffer, szBits);
  701.         *lpdwBufferSize = dwSize;
  702.       }
  703.       else
  704.       { 
  705.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  706.         bSuccess = FALSE;
  707.       }
  708.     }
  709.     else
  710.     {
  711.       SetLastError(ERROR_NO_DATA);
  712.       bSuccess = FALSE;
  713.     }
  714.   }
  715.   else if ((strcmpi(lpszVariableName, "HTTPS_KEYSIZE") == 0) ||
  716.            (strcmpi(lpszVariableName, "CERT_KEYSIZE") == 0)) 
  717.   {
  718.     int nBits = 0;
  719.     if (pClient->GetKeySizeServerVariable(nBits))
  720.     {
  721.       char szBits[10];
  722.       sprintf(szBits, "%d", nBits);
  723.       DWORD dwSize = strlen(szBits) + 1;
  724.       if (*lpdwBufferSize >= dwSize)
  725.       {
  726.         strcpy((char*) lpBuffer, szBits);
  727.         *lpdwBufferSize = dwSize;
  728.       }
  729.       else
  730.       { 
  731.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  732.         bSuccess = FALSE;
  733.       }
  734.     }
  735.     else
  736.     {
  737.       SetLastError(ERROR_NO_DATA);
  738.       bSuccess = FALSE;
  739.     }
  740.   }
  741.   else if (strcmpi(lpszVariableName, "PATH_TRANSLATED") == 0)
  742.   {
  743.     LPTSTR pszFilePart;
  744.     TCHAR pszAbsolutePath[_MAX_PATH];
  745.     GetFullPathName(pClient->m_Request.m_sLocalFile, _MAX_PATH, pszAbsolutePath, &pszFilePart);
  746.     char* szAbsolutePath = T2A(pszAbsolutePath);
  747.     DWORD dwSize = strlen(szAbsolutePath) + 1;
  748.     if (*lpdwBufferSize >= dwSize)
  749.     {
  750.       strcpy((char*) lpBuffer, szAbsolutePath);
  751.       *lpdwBufferSize = dwSize;
  752.     }
  753.     else
  754.     { 
  755.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  756.       bSuccess = FALSE;
  757.     }
  758.   }
  759.   else if (strcmpi(lpszVariableName, "SCRIPT_NAME") == 0)
  760.   {
  761.     CString sScriptName = pClient->m_Request.m_sLocalFile;
  762.     sScriptName.Replace(_T('\'), _T('/')); //Ensure we use unix directory separators
  763.     if (sScriptName.GetLength() && sScriptName.GetAt(0) != _T('/'))
  764.       sScriptName = _T("/") + sScriptName;
  765.     char* szScriptName = T2A((LPTSTR) (LPCTSTR) sScriptName);
  766.     DWORD dwSize = strlen(szScriptName) + 1;
  767.     if (*lpdwBufferSize >= dwSize)
  768.     {
  769.       strcpy((char*) lpBuffer, szScriptName);
  770.       *lpdwBufferSize = dwSize;
  771.     }
  772.     else
  773.     { 
  774.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  775.       bSuccess = FALSE;
  776.     }
  777.   }
  778.   else if (strcmpi(lpszVariableName, "REQUEST_LINE") == 0)
  779.   {
  780.     char* szRequest = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRequest);
  781.     DWORD dwSize = strlen(szRequest) + 1;
  782.     if (*lpdwBufferSize >= dwSize)
  783.     {
  784.       strcpy((char*) lpBuffer, szRequest);
  785.       *lpdwBufferSize = dwSize;
  786.     }
  787.     else
  788.     { 
  789.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  790.       bSuccess = FALSE;
  791.     }
  792.   }
  793.   else if (strcmpi(lpszVariableName, "ALL_HTTP") == 0)
  794.   {
  795.     CString sAllHeaders;
  796.     POSITION posMap = pClient->m_Request.m_HeaderMap.GetStartPosition();
  797.     while (posMap)
  798.     {
  799.       CString sKey;
  800.       CString sValue;
  801.       pClient->m_Request.m_HeaderMap.GetNextAssoc(posMap, sKey, sValue);
  802.       CString sLine;
  803.       if (posMap)  
  804.         sLine.Format(_T("HTTP_%s=%sn"), sKey, sValue);
  805.       else
  806.         sLine.Format(_T("HTTP_%s=%s"), sKey, sValue);
  807.         
  808.       sAllHeaders += sLine;
  809.     }
  810.     
  811.     char* pszAllHeaders = T2A((LPTSTR) (LPCTSTR) sAllHeaders);
  812.     DWORD dwSize = strlen(pszAllHeaders) + 1;
  813.     if (*lpdwBufferSize >= dwSize)
  814.     {
  815.       strcpy((char*) lpBuffer, pszAllHeaders);
  816.       *lpdwBufferSize = dwSize;
  817.     }
  818.     else
  819.     { 
  820.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  821.       bSuccess = FALSE;
  822.     }
  823.   }
  824.   else if (strcmpi(lpszVariableName, "ALL_RAW") == 0)
  825.   {
  826.     DWORD dwSize = 0;
  827.     if (pClient->m_Request.m_pRawEntity)
  828.       dwSize = pClient->m_Request.m_pRawEntity - pClient->m_Request.m_pRawRequest + 1;
  829.     else
  830.       dwSize = pClient->m_Request.m_dwRawRequestSize;
  831.     if (*lpdwBufferSize >= dwSize)
  832.     {
  833.       CopyMemory(lpBuffer, pClient->m_Request.m_pRawRequest, dwSize);
  834.       ((BYTE*) lpBuffer)[dwSize] = '';
  835.       *lpdwBufferSize = dwSize;
  836.     }
  837.     else
  838.     { 
  839.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  840.       bSuccess = FALSE;
  841.     }
  842.   }
  843.   else if (strcmpi(lpszVariableName, "HTTP_VERSION") == 0)
  844.   {
  845.     char szVersion[10];
  846.     sprintf(szVersion, "%d.%d", HIWORD(pClient->m_Request.m_dwHttpVersion), LOWORD(pClient->m_Request.m_dwHttpVersion));
  847.     DWORD dwSize = strlen(szVersion) + 1;
  848.     if (*lpdwBufferSize >= dwSize)
  849.     {
  850.       strcpy((char*) lpBuffer, szVersion);
  851.       *lpdwBufferSize = dwSize;
  852.     }
  853.     else
  854.     { 
  855.       SetLastError(ERROR_INSUFFICIENT_BUFFER);
  856.       bSuccess = FALSE;
  857.     }
  858.   }
  859.   else if (_strnicmp(lpszVariableName, "HTTP_", 5) == 0)
  860.   {
  861.     CString sKey(lpszVariableName);
  862.     sKey = sKey.Right(sKey.GetLength() - 5);
  863.     sKey.MakeUpper();
  864.     CString sValue;
  865.     if (pClient->m_Request.m_HeaderMap.Lookup(sKey, sValue))
  866.     {
  867.       char* szValue = T2A((LPTSTR) (LPCTSTR) sValue);
  868.       DWORD dwSize = strlen(szValue) + 1;
  869.       if (*lpdwBufferSize >= dwSize)
  870.       {
  871.         strcpy((char*) lpBuffer, szValue);
  872.         *lpdwBufferSize = dwSize;
  873.       }
  874.       else
  875.       { 
  876.         SetLastError(ERROR_INSUFFICIENT_BUFFER);
  877.         bSuccess = FALSE;
  878.       }
  879.     }
  880.     else
  881.     {
  882.       SetLastError(ERROR_NO_DATA);
  883.       bSuccess = FALSE;
  884.     }
  885.   }
  886.   else
  887.   {
  888.     SetLastError(ERROR_INVALID_INDEX);
  889.     bSuccess = FALSE;
  890.   }
  891.   return bSuccess;
  892. }
  893. BOOL CHttpISAPI::ReadClient(HCONN hConn, LPVOID /*lpvBuffer*/, LPDWORD lpdwSize)
  894. {
  895.   //nothing to read, so set the value
  896.   *lpdwSize = 0;
  897.   //Validate our parameters
  898.   CHttpClient* pClient = (CHttpClient*) hConn;
  899.   if (pClient == NULL)
  900.   {
  901.     SetLastError(ERROR_INVALID_PARAMETER);
  902.     return FALSE;
  903.   }  
  904.   //We do not support reading from the client, since we supply all of the data in the EXTENSION_CONTROL_BLOCK
  905.   SetLastError(ERROR_NO_DATA);
  906.   return FALSE;
  907. }
  908. BOOL CHttpISAPI::WriteClient(HCONN hConn, LPVOID Buffer, LPDWORD lpdwBytes, DWORD dwSync)
  909. {
  910.   //Validate our parameters
  911.   CHttpClient* pClient = (CHttpClient*) hConn;
  912.   if ((pClient == NULL) || (dwSync == HSE_IO_ASYNC))
  913.   {
  914.     SetLastError(ERROR_INVALID_PARAMETER);
  915.     return FALSE;
  916.   }  
  917.   ASSERT(pClient->m_pServer);
  918.   CHttpServerSettings* pSettings = pClient->m_pServer->GetSettings();
  919.   ASSERT(pSettings);
  920.   //Assume the worst
  921.   BOOL bSuccess = FALSE;
  922.   try
  923.   {
  924.   #ifdef W3MFC_SSL_SUPPORT
  925.     pClient->m_Socket.SendWithRetry(Buffer, *lpdwBytes, pSettings->m_dwWritableTimeout, pClient->m_SSL);
  926.   #else    
  927.     pClient->m_Socket.SendWithRetry(Buffer, *lpdwBytes, pSettings->m_dwWritableTimeout);
  928.   #endif
  929.     pClient->m_dwDataSentViaWriteClient += *lpdwBytes;
  930.     bSuccess = TRUE;
  931.   }
  932.   catch(CWSocketException* pEx)
  933.   {
  934.     //Report the error
  935.     CString sError;
  936.     sError.Format(_T("CHttpISAPI::WriteClient, Failed to send to socket, error:%d"), pEx->m_nError);
  937.     pClient->m_pServer->OnError(sError);
  938.     //Allow callers to see what the error was
  939.     SetLastError(pEx->m_nError);
  940.     pEx->Delete();  
  941.   }
  942.   return bSuccess;
  943. }
  944. BOOL CHttpISAPI::ServerSupportFunction(HCONN hConn, DWORD dwHSERRequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType)
  945. {
  946.   USES_CONVERSION;
  947.   //Validate our parameters
  948.   CHttpClient* pClient = (CHttpClient*) hConn;
  949.   if (pClient == NULL)
  950.   {
  951.     SetLastError(ERROR_INVALID_PARAMETER);
  952.     return FALSE;
  953.   }  
  954.   ASSERT(pClient->m_pServer);
  955.   CHttpServerSettings* pSettings = pClient->m_pServer->GetSettings();
  956.   ASSERT(pSettings);
  957.   //Assume the best
  958.   BOOL bSuccess = TRUE;
  959.   switch (dwHSERRequest)
  960.   {
  961.     case HSE_REQ_CLOSE_CONNECTION:
  962.     {
  963.       //We support this function but do a NOOP since
  964.       //the connection will be closed when HttpExtensionProc
  965.       //returns normally
  966.       break;
  967.     }
  968.     case HSE_REQ_GET_IMPERSONATION_TOKEN:
  969.     {
  970.       if (pClient->m_Request.m_hImpersonation)
  971.         *((HANDLE*) lpvBuffer) = pClient->m_Request.m_hImpersonation;
  972.       else
  973.       {
  974.         SetLastError(ERROR_NO_DATA);
  975.         bSuccess = FALSE;
  976.       }
  977.       break;
  978.     }
  979.     case HSE_REQ_GET_SSPI_INFO:
  980.     {
  981.     #ifndef W3MFC_NO_SSPI_SUPPORT
  982.       CopyMemory(((CtxtHandle*) lpvBuffer), &pClient->m_Request.m_hImpersonation, sizeof(CtxtHandle));
  983.       CopyMemory(((CredHandle*) lpdwDataType), pClient->m_pServer->GetCredentialHandle(), sizeof(CredHandle));
  984.     #else
  985.       SetLastError(ERROR_NO_DATA);
  986.       bSuccess = FALSE;
  987.     #endif
  988.       break;
  989.     }
  990.     case HSE_REQ_IS_KEEP_CONN:
  991.     {
  992.       *((BOOL*) lpvBuffer) = pClient->m_bResponseKeepAlive;
  993.       break;
  994.     }
  995.     case HSE_REQ_MAP_URL_TO_PATH:
  996.     {
  997.       LPSTR pszURL = (LPSTR) lpvBuffer;
  998.       HSE_URL_MAPEX_INFO* pUMI = (HSE_URL_MAPEX_INFO*) lpdwDataType;
  999.       pUMI->dwFlags = 0;
  1000.       CString sURL(pszURL);
  1001.       BOOL bDirectory = FALSE;
  1002.       CHttpDirectory* pDirectory = NULL;
  1003.       CString sLocalFile;
  1004.       CString sPathInfo;
  1005.       if (pClient->MapURLToLocalFilename(sURL, sLocalFile, sPathInfo, bDirectory, pDirectory, pUMI->cchMatchingURL, pUMI->cchMatchingPath))
  1006.       {
  1007.         LPSTR pszLocalFile = T2A((LPTSTR) (LPCTSTR) sLocalFile);
  1008.         DWORD dwSize = strlen(pszLocalFile) + 1;
  1009.         if (*lpdwSize >= dwSize)
  1010.         {
  1011.           strcpy(pszURL, pszLocalFile);
  1012.           if (!pDirectory->GetScript())
  1013.             pUMI->dwFlags |= HSE_URL_FLAGS_READ;
  1014.           else
  1015.           {
  1016.             pUMI->dwFlags |= HSE_URL_FLAGS_EXECUTE;
  1017.             pUMI->dwFlags |= HSE_URL_FLAGS_SCRIPT;
  1018.           }
  1019.           if (pDirectory->GetWritable())
  1020.             pUMI->dwFlags |= HSE_URL_FLAGS_WRITE;
  1021.         #ifdef W3MFC_SSL_SUPPORT
  1022.           if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  1023.              pUMI->dwFlags |= HSE_URL_FLAGS_SSL;
  1024.         #endif
  1025.         }
  1026.         else
  1027.         {
  1028.           SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1029.           bSuccess = FALSE;
  1030.         }
  1031.       }
  1032.       else
  1033.       {
  1034.         SetLastError(ERROR_NO_DATA);
  1035.         bSuccess = FALSE;
  1036.       }
  1037.       break;
  1038.     }
  1039.     case HSE_REQ_MAP_URL_TO_PATH_EX:
  1040.     {
  1041.       LPSTR pszURL = (LPSTR) lpvBuffer;
  1042.       HSE_URL_MAPEX_INFO* pUMI = (HSE_URL_MAPEX_INFO*) lpdwDataType;
  1043.       pUMI->dwFlags = 0;
  1044.       CString sURL(pszURL);
  1045.       BOOL bDirectory = FALSE;
  1046.       CHttpDirectory* pDirectory = NULL;
  1047.       CString sLocalFile;
  1048.       CString sPathInfo;
  1049.       if (pClient->MapURLToLocalFilename(sURL, sLocalFile, sPathInfo, bDirectory, pDirectory, pUMI->cchMatchingURL, pUMI->cchMatchingPath))
  1050.       {
  1051.         LPSTR pszLocalFile = T2A((LPTSTR) (LPCTSTR) sLocalFile);
  1052.         strcpy(pUMI->lpszPath, pszLocalFile);
  1053.         if (!pDirectory->GetScript())
  1054.           pUMI->dwFlags |= HSE_URL_FLAGS_READ;
  1055.         else
  1056.         {
  1057.           pUMI->dwFlags |= HSE_URL_FLAGS_EXECUTE;
  1058.           pUMI->dwFlags |= HSE_URL_FLAGS_SCRIPT;
  1059.         }
  1060.         if (pDirectory->GetWritable())
  1061.           pUMI->dwFlags |= HSE_URL_FLAGS_WRITE;
  1062.       #ifdef W3MFC_SSL_SUPPORT
  1063.         if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  1064.            pUMI->dwFlags |= HSE_URL_FLAGS_SSL;
  1065.       #endif
  1066.       }
  1067.       else
  1068.       {
  1069.         SetLastError(ERROR_NO_DATA);
  1070.         bSuccess = FALSE;
  1071.       }
  1072.       break;
  1073.     }
  1074.     case HSE_REQ_SEND_URL:
  1075.     case HSE_REQ_SEND_URL_REDIRECT_RESP:
  1076.     {
  1077.       LPSTR pszURL = (LPSTR) lpvBuffer;
  1078.       pClient->ReturnRedirectMessage(pszURL);
  1079.       pClient->m_nHttpStatusCodeSent = 302;
  1080.       break;
  1081.     }
  1082.     case HSE_REQ_SEND_RESPONSE_HEADER:
  1083.     {
  1084.       LPSTR pszStatusString = (LPSTR) lpvBuffer;
  1085.       LPSTR pszExtraHeaders = (LPSTR) lpdwDataType;
  1086.       CHttpResponseHeader responseHdr;
  1087.       if (pszStatusString && strlen(pszStatusString))
  1088.       {
  1089.         responseHdr.AddStatus(pszStatusString);
  1090.         pClient->m_nHttpStatusCodeSent = atoi(pszStatusString);
  1091.       }
  1092.       else
  1093.       {
  1094.         responseHdr.AddStatusCode(200);
  1095.         pClient->m_nHttpStatusCodeSent = 200;
  1096.       }
  1097.       SYSTEMTIME stCurTime;
  1098.       ::GetSystemTime(&stCurTime);
  1099.       responseHdr.AddDate(stCurTime);
  1100.       responseHdr.AddServer(pSettings->m_sServerName);
  1101.       responseHdr.AddW3MfcAllowFields(pSettings->m_bAllowDeleteRequest);
  1102.       if (pszExtraHeaders && strlen(pszExtraHeaders))
  1103.         responseHdr.AddExtraHeaders(pszExtraHeaders);
  1104.       pClient->m_bResponseKeepAlive = FALSE;
  1105.       responseHdr.SetAddEntitySeparator(FALSE);
  1106.       
  1107.       //Send the header 
  1108.       pClient->TransmitBuffer(pClient->m_Socket, responseHdr, NULL, 0, pSettings->m_dwWritableTimeout);
  1109.       break;
  1110.     }
  1111.     case HSE_REQ_SEND_RESPONSE_HEADER_EX:
  1112.     {
  1113.       HSE_SEND_HEADER_EX_INFO* pHeader = (HSE_SEND_HEADER_EX_INFO*) lpvBuffer;
  1114.       CHttpResponseHeader responseHdr;
  1115.       if (pHeader->pszStatus && strlen(pHeader->pszStatus))
  1116.       {
  1117.         responseHdr.AddStatus(pHeader->pszStatus);
  1118.         pClient->m_nHttpStatusCodeSent = atoi(pHeader->pszStatus);
  1119.       }
  1120.       else
  1121.       {
  1122.         responseHdr.AddStatusCode(200);
  1123.         pClient->m_nHttpStatusCodeSent = 200;
  1124.       }
  1125.       SYSTEMTIME stCurTime;
  1126.       ::GetSystemTime(&stCurTime);
  1127.       responseHdr.AddDate(stCurTime);
  1128.       responseHdr.AddServer(pSettings->m_sServerName);
  1129.       responseHdr.AddW3MfcAllowFields(pSettings->m_bAllowDeleteRequest);
  1130.       if (pHeader->pszHeader && strlen(pHeader->pszHeader))
  1131.         responseHdr.AddExtraHeaders(pHeader->pszHeader);
  1132.       if (pHeader->fKeepConn)
  1133.         responseHdr.AddKeepAlive();
  1134.       pClient->m_bResponseKeepAlive = pHeader->fKeepConn;
  1135.       responseHdr.SetAddEntitySeparator(FALSE);
  1136.       //Send the header 
  1137.       pClient->TransmitBuffer(pClient->m_Socket, responseHdr, NULL, 0, pSettings->m_dwWritableTimeout);
  1138.       break;
  1139.     }
  1140.     case HSE_REQ_TRANSMIT_FILE:
  1141.     {
  1142.     #ifdef W3MFC_SSL_SUPPORT
  1143.       BOOL bAvailable = (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE);
  1144.     #else
  1145.       BOOL bAvailable = TRUE;
  1146.     #endif
  1147.       if (bAvailable)
  1148.       {
  1149.         CHttpResponseHeader responseHdr;
  1150.         SYSTEMTIME stCurTime;
  1151.         ::GetSystemTime(&stCurTime);
  1152.         responseHdr.AddDate(stCurTime);
  1153.         responseHdr.AddServer(pSettings->m_sServerName);
  1154.         responseHdr.AddW3MfcAllowFields(pSettings->m_bAllowDeleteRequest);
  1155.         pClient->m_bResponseKeepAlive = FALSE;
  1156.         HSE_TF_INFO* pInfo = (HSE_TF_INFO*) lpvBuffer;
  1157.         bSuccess = pClient->TransmitFile(pClient->m_Socket, responseHdr, pInfo);
  1158.       }
  1159.       else
  1160.       {
  1161.         SetLastError(ERROR_INVALID_INDEX);
  1162.         bSuccess = FALSE;
  1163.       }
  1164.       break;
  1165.     }
  1166.     default:
  1167.     {
  1168.       //Report the error
  1169.       CString sError;
  1170.       sError.Format(_T("CHttpISAPI::ServerSupportFunction, An invalid HSERequest value was specified %s, HSERequest:%d"), pClient->m_Request.m_sURL, dwHSERRequest);
  1171.       pClient->m_pServer->OnError(sError);
  1172.       SetLastError(ERROR_INVALID_INDEX);
  1173.       bSuccess = FALSE;
  1174.       break;
  1175.     }
  1176.   }
  1177.   return bSuccess;
  1178. }
  1179. void CHttpISAPI::ReportHttpExtensionProcError(CHttpClient* pClient, CHttpISAPIExtension& extension, DWORD dwError)
  1180. {
  1181.   //Validate our parameters
  1182.   ASSERT(pClient);
  1183.   ASSERT(pClient->m_pServer);
  1184.   //Report the error
  1185.   CString sError;
  1186.   sError.Format(_T("CHttpISAPI::ReportHTTPExtensionProcError, Failed calling the function HttpExtensionProc in the ISAPI extension %s, error:%d"), extension.m_sPath, dwError);
  1187.   pClient->m_pServer->OnError(sError);
  1188. }
  1189. BOOL CHttpISAPI::CallHttpExtensionProc(CHttpClient* pClient, CHttpISAPIExtension& extension)
  1190. {
  1191.   USES_CONVERSION;
  1192.   //Validate our parameters
  1193.   ASSERT(extension.m_lpHttpExtensionProc);
  1194.   ASSERT(pClient);
  1195.   ASSERT(pClient->m_pServer);
  1196.   //Assume the worst
  1197.   BOOL bSuccess = FALSE;
  1198.   __try
  1199.   {
  1200.     //Setup the structure
  1201.     EXTENSION_CONTROL_BLOCK ecb;
  1202.     ecb.cbSize = sizeof(EXTENSION_CONTROL_BLOCK);
  1203.     ecb.dwVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
  1204.     ecb.ConnID = (HCONN) pClient;
  1205.     ecb.dwHttpStatusCode = 200;
  1206.     strcpy(ecb.lpszLogData, "");
  1207.     ecb.lpszMethod = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sVerb);
  1208.     ecb.lpszQueryString = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRawExtra);
  1209.     ecb.lpszPathInfo = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sPathInfo);
  1210.     ecb.lpszPathTranslated = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sLocalFile);
  1211.     ecb.cbTotalBytes = pClient->m_Request.m_dwRawEntitySize;
  1212.     ecb.cbAvailable = ecb.cbTotalBytes;
  1213.     ecb.lpbData = pClient->m_Request.m_pRawEntity;
  1214.     ecb.lpszContentType = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sContentType);
  1215.     ecb.GetServerVariable = GetServerVariable;
  1216.     ecb.WriteClient = WriteClient;
  1217.     ecb.ReadClient = ReadClient;
  1218.     ecb.ServerSupportFunction = ServerSupportFunction;
  1219.     //Finally call the function with the structure
  1220.     DWORD dwSuccess = extension.m_lpHttpExtensionProc(&ecb);
  1221.     bSuccess = (dwSuccess == HSE_STATUS_SUCCESS);
  1222.     if (dwSuccess == HSE_STATUS_SUCCESS_AND_KEEP_CONN)
  1223.     {
  1224.       pClient->m_bResponseKeepAlive = TRUE;
  1225.       bSuccess = TRUE;
  1226.     }
  1227.     if (!bSuccess)
  1228.       ReportHttpExtensionProcError(pClient, extension, dwSuccess);
  1229.   }
  1230.   __except(1)
  1231.   {
  1232.     bSuccess = FALSE;
  1233.   }
  1234.   return bSuccess;
  1235. }