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

📄 httpmain.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
DWORD WINAPI InitializeGlobalsThread(LPVOID lpv) {
	MyWaitForAdminThreadReadyState();

	DEBUGCHK(g_fState == SERVICE_STATE_STARTING_UP);

	InitializeGlobals();
	CloseHandle(g_hAdminThread);
	g_hAdminThread = 0;
	return 0;
}

DWORD WINAPI HttpConnectionThread(LPVOID lpv) {
	CHttpRequest *pRequest = (CHttpRequest*) lpv;
	DEBUGCHK(pRequest && pRequest->m_dwSig == CHTTPREQUEST_SIG);

	SOCKET sock = pRequest->m_socket;

	// this outer _try--_except is to catch crashes in the destructor
	__try {
		__try {
			// This loops as long the the socket is being kept alive 
			for(;;) {				
				pRequest->HandleRequest();
					
				// figure out if we must keep this connection alive,
				// Either session is over through this request's actions or
				// globally set to accept no more connections.

				// We do the global g_pVars->m_fAcceptConnections check 
				// because it's possible that we may be in the process of 
				// shutting down the web server, in which case we want to
				// exit even if we're performing a keep alive.
				if(! (g_pVars->m_fAcceptConnections && pRequest->m_fKeepAlive)) {
					if(g_pVars->m_fFilters)
						pRequest->CallFilter(SF_NOTIFY_END_OF_NET_SESSION);
					break;
				}

				// If we're continuing the session don't delete all data, just request specific data
				if ( ! pRequest->ReInit())
					break;
			}
		}
		__finally {
			// Note:  To get this to compile under Visual Studio on NT, the /Gx- compile line option is set
			delete pRequest;
			pRequest = 0;
		}
	}
	__except(ReportFault(GetExceptionInformation(),0), EXCEPTION_EXECUTE_HANDLER) {
		RETAILMSG(1, (L"HTTP Server got an exception!!!\r\n"));
		g_pVars->m_pLog->WriteEvent(IDS_HTTPD_EXCEPTION,GetExceptionCode(),GetLastError());
	}

	return 0;
}
 

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
//  UTILITY FUNCTIONS
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
void WaitForConnectionThreadsToEnd(void) {
	DEBUGCHK (g_fState == SERVICE_STATE_SHUTTING_DOWN || g_fState == SERVICE_STATE_UNLOADING);

	//  NOTE.  It's possible ASP pages or ISAPI extns may have an 
	//  infinite loop in them, in which case we never decrement this value and
	//  never get to stop the server.  There is no clean way to fix this.

	DEBUGMSG(ZONE_LISTEN,(L"HTTPD: Wating for %d HTTP threads to come to a halt\r\n", g_pVars->m_nConnections));
	g_pVars->m_pLog->WriteEvent(IDS_HTTPD_SHUTDOWN_START);

	g_pVars->m_pThreadPool->Shutdown();
	DEBUGCHK(g_pVars->m_nConnections == 0);
	DEBUGMSG(ZONE_LISTEN,(L"HTTPD: All HTTPD threads have come to halt, shutting down server\r\n"));
}

// Note: This function is executed on the super services accept thread, blocking all 
// other services from receiving new connections.  Need to execute this code as quickly as possible.
BOOL CreateHTTPConnection(SOCKET sock, PSOCKADDR pSockAddr, DWORD cbSockAddr) {
	DEBUG_CODE_INIT;
	BOOL fRet        = FALSE;
	CHttpRequest     *pRequest = NULL;
	BOOL fSecure;

	EnterCriticalSection(&g_CritSect);
	DEBUGCHK(g_pVars->m_nConnections <= g_pVars->m_nMaxConnections);
	
	if (g_pVars->m_nConnections + 1 > g_pVars->m_nMaxConnections)  {
		DEBUGMSG(ZONE_ERROR, (TEXT("HTTPD: Connection Count -- Reached maximum # of connections, won't accept current request.")));
		send(sock,g_pVars->m_szMaxConnectionMsg,strlen(g_pVars->m_szMaxConnectionMsg),0);
		myleave(59);
	}

	fSecure = g_pVars->IsSecureSocket(pSockAddr,cbSockAddr);
	if (fSecure && !g_pVars->m_fSSL) {
		DEBUGMSG(ZONE_ERROR,(L"HTTPD: Request fails because client requests SSL, SSL not activated\r\n"));
		goto done;
	}			

	pRequest = new CHttpRequest(sock,fSecure);
	if (!pRequest)
		myleave(60);

	g_pVars->m_nConnections++;

	if (! g_pVars->m_pThreadPool->ScheduleEvent(HttpConnectionThread,(LPVOID) pRequest))
		myleave(61);

	fRet = TRUE;
done:
	if (!fRet) {
		SetLastError(ERROR_SERVICE_CANNOT_ACCEPT_CTRL);
		shutdown(sock, 1);
		closesocket(sock);

		if (pRequest)
			delete pRequest; // pRequest destructor decrements m_nConnections
	}
	LeaveCriticalSection(&g_CritSect);

	return fRet;
}

