#include "QHttpServer.h"
VISVECTOR visitsip;
REQUESTSTR reqinfo;
LOGSTR serverlog;
QHttpServer::QHttpServer()
{
bRun = FALSE;
// 初始化 MIME 类型
MimeTypes["doc"] = "application/msword";
MimeTypes["bin"] = "application/octet-stream";
MimeTypes["dll"] = "application/octet-stream";
MimeTypes["exe"] = "application/octet-stream";
MimeTypes["pdf"] = "application/pdf";
MimeTypes["p7c"] = "application/pkcs7-mime";
MimeTypes["ai"] = "application/postscript";
MimeTypes["eps"] = "application/postscript";
MimeTypes["ps"] = "application/postscript";
MimeTypes["rtf"] = "application/rtf";
MimeTypes["fdf"] = "application/vnd.fdf";
MimeTypes["arj"] = "application/x-arj";
MimeTypes["gz"] = "application/x-gzip";
MimeTypes["class"] = "application/x-java-class";
MimeTypes["js"] = "application/x-javascript";
MimeTypes["lzh"] = "application/x-lzh";
MimeTypes["lnk"] = "application/x-ms-shortcut";
MimeTypes["tar"] = "application/x-tar";
MimeTypes["hlp"] = "application/x-winhelp";
MimeTypes["cert"] = "application/x-x509-ca-cert";
MimeTypes["zip"] = "application/zip";
MimeTypes["cab"] = "application/x-compressed";
MimeTypes["arj"] = "application/x-compressed";
MimeTypes["aif"] = "audio/aiff";
MimeTypes["aifc"] = "audio/aiff";
MimeTypes["aiff"] = "audio/aiff";
MimeTypes["au"] = "audio/basic";
MimeTypes["snd"] = "audio/basic";
MimeTypes["mid"] = "audio/midi";
MimeTypes["rmi"] = "audio/midi";
MimeTypes["mp3"] = "audio/mpeg";
MimeTypes["vox"] = "audio/voxware";
MimeTypes["wav"] = "audio/wav";
MimeTypes["ra"] = "audio/x-pn-realaudio";
MimeTypes["ram"] = "audio/x-pn-realaudio";
MimeTypes["bmp"] = "image/bmp";
MimeTypes["gif"] = "image/gif";
MimeTypes["jpeg"] = "image/jpeg";
MimeTypes["jpg"] = "image/jpeg";
MimeTypes["tif"] = "image/tiff";
MimeTypes["tiff"] = "image/tiff";
MimeTypes["xbm"] = "image/xbm";
MimeTypes["png"] = "image/png";
MimeTypes["wrl"] = "model/vrml";
MimeTypes["htm"] = "text/html";
MimeTypes["html"] = "text/html";
MimeTypes["c"] = "text/plain";
MimeTypes["cpp"] = "text/plain";
MimeTypes["def"] = "text/plain";
MimeTypes["h"] = "text/plain";
MimeTypes["txt"] = "text/plain";
MimeTypes["rtx"] = "text/richtext";
MimeTypes["rtf"] = "text/richtext";
MimeTypes["java"] = "text/x-java-source";
MimeTypes["css"] = "text/css";
MimeTypes["mpeg"] = "video/mpeg";
MimeTypes["mpg"] = "video/mpeg";
MimeTypes["mpe"] = "video/mpeg";
MimeTypes["avi"] = "video/msvideo";
MimeTypes["mov"] = "video/quicktime";
MimeTypes["qt"] = "video/quicktime";
MimeTypes["shtml"] = "wwwserver/html-ssi";
MimeTypes["asa"] = "wwwserver/isapi";
MimeTypes["asp"] = "wwwserver/isapi";
MimeTypes["cfm"] = "wwwserver/isapi";
MimeTypes["dbm"] = "wwwserver/isapi";
MimeTypes["isa"] = "wwwserver/isapi";
MimeTypes["plx"] = "wwwserver/isapi";
MimeTypes["url"] = "wwwserver/isapi";
MimeTypes["cgi"] = "wwwserver/isapi";
MimeTypes["php"] = "wwwserver/isapi";
MimeTypes["wcgi"] = "wwwserver/isapi";
}
/*
VISVECTOR::iterator visitsipd;
REQUESTSTR::iterator reqinfod;
LOGSTR::iterator serverlogd;
*/
QHttpServer::~QHttpServer()
{
}
//获取状态
void QHttpServer::GetStats(StatsInfo &si)
{
si.nTotalRecv = Stats.nTotalRecv;
si.nTotalSent = Stats.nTotalSent;
si.nTotalHits = Stats.nTotalHits;
si.nVisitors = Visitors.size();
EnterCriticalSection(&_cs);
si.nClientsConnected = ThreadList.size();
LeaveCriticalSection(&_cs);
}
//增加新的连接
BOOL QHttpServer::AddClient(SOCKET s, char* clientAddress, int port)
{
VISVECTOR::iterator it;
it = find(Visitors.begin(), Visitors.end(), clientAddress);//查找重复IP
if(it == Visitors.end())
{
Visitors.push_back(clientAddress);//增加新客户IP
visitsip.push_back(clientAddress); //输出用
}
InterlockedIncrement(&Stats.nTotalHits);//互斥
ThreadTag threadTag;
HANDLE hThread;
unsigned int threadID;
//进入临界区并创建连接对象
EnterCriticalSection(&cs);
NewConnectionTag *NewConn = new NewConnectionTag;
NewConn->pHttpServer = this;
NewConn->s = s;
hThread = (HANDLE)_beginthreadex(NULL, 0, ClientThread, NewConn, 0, &threadID);
if(hThread)
{
threadTag.threadID = threadID;
threadTag.hThread = hThread;
ThreadList.push_back(threadTag);
}
else
serverlog.push_back("_beginthreadex(...) failure");
//else
//LogMessage(LOGFILENAME, "_beginthreadex(...) failure", "AddClient", errno);
LeaveCriticalSection(&cs);
return TRUE;
}
//客户端线程
unsigned __stdcall QHttpServer::ClientThread(LPVOID pParam)
{
NewConnectionTag *pNewConn = (NewConnectionTag*)pParam;
QHttpServer *pHttpServer = pNewConn->pHttpServer;
SOCKET s = pNewConn->s;
int result;
WSAEVENT EventArray[2];
WSANETWORKEVENTS NetworkEvents;
BOOL bResend = FALSE;
WSABUF Buffer;
DWORD NumberOfBytesSent;
DWORD dwBytesSent;
BOOL bKeepAlive = FALSE;
string szRequest;
string szResponse;
//创建事件对象
WSAEVENT Event = WSACreateEvent();
if(Event == WSA_INVALID_EVENT)
{
pHttpServer->CleanupThread(NULL, s, pNewConn, GetCurrentThreadId());
return THREADEXIT_SUCCESS;
}
//事件对象选择性绑定
result = WSAEventSelect(s, Event, FD_READ | FD_WRITE | FD_CLOSE);
if(result == SOCKET_ERROR)
{
pHttpServer->CleanupThread(Event, s, pNewConn, GetCurrentThreadId());
return THREADEXIT_SUCCESS;
}
EventArray[0] = Event;
EventArray[1] = pHttpServer->ShutdownEvent;
//进入循环
while (1)
{
DWORD EventCaused = WSAWaitForMultipleEvents(
2,
EventArray,
FALSE,
pHttpServer->PersistenceTO ? pHttpServer->PersistenceTO : WSA_INFINITE,
FALSE);
if( EventCaused == WSA_WAIT_FAILED)
{
pHttpServer->CleanupThread(Event, s, pNewConn, GetCurrentThreadId());
return THREADEXIT_SUCCESS;
}
// 检查是否服务器任务已经完成
if(EventCaused == 1 || EventCaused == WSA_WAIT_TIMEOUT)
{
pHttpServer->CleanupThread(Event, s, pNewConn, GetCurrentThreadId());
return THREADEXIT_SUCCESS;
}
//
// 分析什么网络事件产生
//
result = WSAEnumNetworkEvents(
s,
Event,
&NetworkEvents);
if(result == SOCKET_ERROR)
{
//pHttpServer->LogMessage(LOGFILENAME, "WSAEnumNetworkEvents(...) failure", "ClientThread", WSAGetLastError());
serverlog.push_back("WSAEnumNetworkEvents(...) failure");
continue;
}
//
// 其他情况
//
if(!NetworkEvents.lNetworkEvents)
continue;
//
// 处理事件
//
if(NetworkEvents.lNetworkEvents & FD_READ)
{
//
// 不需要接收接传入的数据,只需要传给继承类
//
DWORD NumberOfBytesRecvd;
WSABUF Buffers;
DWORD dwBufferCount = 1;
char szBuffer[MAX_BUFFER];
DWORD Flags = 0;
Buffers.buf = szBuffer;
Buffers.len = MAX_BUFFER;
result = WSARecv(
s,
&Buffers,
dwBufferCount,
&NumberOfBytesRecvd,
&Flags,
NULL,
NULL);
if(result != SOCKET_ERROR)
{
pHttpServer->Stats.nTotalRecv += (double)NumberOfBytesRecvd / 1024;
//
// 检测是否获得完整的请求
//
szRequest += string(szBuffer, NumberOfBytesRecvd);
if(!pHttpServer->IsComplete(szRequest))
continue;
reqinfo.push_back(szRequest);
if(!pHttpServer->ParseRequest(szRequest, szResponse, bKeepAlive))
{
pHttpServer->CleanupThread(Event, s, pNewConn, GetCurrentThreadId());
return THREADEXIT_SUCCESS;
}
//
// 发送响应倒客户端
//
NumberOfBytesSent = 0;
dwBytesSent = 0;
do
{
Buffer.len = (szResponse.size() - dwBytesSent) >= SENDBLOCK ? SENDBLOCK : szResponse.size() - dwBytesSent;
Buffer.buf = (char*)((DWORD)szResponse.c_str() + dwBytesSent);
result = WSASend(
s,
&Buffer,
1,
- 1
- 2
- 3
- 4
前往页