⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpisapi.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
Module : HttpISAPI.cpp
Purpose: Implementation for the CHttpISAPI class
Created: PJN / 21-02-2003
History: PJN / 22-02-2004 1. Fixed a memory leak in CHttpISAPI::CachedLoad. Thanks to "mori" for
                          reporting and suggesting the fix for this bug.

Copyright (c) 2003 - 2005 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/



//////////////// Includes ////////////////////////////////////////////

#include "stdafx.h"
#include "HttpISAPI.h"
#include "HttpClient.h"

//////////////// Macros / Defines ////////////////////////////////////

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifndef HSE_REQ_CLOSE_CONNECTION
#define HSE_REQ_CLOSE_CONNECTION                 (HSE_REQ_END_RESERVED+17)
#endif



//////////////// Implementation //////////////////////////////////////

CHttpISAPIExtension::CHttpISAPIExtension()
{
  m_hDLL = NULL;
  m_lpGetExtensionVersion = NULL;
  m_lpHttpExtensionProc = NULL;
  m_lpTerminateExtension = NULL;
}

CHttpISAPIExtension::~CHttpISAPIExtension()
{
  if (m_hDLL)
  {
    //Call the terminate function (if it exists)
    if (m_lpTerminateExtension)
      CallTerminateExtension();
      
    //Finally free up the library
    FreeLibrary(m_hDLL);
  }
}

BOOL CHttpISAPIExtension::CallGetExtensionVersion(HSE_VERSION_INFO* phseVerInfo)
{
  //Validate our parameters
  ASSERT(m_lpGetExtensionVersion);

  //Assume the worst
  BOOL bSuccess = FALSE;

  __try
  {
    bSuccess = m_lpGetExtensionVersion(phseVerInfo);
  }
  __except(1)
  {
    bSuccess = FALSE;
  }

  return bSuccess;
}

BOOL CHttpISAPIExtension::CallTerminateExtension()
{
  ASSERT(m_lpTerminateExtension);

  //Assume the worst
  BOOL bSuccess = FALSE;

  __try
  {
    bSuccess = m_lpTerminateExtension(HSE_TERM_MUST_UNLOAD);
  }
  __except(1)
  {
    bSuccess = FALSE;
  }

  return bSuccess;
}



CHttpISAPI::CHttpISAPI(int nISAPIHashTableSize) : m_mapExtensions(nISAPIHashTableSize)
{
  m_pServer = NULL;
}

CHttpISAPI::~CHttpISAPI()
{
  FreeMapEntries();
}

void CHttpISAPI::SetServer(CHttpServer* pServer)
{
  m_pServer = pServer;
}

void CHttpISAPI::FreeMapEntries()
{
  //Prevent the hash table from being manipulated
  //by multiple threads at the one time
  CSingleLock sl(&m_CS, TRUE);

  //Remove all the entries in the hash table
  for (POSITION pos = m_mapExtensions.GetStartPosition(); pos != NULL; )
  {
    CHttpISAPIExtension* pEntry = NULL;
    CString sKey;
    m_mapExtensions.GetNextAssoc(pos, sKey, (void*&) pEntry);
    if (pEntry)
      delete pEntry;
  }
  m_mapExtensions.RemoveAll();
}

BOOL CHttpISAPI::UncachedLoad(const CString& sPath, CHttpISAPIExtension& extension)
{
  //Validate our parameters
  ASSERT(m_pServer);

  //What will be the return value
  BOOL bSuccess = FALSE;
 
  //Load up the DLL
  ASSERT(extension.m_hDLL == NULL);
  extension.m_sPath = sPath;
  extension.m_hDLL = LoadLibraryEx(sPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  if (extension.m_hDLL)
  {
    //Get the "GetExtensionVersion" function
    extension.m_lpGetExtensionVersion = (CHttpISAPIExtension::LPGETEXTENSIONVERSION) GetProcAddress(extension.m_hDLL, "GetExtensionVersion");
    if (extension.m_lpGetExtensionVersion == NULL)    
    {
      //Report the error that we could not find the function
      CString sError;
      sError.Format(_T("CHttpISAPI::UncachedLoad, Could not find entry point GetExtensionVersion in dll %s"), sPath);
      m_pServer->OnError(sError);
    }

    //Get the HttpExtensionProc function
    extension.m_lpHttpExtensionProc = (CHttpISAPIExtension::LPHTTPEXTENSIONPROC) GetProcAddress(extension.m_hDLL, "HttpExtensionProc");
    if (extension.m_lpHttpExtensionProc == NULL)    
    {
      //Report the error that we could not find the function
      CString sError;
      sError.Format(_T("CHttpISAPI::UncachedLoad, Could not find entry point HttpExtensionProc in dll %s"), sPath);
      m_pServer->OnError(sError);
    }

    if (extension.m_lpGetExtensionVersion && extension.m_lpHttpExtensionProc)
    {
      //Now find the optional "TerminateExtension" function (if initialisation succeeded)
      extension.m_lpTerminateExtension = (CHttpISAPIExtension::LPTERMINATEEXTENSION) GetProcAddress(extension.m_hDLL, "TerminateExtension");

      //Also call the GetExtensionVersion function
      HSE_VERSION_INFO hseVerInfo;
      CString sError;
      bSuccess = extension.CallGetExtensionVersion(&hseVerInfo);
      if (!bSuccess)
      {
        //Report the error that we could not call the GetExtensionVersion function
        sError.Format(_T("CHttpISAPI::UncachedLoad, Failed in call to GetExtensionVersion in dll %s, error:%d"), sPath, GetLastError());
        m_pServer->OnError(sError);
      }
    }
  }
  else
  {
    //Report the error that we could not find the function
    DWORD dwError = GetLastError();
    CString sError;
    sError.Format(_T("CHttpISAPI::UncachedLoad, Could not load the dll %s, error:%d"), sPath, dwError);
    m_pServer->OnError(sError);
  }

  return bSuccess;
}

CHttpISAPIExtension* CHttpISAPI::CachedLoad(const CString& sPath)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);
  ASSERT(pSettings->m_bCacheISAPI);

  //Look up in the hash table case insensitively
  CString sKey(sPath);
  sKey.MakeUpper(); 

  //What will be the return value
  CHttpISAPIExtension* pExtension = NULL;

  //Prevent the hash table from being manipulated
  //by multiple threads at the one time
  CSingleLock sl(&m_CS, TRUE);

  //try looking it up in the cache first
  if (!m_mapExtensions.Lookup(sKey, (void*&) pExtension))
  {
    //Only created if not found in hash
    pExtension = new CHttpISAPIExtension;
 
    //Call the other Load method to do most of the work
    if (!UncachedLoad(sPath, *pExtension))
    {
      delete pExtension;
      pExtension = NULL;
    }
    else
    {
      //Add it to the hash if caching is enabled
      m_mapExtensions.SetAt(sKey, pExtension);
    }
  }

  return pExtension;
}

