Move the HTTP/IRC switching to CIncomingConnection

This new class waits for the first line from the client and checks if it's an
HTTP request and then passes the connection on to the irc or http code.

Before this, the IRC parser handled this as a special case which wasn't as
nice-looking as this is. :)


git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1925 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
psychon
2010-04-15 18:20:12 +00:00
parent ab849bb922
commit 6824e3e269
7 changed files with 58 additions and 33 deletions
+43 -2
View File
@@ -38,11 +38,12 @@ bool CRealListener::ConnectionFrom(const CString& sHost, unsigned short uPort) {
}
Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) {
CClient *pClient = new CClient(sHost, uPort);
CIncomingConnection *pClient = new CIncomingConnection(sHost, uPort);
if (CZNC::Get().AllowConnectionFrom(sHost)) {
CZNC::Get().GetModules().OnClientConnect(pClient, sHost, uPort);
} else {
pClient->RefuseLogin("Too many anonymous connections from your IP");
pClient->Write(":irc.znc.in 464 unknown-nick :Too many anonymous connections from your IP\r\n");
pClient->Close(Csock::CLT_AFTERWRITE);
CZNC::Get().GetModules().OnFailedLogin("", sHost);
}
return pClient;
@@ -56,3 +57,43 @@ void CRealListener::SockError(int iErrno) {
Close();
}
}
CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned short uPort) : CZNCSock(sHostname, uPort) {
// The socket will time out in 120 secs, no matter what.
// This has to be fixed up later, if desired.
SetTimeout(120, 0);
EnableReadLine();
}
void CIncomingConnection::ReadLine(const CString& sLine) {
bool bIsHTTP = (sLine.WildCmp("GET * HTTP/1.?\r\n") || sLine.WildCmp("POST * HTTP/1.?\r\n"));
Csock *pSock = NULL;
if (!bIsHTTP) {
// Let's assume it's an IRC connection
pSock = new CClient();
CZNC::Get().GetManager().SwapSockByAddr(pSock, this);
// And don't forget to give it some sane name / timeout
pSock->SetSockName("USR::???");
} else {
// This is a HTTP request, let the webmods handle it
CModule* pMod = new CModule(NULL, "<webmod>", "");
pMod->SetFake(true);
pSock = new CWebSock(pMod);
CZNC::Get().GetManager().SwapSockByAddr(pSock, this);
// And don't forget to give it some sane name / timeout
pSock->SetSockName("WebMod::Client");
}
if (pSock) {
// TODO can we somehow get rid of this?
pSock->ReadLine(sLine);
pSock->PushBuff("", 0, true);
}
}