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

📄 httpmt.c

📁 http服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 0;
}

////////////////////////////////////////////////////////////

BOOL RecvRequest(LPREQUEST lpReq, LPBYTE pBuf, DWORD dwBufSize)
{
	WSABUF			wsabuf;
	WSAOVERLAPPED	over;
	DWORD			dwRecv;
	DWORD			dwFlags;
	DWORD			dwRet;
	HANDLE			hEvents[2];
	BOOL			fPending;
	int				nRet;

	//
	// Zero the buffer so the recv is null-terminated
	//
	memset(pBuf, 0, dwBufSize);

	//
	// Setup the WSABUF and WSAOVERLAPPED structures
	//
	wsabuf.buf  = pBuf;
	wsabuf.len  = dwBufSize;
	over.hEvent = WSACreateEvent();

	dwFlags = 0;
	fPending = FALSE;
	nRet = WSARecv(lpReq->Socket,	// Socket
				   &wsabuf,			// WSABUF
				   1,				// Number of buffers
				   &dwRecv,			// Bytes received
				   &dwFlags,		// Flags
				   &over,			// WSAOVERLAPPED
				   NULL);			// Completion function
	if (nRet != 0)
	{
		if (WSAGetLastError() != WSA_IO_PENDING)
		{
			LogWinSockError(ghwnd, 
						    "WSARecv()", 
							WSAGetLastError());
			CloseHandle(over.hEvent);
			return FALSE;
		}
		else
			fPending = TRUE;
	}

	//
	// If the I/O isn't finished...
	//
	if (fPending)
	{
		//
		// Wait for the request to complete or the exit event 
		//
		hEvents[0]  = over.hEvent;
		hEvents[1]  = lpReq->hExit;
		dwRet = WaitForMultipleObjects(2,
									   hEvents,
									   FALSE,
									   INFINITE);
		//
		// Was the recv event signaled?
		//
		if (dwRet != 0)
		{
			CloseHandle(over.hEvent);
			return FALSE;
		}
		if (!WSAGetOverlappedResult(lpReq->Socket,
									&over,
									&dwRecv,
									FALSE,
									&dwFlags))
			CloseHandle(over.hEvent);
			return FALSE;
	}
	//
	// Recv event is complete -- keep statistics
	//
	lpReq->dwRecv += dwRecv;
	CloseHandle(over.hEvent);
	return TRUE;
}

////////////////////////////////////////////////////////////

int ParseRequest(LPREQUEST lpReq, LPBYTE lpBuf)
{
	char szSeps[] = " \n";
	char *cpToken;

	//
	// Don't let requests include ".." characters
	// in requests
	//
	if (strstr(lpBuf, "..") != NULL)
	{
		// Send "bad request" error
		return(HTTP_STATUS_BADREQUEST);
	}

	//
	// Determine request method
	//
	cpToken = strtok(lpBuf, szSeps);
	if (!_stricmp(cpToken, "GET"))
		lpReq->nMethod = METHOD_GET;          //GET
	else if(!_stricmp(cpToken, "POST"))
	{
		lpReq->nMethod = METHOD_POST;          //post
	}
	else
	{
		// Send "not implemented" error
		return(HTTP_STATUS_NOTIMPLEMENTED);
	}

	//
	// Get the file name
	//
	cpToken = strtok(NULL, szSeps);
	if (cpToken == NULL)
	{
		// Send "bad request" error
		return(HTTP_STATUS_BADREQUEST);
	}
	strcpy(lpReq->szFileName, szWebRoot);
	if (strlen(cpToken) > 1)
		strcat(lpReq->szFileName, cpToken);
	else
		strcat(lpReq->szFileName, "/index.html");
	return 0;
}

////////////////////////////////////////////////////////////

