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

📄 w3mfc.cpp

📁 MiniCA V2.0版本源码。《小型CA系统V2.1含源码》发表以来
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    OnError(sError);
    return FALSE;
  }
  m_pListenThread->m_bAutoDelete = FALSE;
  m_pListenThread->ResumeThread();

  //Wait until the thread has completely started and return the success indicator
  ::WaitForSingleObject(m_ListenStartEvent, INFINITE);
  return m_bListenerRunningOK;
}

BOOL CHttpServer::Wait()
{
  CSingleLock sl(&m_csListenThread, TRUE); //synchronize access to the listening thread

  //If the listener thread is running, then just wait for it to exit
  if (m_pListenThread)
  {
    ::WaitForSingleObject(m_pListenThread->m_hThread, INFINITE);
    delete m_pListenThread;
    m_pListenThread = NULL;
    return TRUE;
  }
  else
  {
    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::Wait, Http server is not running, so no need to wait"));
    OnError(sError);
    return FALSE;
  }
}

BOOL CHttpServer::Stop()
{
  //Signal the listener thread to stop and wait for it to do so, Note that we do 
  //this before we enter the critical section because otherwise we could end
  //up in a deadlock situation between this function and Wait
  m_StopEvent.SetEvent();

  CSingleLock sl(&m_csListenThread, TRUE); //synchronize access to the listening thread

  //If the listener thread is running, then stop it
  if (m_pListenThread)
  {
    ::WaitForSingleObject(m_pListenThread->m_hThread, INFINITE);
    delete m_pListenThread;
    m_pListenThread = NULL;

    //Release SSPI
#ifndef W3MFC_NO_SSPI_SUPPORT
    ReleaseSSPI();
#endif
  }

  return TRUE;
}

BOOL CHttpServer::ReverseDNSLookup(in_addr sin_addr, CString& sDomainName)
{
  BOOL bSuccess = FALSE;
  HOSTENT* pHostEnt = gethostbyaddr((const char*) &sin_addr, sizeof(sin_addr), AF_INET); 
  if (pHostEnt)
  {
    bSuccess = TRUE;
    sDomainName = pHostEnt->h_name;
  }

  return bSuccess;
}

#ifdef W3MFC_SSL_SUPPORT
void CHttpServer::LogSSLErrors()
{
  char sError[1024];
  unsigned long nError;
  do
  { 
    nError = ERR_get_error();
    if (nError)
    {
      ERR_error_string(nError, sError);
      OnError(sError);
    }
  }
  while (nError);
}
#endif


CString CHttpServer::ErrorString()
{
	DWORD err = ::GetLastError();
	CString Error;
	LPTSTR s;
	if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		err,
		0x0409,
		(LPTSTR)&s,
		0,
		NULL) == 0)
    { /* failed */
		// Unknown error code %08x (%d)
		CString fmt;
		CString t;
		fmt.LoadString(IDS_UNKNOWN_ERROR);
		t.Format(fmt, err, LOWORD(err));
		Error = t;
    } /* failed */
	else
    { /* success */
		LPTSTR p = _tcschr(s, _T('\r'));
		if(p != NULL)
        { /* lose CRLF */
			*p = _T('\0');
        } /* lose CRLF */
		Error = s;
		::LocalFree(s);
    } /* success */
	return Error;
}
                               
