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

📄 httpclient.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      sRelativeFile = sRelativeFile.Right(sRelativeFile.GetLength() - sAlias.GetLength());

      //Form the local filename from the requested URL
      CString sDirectory = pDirectory->GetDirectory();
      int nLength = sDirectory.GetLength();
      if (sDirectory.GetAt(nLength-1) != _T('\\'))
        sDirectory += _T("\\");
      sLocalFile = sDirectory; 

      //Asking for the default filename
      if (sRelativeFile.IsEmpty())
      {
        bDirectory = pDirectory->GetDirectoryListing();
        if (!bDirectory)
          sLocalFile += pDirectory->GetDefaultFile(); 

        dwMatchingURL = sURL.GetLength();
        dwMatchingPath = sLocalFile.GetLength();
      }
      else
      {
        //Ensure that we don't have two "\" separating the filename from the directory
        if (sClientURL.Find(_T('\\')) == 0)
          sLocalFile += sRelativeFile.Right(sRelativeFile.GetLength());
        else
          sLocalFile += sRelativeFile; 

        dwMatchingURL = sURL.GetLength();
        dwMatchingPath = sLocalFile.GetLength();

        //Keep parsing left to right until we find a piece of the path which is a file.
        //This is used to work out the PathInfo value
        CString sTemp(sRelativeFile);
        int nLocalFileData = 0;
        BOOL bContinueParse = TRUE;
        while (bContinueParse)
        {
          int nSlash = sTemp.Find(_T('\\'));
          if (nSlash != -1)
          {
            nLocalFileData += nSlash;
            CString sFile(sDirectory + sRelativeFile.Left(nLocalFileData));
            sTemp = sTemp.Right(sTemp.GetLength() - nSlash - 1);

            DWORD dwAttributes = GetFileAttributes(sFile);
            if (dwAttributes == INVALID_FILE_ATTRIBUTES)
            {
              bContinueParse = FALSE;
              sPathInfo = sLocalFile.Right(sLocalFile.GetLength() - sFile.GetLength() + nSlash);
              sPathInfo.Replace(_T("\\"), _T("/"));
              sLocalFile = sFile.Left(sFile.GetLength() - nSlash - 1);

              //Remove the PathInfo from the incoming parameter
              sURL = sURL.Left(sURL.GetLength() - sPathInfo.GetLength());

              dwMatchingURL = sClientURL.GetLength() - sPathInfo.GetLength();
              dwMatchingPath = sLocalFile.GetLength();
            }
            else if ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
            {
              bContinueParse = FALSE;
              sPathInfo = sLocalFile.Right(sLocalFile.GetLength() - sFile.GetLength() - 1);
              sPathInfo.Replace(_T("\\"), _T("/"));
              sLocalFile = sFile;

              //Remove the PathInfo from the incoming parameter
              sURL = sURL.Left(sURL.GetLength() - sPathInfo.GetLength() - 1);

              dwMatchingURL = sClientURL.GetLength() - sPathInfo.GetLength();
              dwMatchingPath = sLocalFile.GetLength();
            }

            nLocalFileData++; //Move over the directory separator
          }
          else
          {
            bContinueParse = FALSE;

            CString sFile(sDirectory + sRelativeFile.Left(nLocalFileData) + sTemp);

            DWORD dwAttributes = GetFileAttributes(sFile);
            if (dwAttributes == INVALID_FILE_ATTRIBUTES)
            {
              sPathInfo = sTemp;
              sPathInfo.Replace(_T("\\"), _T("/"));
              sLocalFile = sDirectory + sRelativeFile.Left(nLocalFileData);

              //Remove the PathInfo from the incoming parameter
              sURL = sURL.Left(sURL.GetLength() - sPathInfo.GetLength());

              dwMatchingURL = sClientURL.GetLength() - sPathInfo.GetLength();
              dwMatchingPath = sLocalFile.GetLength();
            }
          }
        }

        bDirectory = pDirectory->GetDirectoryListing() && (((GetFileAttributes(sLocalFile) & FILE_ATTRIBUTE_DIRECTORY) != 0));
        if (bDirectory)
        {
          int nURLLength = sURL.GetLength();
          if (nURLLength && sURL.GetAt(nURLLength-1) != _T('/'))
            sURL += _T("/");
        }

      }

      bSuccess = TRUE;
    }
  }

  return bSuccess;
}

