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

📄 httpisapi.cpp

📁 minica2的第2个版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      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 + -