void CloseConnection(LPREQUEST lpReq)
{
	HTTPSTATS	stats;
	int			nRet;

	//
	// Log the event and close the socket
	//
//	LogEvent(ghwnd, 
//			 "Closing socket: %d",
//			 lpReq->Socket);

	nRet = closesocket(lpReq->Socket);
	if (nRet == SOCKET_ERROR)
	{
		LogWinSockError(ghwnd, 
			 "closesocket()",
			 WSAGetLastError());
	}

	//
	// Give the user interface the stats
	//
	stats.dwElapsedTime = 
			(GetTickCount() - lpReq->dwConnectTime);
	stats.dwRecv = lpReq->dwRecv;
	stats.dwSend = lpReq->dwSend;
//	SendMessage(ghwnd,
//				guAppMsg,
//				HTTP_STATS_MSG,
//				(LPARAM)&stats);

  }

////////////////////////////////////////////////////////////

void SendFile(LPREQUEST lpReq)
{
	//
	// Open the file for reading
	//
	lpReq->hFile = CreateFile(lpReq->szFileName, 
							  GENERIC_READ,
							  FILE_SHARE_READ,
							  NULL,
							  OPEN_EXISTING,
							  FILE_ATTRIBUTE_NORMAL,
							  NULL);
	if (lpReq->hFile == INVALID_HANDLE_VALUE)
	{
		SendMessage(ghwnd,
					guAppMsg,
					HTTP_FILENOTFOUND_MSG,
					(LPARAM)(LPCSTR)lpReq->szFileName);
		// Send "404 Not Found" error
		SendError(lpReq, HTTP_STATUS_NOTFOUND);
		return;
	}

	//
	// Tell the user interface about the file hit
	// (Sending just the request portion -- without
	// the root web directory portion
	//
	SendMessage(ghwnd,
				guAppMsg,
				HTTP_FILEOK_MSG,
				(LPARAM)(LPCSTR)&lpReq->szFileName[strlen(szWebRoot)]);
	//
	// Send the file contents to the client
	//
	SendFileContents(lpReq);

	//
	// Close the file
	//
	if (CloseHandle(lpReq->hFile))
		lpReq->hFile = INVALID_HANDLE_VALUE;
	else
		LogEvent(ghwnd,
				 "Error closing file: %d",
				 GetLastError());
}

////////////////////////////////////////////////////////////

void SendFileContents(LPREQUEST lpReq)
{
	static BYTE buf[1024];
	DWORD  dwRead;
	BOOL   fRet;

	//
	// Read and send data until EOF
	//
	while(1)
	{
		//
		// Read a buffer full from the file
		//
		fRet = ReadFile(lpReq->hFile,
						buf,
						sizeof(buf),
						&dwRead,
						NULL);
		if (!fRet)
		{
			// Send "404 Not Found" error
			SendError(lpReq, HTTP_STATUS_SERVERERROR);
			break;
		}

		if (dwRead == 0)
			break;

		//
		// Send this buffer to the client
		//
		if (!SendBuffer(lpReq, buf, dwRead))
			break;

		//
		// Add for statistics
		//
		lpReq->dwSend += dwRead;
	}
}

////////////////////////////////////////////////////////////

BOOL SendBuffer(LPREQUEST lpReq, LPBYTE pBuf, DWORD dwBufSize)
{
	WSABUF			wsabuf;
	WSAOVERLAPPED	over;
	DWORD			dwRecv;
	DWORD			dwFlags;
	DWORD			dwRet;
	HANDLE			hEvents[2];
	BOOL			fPending;
	int				nRet;

	//
	// Setup the WSABUF and WSAOVERLAPPED structures
	//
	wsabuf.buf  = pBuf;
	wsabuf.len  = dwBufSize;
	over.hEvent = WSACreateEvent();

	fPending = FALSE;
	nRet = WSASend(lpReq->Socket,	// Socket
				   &wsabuf,			// WSABUF
				   1,				// Number of buffers
				   &dwRecv,			// Bytes received
				   0,				// Flags
				   &over,			// WSAOVERLAPPED
				   NULL);			// Completion function
	if (nRet != 0)
	{
		if (WSAGetLastError() == WSA_IO_PENDING)
			fPending = TRUE;
		else
		{
			LogWinSockError(ghwnd, 
							"WSASend()", 
							WSAGetLastError());
			CloseHandle(over.hEvent);
			return FALSE;
		}
	}

	//
	// If the I/O isn't finished...
	//
	if (fPending)
	{
		//
		// Wait for the request to complete 
		// or the exit event to be signaled
		//
		hEvents[0]  = over.hEvent;
		hEvents[1]  = lpReq->hExit;
		dwRet = WaitForMultipleObjects(2,
									   hEvents,
									   FALSE,
									   INFINITE);
		//
		// Was the recv event signaled?
		//
		if (dwRet != 0)
		{
			CloseHandle(over.hEvent);
			return FALSE;
		}

		//
		// Get I/O result
		//
		if (!WSAGetOverlappedResult(lpReq->Socket,
									&over,
									&dwRecv,
									FALSE,
									&dwFlags))
		{
			LogWinSockError(ghwnd, 
							"WSAGetOverlappedResult()", 
							WSAGetLastError());
			CloseHandle(over.hEvent);
			return FALSE;
		}
	}

	CloseHandle(over.hEvent);
	return TRUE;
}