void CHttpServer::ListenSocketFunction()
{
  USES_CONVERSION;

  //Setup the thread pool 
  ASSERT(m_pSettings);
  ASSERT(m_pSettings->m_pRuntimeClientClass);
  if (!m_ThreadPool.Start(m_pSettings->m_pRuntimeClientClass, m_pSettings->m_bUseIOCPQueue ? RUNTIME_CLASS(CIOCPThreadPoolQueue) : RUNTIME_CLASS(CHttpDirectedThreadPoolQueue), 
                          m_pSettings->m_nThreadPoolSize, m_pSettings->m_nThreadPoolSize, TRUE))
  {
    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to create thread pool, GetLastError:%d"), ::GetLastError());
    OnError(sError);
    m_ListenStartEvent.SetEvent();
    return;
  }

  //Setup the pointers in the thread pool instances and resume the threads
  for (int i=0; i<m_pSettings->m_nThreadPoolSize; i++)
  {
    CHttpClient* pClient = (CHttpClient*) m_ThreadPool.GetAtClient(i);
    ASSERT(pClient);
    ASSERT(pClient->IsKindOf(RUNTIME_CLASS(CHttpClient)));
    pClient->m_pServer = this;
    pClient->m_pWorkerThread->ResumeThread();
  }

  //Setup the recycling of threads
  if (!m_ThreadPool.SetMaxThreadClientLifetime(m_pSettings->m_bEnableThreadLifetime, m_pSettings->m_dwThreadLifetime))
  {
    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::ListenSocketFunction, Failed in call to m_ThreadPool.SetMaxThreadClientLifetime, GetLastError:%d"), GetLastError());
    OnError(sError);

    m_ListenStartEvent.SetEvent();
    return;
  }

  //Create the server socket
  CHttpSocket serverSocket;
  try
  {
    serverSocket.Create();
  }
  catch(CWSocketException* pEx)
  {
    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to create server socket, GetLastError:%d"), pEx->m_nError);
    OnError(sError);

    m_ListenStartEvent.SetEvent();
    pEx->Delete();  
    return;
  }

  //Bind the server socket
  try
  {
    if (m_pSettings->m_bBind)
      serverSocket.Bind(m_pSettings->m_nPort, m_pSettings->m_sBindAddress);
    else
      serverSocket.Bind(m_pSettings->m_nPort);
  }
  catch(CWSocketException* pEx)
  {
    //Report the error
    CString sError;
    sError.Format(_T("Error Code:%d  %s"), pEx->m_nError,  ErrorString());
    OnError(sError);

    m_ListenStartEvent.SetEvent();
    pEx->Delete();  
    return;
  }

  //Put the server socket in a listening state
  try
  {
    serverSocket.Listen();
  }
  catch(CWSocketException* pEx)
  {
    //Report the error
    CString sError;
    sError.Format(_T("Error Code:%d  %s"), pEx->m_nError,  ErrorString());
    OnError(sError);

    m_ListenStartEvent.SetEvent();
    pEx->Delete();
    return;
  }

  //Run the server under a different account if configured to do so
  BOOL bUseAccount = (m_pSettings->m_sUsername.GetLength() != 0);
  CW32Handle hImpersonation;
  BOOL bLoggedOn = FALSE;
  BOOL bImpersonated = FALSE;
  if (bUseAccount)
  {
    LPTSTR pszUser = m_pSettings->m_sUsername.GetBuffer(m_pSettings->m_sUsername.GetLength());
    LPTSTR pszPassword = m_pSettings->m_sPassword.GetBuffer(m_pSettings->m_sPassword.GetLength());
    HANDLE hRawImpersonation = NULL;
    bLoggedOn = LogonUser(pszUser, NULL, pszPassword, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hImpersonation);
    if (bLoggedOn)
    {
      hImpersonation.Attach(hRawImpersonation);
      bImpersonated = ImpersonateLoggedOnUser(hImpersonation);
    }
    else
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to logon using user name: %s, GetLastError:%d"), pszUser, ::GetLastError());
      OnError(sError);
    }
    m_pSettings->m_sUsername.ReleaseBuffer();
    m_pSettings->m_sPassword.ReleaseBuffer();

    //Clear the password now that we are finished with it
    m_pSettings->m_sPassword.Empty();
  } 
  m_hImpersonation = hImpersonation; 

  //Handle the case if the impersonation failed
  if (bUseAccount && !bImpersonated)
  {
    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to impersonate using supplied user credentials"));
    OnError(sError);

    m_ListenStartEvent.SetEvent();
    return;
  }

  //Initialize SSL context if required to do so
#ifdef W3MFC_SSL_SUPPORT
  //Initialize the PRNG in OpenSSL
  if (m_pSettings->m_sSSLRandomnessFile.IsEmpty())
  {
    //Get the default rand file from OpenSSL
    char sSSLFile[1024];
    const char* pszRandFile = RAND_file_name(sSSLFile, sizeof(sSSLFile));
    if (pszRandFile)
      m_pSettings->m_sSSLRandomnessFile = pszRandFile;
    else
    {
      //Report the error
      CString sError;
      sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to get the default RAND file from OpenSSL"));
      OnError(sError);

      LogSSLErrors();
    }
  }
  RAND_load_file(T2A((LPTSTR)(LPCTSTR)m_pSettings->m_sSSLRandomnessFile), -1);
  if (RAND_status() == 0)
  {
    //Report the error
    CString sError;
    sError.Format(_T("CHttpServer::ListenSocketFunction, Failed to initialize the PRNG in OpenSSL"));
    OnError(sError);

    LogSSLErrors();

    //Failing to initialize the PRNG is not considered critical for W3MFC
  }

  CSSLContext sslContext;
  if (m_pSettings->m_SSLProtocol != CHttpServerSettings::SSL_NONE)
  {

⌨️ 快捷键说明

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