#ifdef _DEBUG
void CHttpClient::PostLog(int nHTTPStatusCode, DWORD dwBodyLength)
#else
void CHttpClient::PostLog(int /*nHTTPStatusCode*/, DWORD /*dwBodyLength*/)
#endif
{
#ifdef _DEBUG
  //The default is to just TRACE the details

  //Get the current date and time
  time_t now = time(NULL);
  tm* pNow = localtime(&now);

  //Get the time zone information
  TIME_ZONE_INFORMATION tzi;
  GetTimeZoneInformation(&tzi);

  //Format the date and time appropiately
  TCHAR sDateTime[64];
  _tcsftime(sDateTime, 64, _T("[%d/%b/%Y:%H:%M:%S"), pNow);

  //Display the connections to the console window
  CString sUser(m_Request.m_sUsername);
  if (sUser.IsEmpty())
    sUser = _T("-");
  TRACE(_T("%d.%d.%d.%d - %s %s %04d] \"%s\" %d %d\n"), 
        m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b1,
        m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b2, 
        m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b3, 
        m_Request.m_ClientAddress.sin_addr.S_un.S_un_b.s_b4, 
        sUser, sDateTime, tzi.Bias, m_Request.m_sRequest, nHTTPStatusCode, dwBodyLength);
#endif        
}

BOOL CHttpClient::TransmitFile(CHttpSocket& socket, CHttpResponseHeader& responseHdr, HANDLE hFile, DWORD dwSize, DWORD dwTimeout)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //Assume the worst
  BOOL bSuccess = FALSE;

#ifdef W3MFC_SSL_SUPPORT
  BOOL bTryUsingSendExtension = (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE);
#else
  BOOL bTryUsingSendExtension = TRUE;
#endif

  if (bTryUsingSendExtension && _W3MFCData.m_lpfnTransmitFile)
  {
    bSuccess = _W3MFCData.TransmitFile(socket, responseHdr, hFile, dwSize);

    //Handle the error
    if (!bSuccess)
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpClient::TransmitFile, Failed to send response via TransmitFile, Error:%d"), ::GetLastError());
      m_pServer->OnError(sError);
    }
  }
  else
  {
    //Send the header
#ifdef W3MFC_SSL_SUPPORT
    bSuccess = responseHdr.Send(m_Socket, dwTimeout, m_SSL);
#else
    bSuccess = responseHdr.Send(socket, dwTimeout);
#endif
    if (!bSuccess)
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpClient::TransmitFile, Failed to send to response header, Error:%d"), ::GetLastError());
      m_pServer->OnError(sError);
    }

    //Send the body
    if (bSuccess)
    {
      try
      {
        char sBuf[4096];
        DWORD dwBytesRead = 0;
        do 
        {
          if (::ReadFile(hFile, sBuf, 4096, &dwBytesRead, NULL) && dwBytesRead)
#ifdef W3MFC_SSL_SUPPORT
            socket.SendWithRetry(sBuf, dwBytesRead, dwTimeout, m_SSL);
#else
            socket.SendWithRetry(sBuf, dwBytesRead, dwTimeout);
#endif
        } 
        while (dwBytesRead);
        bSuccess = TRUE;
      }
      catch(CWSocketException* pEx)
      {
        //Report the error
        CString sError;
        sError.Format(_T("CHttpClient::TransmitFile, Failed to send response file data, Error:%d"), pEx->m_nError);
        m_pServer->OnError(sError);

        pEx->Delete();  
      }
    }
  }

  return bSuccess;
}

BOOL CHttpClient::TransmitBuffer(CHttpSocket& socket, CHttpResponseHeader& responseHdr, BYTE* byData, DWORD dwSize, DWORD dwTimeout)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //Assume the worst
  BOOL bSuccess = FALSE;

#ifdef W3MFC_SSL_SUPPORT
  BOOL bTryUsingSendExtension = (pSettings->m_SSLProtocol == CHttpServerSettings::SSL_NONE);
#else
  BOOL bTryUsingSendExtension = TRUE;