////////////////////////////////////////////////////////////

void SendError(LPREQUEST lpReq, UINT uError)
{
	static char szMsg[512];
	static char *szStatMsgs [] = {
								"200 OK",
								"201 Created",
								"202 Accepted",
								"204 No Content",
								"301 Moved Permanently",
								"302 Moved Temporarily",
								"304 Not Modified",
								"400 Bad Request",
								"401 Unauthorized",
								"403 Forbidden",
								"404 Not Found",
								"500 Internal Server Error",
								"501 Not Implemented",
								"502 Bad Gateway",
								"503 Service Unavailable"
								};
	#define NUMSTATMSGS sizeof(szStatMsgs) / sizeof(szStatMsgs[0])

	if (uError < 0 || uError > NUMSTATMSGS)
		return;

	wsprintf(szMsg, "<body><h1>%s</h1></body>",
				 szStatMsgs[uError]);
	send(lpReq->Socket,
		 szMsg,
		 strlen(szMsg),
		 0);
}

////////////////////////////////////////////////////////////

void LogEvent(HWND hwnd, LPCSTR lpFormat, ...)
{
	va_list Marker;
	char szBuf[256];
	
	// Write text to string
	// and append to edit control
	va_start(Marker, lpFormat);
	vsprintf(szBuf, lpFormat, Marker);
	va_end(Marker);
	SendMessage(ghwnd,
				guAppMsg,
				HTTP_EVENT_MSG,
				(LPARAM)szBuf);
}

////////////////////////////////////////////////////////////

void LogWinSockError(HWND hwnd, LPCSTR lpText, int nErrorCode)
{
	char szBuf[256];

	szBuf[0] = '\0';
	LoadString(GetWindowInstance(hwnd),
			   nErrorCode,
			   szBuf,
			   sizeof(szBuf));
	LogEvent(hwnd, "%s : %s", lpText, szBuf);
}

////////////////////////////////////////////////////////////

int GetLocalAddress(LPSTR lpStr, LPDWORD lpdwStrLen)
{
    struct in_addr *pinAddr;
    LPHOSTENT	lpHostEnt;
	int			nRet;
	int			nLen;

	//
	// Get our local name
	//
    nRet = gethostname(lpStr, *lpdwStrLen);
	if (nRet == SOCKET_ERROR)
	{
		lpStr[0] = '\0';
		return SOCKET_ERROR;
	}

	//
	// "Lookup" the local name
	//
	lpHostEnt = gethostbyname(lpStr);
    if (lpHostEnt == NULL)
	{
		lpStr[0] = '\0';
		return SOCKET_ERROR;
	}

	//
    // Format first address in the list
	//
	pinAddr = ((LPIN_ADDR)lpHostEnt->h_addr);
	nLen = strlen(inet_ntoa(*pinAddr));
	if ((DWORD)nLen > *lpdwStrLen)
	{
		*lpdwStrLen = nLen;
		WSASetLastError(WSAEINVAL);
		return SOCKET_ERROR;
	}

	*lpdwStrLen = nLen;
	strcpy(lpStr, inet_ntoa(*pinAddr));
    return 0;
}

⌨️ 快捷键说明

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