// When we get a connection socket from IOCTL_SERVICE_CONNECTION, need to determine if 
// it's an SSL sock or not.  We'll only accept SSL over TCP/IP port 443, so should 
// getsockname() fail (for instance in case where service provider had a larger SOCKADDR) assume
// clear text.
BOOL CGlobalVariables::IsSecureSocket(PSOCKADDR pSockAddr, DWORD cbSockAddr) {
	if ((pSockAddr->sa_family == AF_INET || pSockAddr->sa_family == AF_INET6)) 
	{
		return (GetSocketPort(pSockAddr) == htons((WORD)m_dwSSLPort));
	}
	return FALSE;
}

// runs through active sockets and closes them during shutdown.  This will cause
// any threads waiting for recv timeouts to exit more promptly.  It will not help
// in the case of an ISAPI or ASP page in an infinite loop, only TerminateThread will
// do the trick there, and we're not willing to do this given how much it'd gunk up services.exe.
void CloseAllConnections(void) {
	EnterCriticalSection(&g_CritSect);
	CHttpRequest *pTrav = g_pRequestList;

	while (pTrav) {
		pTrav->CloseSocket();
		pTrav = pTrav->m_pNext;
		// leave it to the ~CHttpRequest to remove itself from the list and do its own memory cleanup.
	}

	LeaveCriticalSection(&g_CritSect);
}

DWORD WINAPI PeriodicWakeupThread(LPVOID lpv) {
	EnterCriticalSection(&g_CritSect);
	if (g_pVars && g_pVars->m_pISAPICache)
		g_pVars->m_pISAPICache->RemoveUnusedISAPIs(FALSE);

	if (g_pFileLockManager)
		g_pFileLockManager->RemoveTimedOutLocks();

	g_pTimer->ScheduleEvent(PeriodicWakeupThread,0,PERIODIC_TIMER_SLEEP_TIMEOUT);
	LeaveCriticalSection(&g_CritSect);

	return 0;
}

PSTR MassageMultiStringToAnsi(PCWSTR wszIn, PCWSTR wszDefault) {
	if(!wszIn) wszIn = wszDefault;
	if(!wszIn) return NULL;

	int iAlloc = MyW2A(wszIn,0,0);
	if (!iAlloc)
		return NULL;

	iAlloc++; // +1 for dbl-null term

	PSTR szBuffer = MySzAllocA(iAlloc); 
	if (!szBuffer)
		return NULL;

	MyW2A(wszIn,szBuffer,iAlloc);
	PSTR szRead  = szBuffer;
	PSTR szWrite = szBuffer;

	// now that we've converted buffer, write out in place.
	for ( ; *szRead; szRead++, szWrite++) {
		PREFAST_SUPPRESS(394,"Updating buffer pointer is safe here");
		*szWrite = (*szRead==';' ? '\0' : *szRead);

		// Ignore space between ";" and next non-space
		if (';' == *szRead || 0 == *szRead) {
			szRead++;
			svsutil_SkipWhiteSpace(szRead);
			szRead--;		// otherwise we skip first char of new string.	
		}
	}
	szWrite[0] = szWrite[1] = 0; // dbl-null

	DEBUGCHK((szWrite - szBuffer + 2) <= iAlloc);
	return szBuffer;
}


PWSTR MassageMultiString(PCWSTR wszIn, PCWSTR wszDefault) {
	if(!wszIn) wszIn = wszDefault;
	if(!wszIn) return NULL;
	
	PWSTR wszOut = MyRgAllocNZ(WCHAR, 2+wcslen(wszIn)); // +2 for dbl-null term
	if (!wszOut)
		return NULL;

	for(PWSTR wszNext=wszOut; *wszIn; wszIn++, wszNext++) {
		PREFAST_SUPPRESS(394,"Updating buffer pointer is safe here");
		*wszNext = (*wszIn==L';' ? L'\0' : *wszIn);

		// Ignore space between ";" and next non-space
		if ( L';' == *wszIn) {
			wszIn++;
			svsutil_SkipWWhiteSpace(wszIn);
			wszIn--;		// otherwise we skip first char of new string.	
		}
	}
	wszNext[0] = wszNext[1] = 0; // dbl-null
	return wszOut;
}


