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

📄 ghttp.cpp

📁 一个非常有用的开源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			int n;			for(n = 0; (szData[n] < '0' || szData[n] > 'f') && n < nSize; n++)			{			}			int nHexStart = n;			for( ; szData[n] >= '0' && szData[n] <= 'f' && n < nSize; n++)			{			}			if(n >= nSize)				break;			// Convert it from hex to an integer			int nPow = 1;			int nDig;			int i;			for(i = n - 1; i >= nHexStart; i--)			{				if(szData[i] >= '0' && szData[i] <= '9')					nDig = szData[i] - '0';				else if(szData[i] >= 'a' && szData[i] <= 'f')					nDig = szData[i] - 'a' + 10;				else if(szData[i] >= 'A' && szData[i] <= 'F')					nDig = szData[i] - 'A' + 10;				else				{					nDig = 0;					GAssert(false, "expected a hex digit");				}				m_nContentSize += (nDig * nPow);				nPow *= 16;			}			for( ; szData[n] != '\n' && n < nSize; n++)			{			}			if(n < nSize && szData[n] == '\n')				n++;			szData += n;			nSize -= n;		}		if(m_nContentSize == 0)		{			m_nContentSize = m_pChunkQueue->GetSize();			delete(m_pData);			m_pData = (unsigned char*)m_pChunkQueue->DumpToString();			m_bChunked = false;			m_bPastHeader = false;			if(m_status == Downloading)				m_status = Done;			break;		}		else		{			int nChunkSize = MIN(m_nContentSize, nSize);			m_pChunkQueue->Push(szData, nChunkSize);			szData += nChunkSize;			nSize -= nChunkSize;			m_nContentSize -= nChunkSize;		}	}}// todo: this is a hack--fix it properlyvoid GHttpClient::GimmeWhatYouGot(){	if(m_bChunked)	{		m_nContentSize = m_pChunkQueue->GetSize();		if(m_nContentSize > 64)		{			delete(m_pData);			m_pData = (unsigned char*)m_pChunkQueue->DumpToString();			m_bChunked = false;			m_bPastHeader = false;			if(m_status == Downloading)				m_status = Done;		}	}	else if(m_nContentSize > 0)	{		if(m_nDataPos > 64)		{			if(m_status == Downloading)				m_status = Done;			m_pData[m_nDataPos] = '\0';			m_bPastHeader = false;			m_nContentSize = m_nDataPos;		}	}	else	{		if(m_pChunkQueue && m_pChunkQueue->GetSize() > 64)		{			if(m_status == Downloading)				m_status = Done;			m_nContentSize = m_pChunkQueue->GetSize();			delete(m_pData);			m_pData = (unsigned char*)m_pChunkQueue->DumpToString();			m_bPastHeader = false;		}	}}unsigned char* GHttpClient::GetData(int* pnSize){	if(m_status != Done)	{		GimmeWhatYouGot();		if(m_status == Done)		{			//GAssert(false, "todo: why are we giving it out early?");		}			}		if(m_status != Done)	{		// it's really not done, so don't return anything [rdp]		*pnSize = 0;		return NULL;	}	*pnSize = m_nContentSize;	return m_pData;}unsigned char* GHttpClient::DropData(int* pnSize){	unsigned char* pData = GetData(pnSize);	if(!pData)		return NULL;	m_pData = NULL;	return pData;}// -----------------------------------------------------------------------class GHttpServerBuffer{public:	enum RequestType	{		None,		Get,		Post,	};	int m_nPos;	char m_szLine[MAX_SERVER_LINE_SIZE];	char m_szUrl[MAX_SERVER_LINE_SIZE];	char m_szParams[MAX_SERVER_LINE_SIZE];	RequestType m_eRequestType;	int m_nContentLength;	GHttpServerBuffer()	{		m_eRequestType = None;		m_nPos = 0;		m_nContentLength = 0;	}	~GHttpServerBuffer()	{	}};GHttpServer::GHttpServer(int nPort){	m_pBuffers = new GPointerArray(16);	m_pSocket = GSocketServer::HostTCPSocket(nPort);	if(!m_pSocket)		throw("failed to open port");	m_pQ = new GQueue();	SetContentType("text/html");}GHttpServer::~GHttpServer(){	int nCount = m_pBuffers->GetSize();	int n;	for(n = 0; n < nCount; n++)		delete((GHttpServerBuffer*)m_pBuffers->GetPointer(n));	delete(m_pBuffers);	delete(m_pSocket);	delete(m_pQ);}bool GHttpServer::Process(){	int nMessageSize;	int nConnection;	unsigned char* pMessage;	unsigned char* pIn;	char c;	GHttpServerBuffer* pBuffer;	bool bDidSomething = false;	while(m_pSocket->GetMessageCount() > 0)	{		bDidSomething = true;		pMessage = m_pSocket->GetNextMessage(&nMessageSize, &nConnection);		pIn = pMessage;		while(m_pBuffers->GetSize() <= nConnection)			m_pBuffers->AddPointer(new GHttpServerBuffer());		pBuffer = (GHttpServerBuffer*)m_pBuffers->GetPointer(nConnection);		while(nMessageSize > 0)		{			c = *pIn;			pBuffer->m_szLine[pBuffer->m_nPos++] = c;			pIn++;			nMessageSize--;			if(c == '\n' || pBuffer->m_nPos >= MAX_SERVER_LINE_SIZE - 1)			{				pBuffer->m_szLine[pBuffer->m_nPos] = '\0';				ProcessLine(nConnection, pBuffer, pBuffer->m_szLine);				pBuffer->m_nPos = 0;			}		}		delete(pMessage);	}	return bDidSomething;}void GHttpServer::ProcessLine(int nConnection, GHttpServerBuffer* pClient, const char* szLine){	OnProcessLine(nConnection, szLine);	while(*szLine > '\0' && *szLine <= ' ')		szLine++;	if(*szLine == '\0')		MakeResponse(nConnection, pClient);	else if(strnicmp(szLine, "GET ", 4) == 0)	{		pClient->m_eRequestType = GHttpServerBuffer::Get;		const char* szIn = szLine + 4;		char* szOut = pClient->m_szUrl;		while(*szIn > ' ' && *szIn != '?')		{			*szOut = *szIn;			szIn++;			szOut++;		}		*szOut = '\0';		if(*szIn == '?')		{			szIn++;			szOut = pClient->m_szParams;			while(*szIn > ' ')			{				*szOut = *szIn;				szIn++;				szOut++;			}			*szOut = '\0';		}		else			pClient->m_szParams[0] = '\0';	}	else if(strnicmp(szLine, "POST ", 5) == 0)		pClient->m_eRequestType = GHttpServerBuffer::Post;	else if(strnicmp(szLine, "Content-Length: ", 16) == 0)		pClient->m_nContentLength = atoi(szLine + 16);}void GHttpServer::SetContentType(const char* szContentType){	GString::StrCpy(m_szContentType, szContentType, 64);}void GHttpServer::MakeResponse(int nConnection, GHttpServerBuffer* pClient){	if(pClient->m_eRequestType == GHttpServerBuffer::None)		return;	else if(pClient->m_eRequestType == GHttpServerBuffer::Get)		DoGet(pClient->m_szUrl, pClient->m_szParams, m_pQ);	else		GAssert(false, "only GET is currently supported");	char szPayloadSize[32];	int nPayloadSize = m_pQ->GetSize();	itoa(nPayloadSize, szPayloadSize, 10);	// Send the header	GQueue q;	q.Push("HTTP/1.1 200 OK\r\nContent-Type: ");	q.Push(m_szContentType);	q.Push("\r\nContent-Length: ");	q.Push(szPayloadSize);	q.Push("\r\n\r\n");	int nHeaderSize = q.GetSize();	char* szHeader = q.DumpToString();	ArrayHolder<char*> hHeader(szHeader);	m_pSocket->Send(szHeader, nHeaderSize, nConnection);	// Send the payload	m_pQ->Push("\r\n\r\n");	char* szPayload = m_pQ->DumpToString();	ArrayHolder<char*> hPayload(szPayload);	m_pSocket->Send(szPayload, nPayloadSize + 4, nConnection);}/*static*/ void GHttpServer::UnescapeUrl(char* szOut, const char* szIn){	int c1, c2, n1, n2;	while(*szIn != '\0')	{		if(*szIn == '%')		{			szIn++;			n1 = *szIn;			szIn++;			n2 = *szIn;			if(n1 >= '0' && n1 <= '9')				c1 = n1 - '0';			else if(n1 >= 'a' && n1 <= 'z')				c1 = n1 - 'a' + 10;			else if(n1 >= 'A' && n1 <= 'Z')				c1 = n1 - 'A' + 10;			else				c1 = 2;			if(n2 >= '0' && n2 <= '9')				c2 = n2 - '0';			else if(n2 >= 'a' && n2 <= 'z')				c2 = n2 - 'a' + 10;			else if(n2 >= 'A' && n2 <= 'Z')				c2 = n2 - 'A' + 10;			else				c2 = 0;			*szOut = 16 * c1 + c2;		}		else if(*szIn == '+')			*szOut = ' ';		else			*szOut = *szIn;		szIn++;		szOut++;	}	*szOut = '\0';}/*static*/ void GHttpServer::ParseParams(GStringHeap* pStringHeap, GConstStringHashTable* pTable, const char* szParams){	char szTmp[512];	UnescapeUrl(szTmp, szParams);	int nNameStart = 0;	int nNameLen, nValueStart, nValueLen;	while(true)	{		for(nNameLen = 0; szTmp[nNameStart + nNameLen] != '=' && szTmp[nNameStart + nNameLen] != '\0'; nNameLen++)		{		}		if(szTmp[nNameStart + nNameLen] == '\0')			return;		nValueStart = nNameStart + nNameLen + 1;		for(nValueLen = 0; szTmp[nValueStart + nValueLen] != '&' && szTmp[nValueStart + nValueLen] != '\0'; nValueLen++)		{		}		const char* szName = pStringHeap->Add(&szTmp[nNameStart], nNameLen);		const char* szValue = pStringHeap->Add(&szTmp[nValueStart], nValueLen);		pTable->Add(szName, szValue);		if(szTmp[nValueStart + nValueLen] == '\0')			return;		nNameStart = nValueStart + nValueLen + 1;	}}

⌨️ 快捷键说明

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