#endif

  if (bTryUsingSendExtension && _W3MFCData.m_lpfnTransmitPackets)
  {
    bSuccess = _W3MFCData.TransmitBuffer(socket, responseHdr, byData, dwSize);
    if (!bSuccess)
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpClient::TransmitBuffer, Failed to send response via TransmitPackets, Error:%d"), ::GetLastError());
      m_pServer->OnError(sError);
    }
  }
  else
  {
    //Send the header
#ifdef W3MFC_SSL_SUPPORT
    bSuccess = responseHdr.Send(socket, dwTimeout, m_SSL);
#else
    bSuccess = responseHdr.Send(socket, dwTimeout);
#endif
    if (!bSuccess)
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpClient::TransmitBuffer, Failed to send to response header, Error:%d"), ::GetLastError());
      m_pServer->OnError(sError);
    }

    //Send the body
    if (bSuccess && dwSize)
    {
      try
      {
#ifdef W3MFC_SSL_SUPPORT
        socket.SendWithRetry(byData, dwSize, dwTimeout, m_SSL);
#else
        socket.SendWithRetry(byData, dwSize, dwTimeout);
#endif
        bSuccess = TRUE;
      }
      catch(CWSocketException* pEx)
      {
        //Report the error
        CString sError;
        sError.Format(_T("CHttpClient::TransmitBuffer, Failed to send to response body, Error:%d"), pEx->m_nError);
        m_pServer->OnError(sError);

        pEx->Delete();  
      }
    }
  }

  return bSuccess;
}

void CHttpClient::SetRequestToStop()
{
  //Let the base class do its thing
  CThreadPoolClient::SetRequestToStop();

  //Set the event which signals that we want this worker thread to exit
  m_StopEvent.SetEvent();
}

BOOL CHttpClient::GetKeySizeServerVariable(int& nKeySize)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //What will be the return value
  BOOL bSuccess = FALSE;
  nKeySize = 0;

#ifdef W3MFC_SSL_SUPPORT
  if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  {
    SSL_get_cipher_bits(m_SSL, &nKeySize);
    bSuccess = TRUE;
  }
#endif

  return bSuccess;
}

BOOL CHttpClient::GetServerKeySizeServerVariable(int& nKeySize)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //What will be the return value
  BOOL bSuccess = FALSE;
  nKeySize = 0;

#ifdef W3MFC_SSL_SUPPORT
  if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  {
    EVP_PKEY* pKey = SSL_get_privatekey(m_SSL);
    if (pKey)
    {
      nKeySize = EVP_PKEY_bits(pKey);
      bSuccess = TRUE;
    }
  }
#endif

  return bSuccess;
}

BOOL CHttpClient::GetCertSerialNumberServerVariable(long& nSerialNumber)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //What will be the return value
  BOOL bSuccess = FALSE;
  nSerialNumber = 0;

#ifdef W3MFC_SSL_SUPPORT
  if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  {
    X509* pCert = SSL_get_certificate(m_SSL);
    if (pCert)
    {
      ASN1_INTEGER* pSerialNumber = X509_get_serialNumber(pCert);
      if (pSerialNumber)
      {
        nSerialNumber = ASN1_INTEGER_get(pSerialNumber);
        bSuccess = TRUE;
      }
    }
  }
#endif

  return bSuccess;
}

BOOL CHttpClient::GetCertIssuerServerVariable(char*& szIssuer)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //What will be the return value
  BOOL bSuccess = FALSE;
  szIssuer = NULL;

#ifdef W3MFC_SSL_SUPPORT
  if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  {
    X509* pCert = SSL_get_certificate(m_SSL);
    if (pCert)
    {
      szIssuer = X509_NAME_oneline(X509_get_issuer_name(pCert), NULL, NULL);
      bSuccess = TRUE;
    }
  }
#endif

  return bSuccess;  
}

BOOL CHttpClient::GetCertSubjectServerVariable(char*& szSubject)
{
  //Validate our parameters
  ASSERT(m_pServer);
  CHttpServerSettings* pSettings = m_pServer->GetSettings();
  ASSERT(pSettings);

  //What will be the return value
  BOOL bSuccess = FALSE;
  szSubject = NULL;

#ifdef W3MFC_SSL_SUPPORT
  if (pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  {
    X509* pCert = SSL_get_certificate(m_SSL);
    i

⌨️ 快捷键说明

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