BOOL GetRemoteAddress(SOCKET sock, PSTR pszBuf, BOOL fTryHostName, DWORD cbBuf) {
	SOCKADDR_STORAGE sockAddr;
	int iLen = sizeof(sockAddr);

	*pszBuf=0;
	if(getpeername(sock, (PSOCKADDR)&sockAddr, &iLen)) {
		DEBUGMSG(ZONE_SOCKET, (L"HTTPD: getpeername failed GLE=%d\r\n", GetLastError()));
		return FALSE;
	}

	if (fTryHostName && (0 == getnameinfo((PSOCKADDR)&sockAddr,iLen,pszBuf,cbBuf,NULL,0,0)))
		return TRUE;

	// if getnameinfo fails on resolving host name, fall through to use IP ADDR.
	return (0 == getnameinfo((PSOCKADDR)&sockAddr,iLen,pszBuf,cbBuf,NULL,0,NI_NUMERICHOST));
}

PSTR MySzDupA(PCSTR pszIn, int iLen) { 
	if(!pszIn) return NULL;
	if(!iLen) iLen = strlen(pszIn);
	PSTR pszOut=MySzAllocA(iLen);
	if(pszOut) {
		memcpy(pszOut, pszIn, iLen); 
		pszOut[iLen] = 0;
	}
	return pszOut; 
}

PWSTR MySzDupW(PCWSTR wszIn, int iLen) { 
	if(!wszIn) return NULL;
	if(!iLen) iLen = wcslen(wszIn);
	PWSTR wszOut=MySzAllocW(iLen);
	if(wszOut) {
		memcpy(wszOut, wszIn, sizeof(WCHAR)*iLen); 
		wszOut[iLen] = 0;
	}
	return wszOut; 
}

PWSTR MySzDupAtoW(PCSTR pszIn, int iInLen) {
	PWSTR pwszOut = 0;
	int   iOutLen = MultiByteToWideChar(CP_ACP, 0, pszIn, iInLen, 0, 0);
	if(!iOutLen)
		goto error;
	pwszOut = MySzAllocW(iOutLen);
	if(!pwszOut)
		goto error;
	if(MultiByteToWideChar(CP_ACP, 0, pszIn, iInLen, pwszOut, iOutLen))
		return pwszOut;

error:
	DEBUGMSG(ZONE_ERROR, (L"HTTPD: MySzDupAtoW(%a, %d) failed. pOut=%0x08x GLE=%d\r\n", pszIn, iInLen, pwszOut, GetLastError()));
	MyFree(pwszOut);
	return FALSE;
}

PSTR MySzDupWtoA(PCWSTR wszIn, int iInLen) {
	PSTR pszOut = 0;
	int   iOutLen = WideCharToMultiByte(CP_ACP, 0, wszIn, iInLen, 0, 0, 0, 0);
	if(!iOutLen)
		goto error;
	pszOut = MySzAllocA(iOutLen);
	if(!pszOut)
		goto error;
	if(WideCharToMultiByte(CP_ACP, 0, wszIn, iInLen, pszOut, iOutLen, 0, 0))
		return pszOut;

error:
	DEBUGMSG(ZONE_ERROR, (L"HTTPD: MySzDupWtoA(%s, %d) failed. pOut=%0x08x GLE=%d\r\n", wszIn, iInLen, pszOut, GetLastError()));
	MyFree(pszOut);
	return FALSE;
}

BOOL MyStrCatA(PSTR *ppszDest, PSTR pszSource, PSTR pszDivider) {
	DEBUG_CODE_INIT;
	BOOL ret = FALSE;
	PSTR pszNew = *ppszDest;  // protect orignal ptr should realloc fail
	PSTR pszTrav;
	DWORD dwSrcLen = MyStrlenA(pszSource);
	DWORD dwDestLen = MyStrlenA(*ppszDest);
	DWORD dwDivLen = MyStrlenA(pszDivider);

	if (!pszSource)  {
		SetLastError(ERROR_INVALID_PARAMETER);
		myleave(259);
	}

	if (!pszNew)  {  // do an alloc first time, ignore divider
		if (NULL == (pszNew = MySzDupA(pszSource,dwSrcLen)))
			myleave(260);
	}
	else {
		if (NULL == (pszNew = MyRgReAlloc(char,pszNew,dwDestLen,dwSrcLen + dwDestLen + dwDivLen + 1)))
			myleave(261);

		pszTrav = pszNew + dwDestLen;
		if (pszDivider)  {
			memcpy(pszTrav, pszDivider, dwDivLen);
			pszTrav += dwDivLen;
		}
		
		strcpy(pszTrav, pszSource);
	}
	
	*ppszDest = pszNew;
	ret = TRUE;
done:
	DEBUGMSG_ERR(ZONE_ERROR,(L"HTTPD: MyStrCat err = %d\r\n",GetLastError()));
	
	return ret;
}

/*===================================================================
strcpyEx

Copy one string to another, returning a pointer to the NUL character
in the destination

Parameters:
    szDest - pointer to the destination string
    szSrc - pointer to the source string

Returns:
    A pointer to the NUL terminator is returned.
===================================================================*/

char *strcpyEx(char *szDest, const char *szSrc) {
	while (*szDest++ = *szSrc++)
		;
	return szDest - 1;
}

⌨️ 快捷键说明

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