BOOL CHttpISAPI::GetServerVariable(HCONN hConn, LPSTR lpszVariableName, void* lpBuffer, DWORD* lpdwBufferSize)
{
  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;

  if (strcmpi(lpszVariableName, "SERVER_PORT") == 0)
  {
    char szPort[10];
    sprintf(szPort, "%d", pSettings->m_nPort);
    DWORD dwSize = strlen(szPort) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szPort);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "SERVER_PORT_SECURE") == 0)
  {
  #ifdef W3MFC_SSL_SUPPORT
    if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
    {
      char szSecure[10];
      sprintf(szSecure, "%d", pSettings->m_nPort);
      DWORD dwSize = strlen(szSecure) + 1;
      if (*lpdwBufferSize >= dwSize)
      {
        strcpy((char*) lpBuffer, szSecure);
        *lpdwBufferSize = dwSize;
      }
      else
      { 
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        bSuccess = FALSE;
      }
    }
    else
    {
      SetLastError(ERROR_NO_DATA);
      bSuccess = FALSE;
    }
  #else
    SetLastError(ERROR_NO_DATA);
    bSuccess = FALSE;
  #endif
  }
  else if (strcmpi(lpszVariableName, "SERVER_PROTOCOL") == 0)
  {
    char szProtocol[10];
  #ifdef W3MFC_SSL_SUPPORT
    if (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE)
      strcpy(szProtocol, "HTTP/1.0");
    else
      strcpy(szProtocol, "HTTPS/1.0");
  #else
    strcpy(szProtocol, "HTTP/1.0");
  #endif

    DWORD dwSize = strlen(szProtocol) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szProtocol);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "SERVER_SOFTWARE") == 0)
  {
    char* szSoftware = T2A((LPTSTR) (LPCTSTR) pSettings->m_sServerName);
    DWORD dwSize = strlen(szSoftware) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szSoftware);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "URL") == 0)
  {
    char* szURL = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sURL);
    DWORD dwSize = strlen(szURL) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szURL);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "QUERY_STRING") == 0)
  {
    char* szQueryString = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRawExtra);
    DWORD dwSize = strlen(szQueryString) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szQueryString);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "PATH_INFO") == 0)
  {
    char* szPathInfo = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sPathInfo);
    DWORD dwSize = strlen(szPathInfo) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szPathInfo);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "REMOTE_ADDR") == 0)
  {
    char szRemote[20];
    sprintf(szRemote, "%d.%d.%d.%d", pClient->m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b1,
               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,
               pClient->m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b4);
    DWORD dwSize = strlen(szRemote) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szRemote);
      *lpdwBufferSize = dwSize;
    }
    else
    { 
      SetLastError(ERROR_INSUFFICIENT_BUFFER);
      bSuccess = FALSE;
    }
  }
  else if (strcmpi(lpszVariableName, "REMOTE_HOST") == 0)
  {
    if (pClient->m_Request.m_sRemoteHost.GetLength())
    {
      char* szRemoteHost = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sRemoteHost);
      DWORD dwSize = strlen(szRemoteHost) + 1;
      if (*lpdwBufferSize >= dwSize)
      {
        strcpy((char*) lpBuffer, szRemoteHost);
        *lpdwBufferSize = dwSize;
      }
      else
      { 
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        bSuccess = FALSE;
      }
    }
    else
    {
      //just return the IP address if the remote host string is empty
      return GetServerVariable(hConn, "REMOTE_ADDR", lpBuffer, lpdwBufferSize);
    }
  }
  else if ((strcmpi(lpszVariableName, "REMOTE_USER") == 0) ||
           (strcmpi(lpszVariableName, "AUTH_USER") == 0))
  {
    char* szUser = T2A((LPTSTR) (LPCTSTR) pClient->m_Request.m_sUsername);
    DWORD dwSize = strlen(szUser) + 1;
    if (*lpdwBufferSize >= dwSize)
    {
      strcpy((char*) lpBuffer, szUser);
      *lpdwBufferSize = dwSize;
    }
    else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -