From 4daa6371301fc468fbc97f2682e6af93ca96f722 Mon Sep 17 00:00:00 2001 From: cflakes Date: Tue, 23 Mar 2010 16:48:25 +0000 Subject: [PATCH] WebMods/HTTPSock: Do not send Set-Cookie headers if the cookie has not changed. To achieve that, split internal cookie jar into a jar for received cookies and one for cookies that are to be sent with the response. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1840 726aef4b-f618-498e-8847-2d620e286838 --- HTTPSock.cpp | 24 +++++++++++++++--------- HTTPSock.h | 9 +++++---- WebModules.cpp | 23 +++++++++++------------ WebModules.h | 4 ++-- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/HTTPSock.cpp b/HTTPSock.cpp index 95298ff1..f6cf4f46 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -41,22 +41,27 @@ void CHTTPSock::ReadData(const char* data, size_t len) { } } -bool CHTTPSock::SetCookie(const CString& sKey, const CString& sValue) { +bool CHTTPSock::SendCookie(const CString& sKey, const CString& sValue) { if (!sKey.empty() && !sValue.empty()) { - m_msCookies[sKey] = sValue; + if (m_msRequestCookies.find(sKey) == m_msRequestCookies.end() || + m_msRequestCookies[sKey].StrCmp(sValue) != 0) + { + m_msResponseCookies[sKey] = sValue; + } return true; } return false; } -const MCString& CHTTPSock::GetCookies() const { - return m_msCookies; + +const MCString& CHTTPSock::GetRequestCookies() const { + return m_msRequestCookies; } -CString CHTTPSock::GetCookie(const CString& sKey) const { - MCString::const_iterator it = m_msCookies.find(sKey); +CString CHTTPSock::GetRequestCookie(const CString& sKey) const { + MCString::const_iterator it = m_msRequestCookies.find(sKey); - return it != m_msCookies.end() ? it->second : ""; + return it != m_msRequestCookies.end() ? it->second : ""; } void CHTTPSock::CheckPost() { @@ -95,7 +100,8 @@ void CHTTPSock::ReadLine(const CString& sData) { for (unsigned int a = 0; a < vsNV.size(); a++) { CString s(vsNV[a]); - SetCookie(s.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII), s.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII)); + m_msRequestCookies[s.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII)] = + s.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII); } } else if (sName.Equals("Authorization:")) { CString sUnhashed; @@ -435,7 +441,7 @@ bool CHTTPSock::PrintHeader(off_t uContentLength, const CString& sContentType, u MCString::iterator it; - for (it = m_msCookies.begin(); it != m_msCookies.end(); ++it) { + for (it = m_msResponseCookies.begin(); it != m_msResponseCookies.end(); ++it) { Write("Set-Cookie: " + it->first.Escape_n(CString::EURL) + "=" + it->second.Escape_n(CString::EURL) + "; path=/;\r\n"); } diff --git a/HTTPSock.h b/HTTPSock.h index bc3e7173..3b17bd5a 100644 --- a/HTTPSock.h +++ b/HTTPSock.h @@ -50,9 +50,9 @@ public: void GetPage(); // Cookies - bool SetCookie(const CString& sKey, const CString& sValue); - const MCString& GetCookies() const; - CString GetCookie(const CString& sKey) const; + const MCString& GetRequestCookies() const; + CString GetRequestCookie(const CString& sKey) const; + bool SendCookie(const CString& sKey, const CString& sValue); // Cookies // Setters @@ -96,7 +96,8 @@ protected: MCString m_msHeaders; bool m_bHTTP10Client; CString m_sIfNoneMatch; - MCString m_msCookies; + MCString m_msRequestCookies; + MCString m_msResponseCookies; }; #endif // !_HTTPSOCK_H diff --git a/WebModules.cpp b/WebModules.cpp index 1137dafe..1ff6ff53 100644 --- a/WebModules.cpp +++ b/WebModules.cpp @@ -483,20 +483,20 @@ bool CWebSock::ForceLogin() { return false; } -CString CWebSock::GetCookie(const CString& sKey) const { +CString CWebSock::GetRequestCookie(const CString& sKey) const { if (!m_sModName.empty()) { - return CHTTPSock::GetCookie("Mod::" + m_sModName + "::" + sKey); + return CHTTPSock::GetRequestCookie("Mod::" + m_sModName + "::" + sKey); } - return CHTTPSock::GetCookie(sKey); + return CHTTPSock::GetRequestCookie(sKey); } -bool CWebSock::SetCookie(const CString& sKey, const CString& sValue) { +bool CWebSock::SendCookie(const CString& sKey, const CString& sValue) { if (!m_sModName.empty()) { - return CHTTPSock::SetCookie("Mod::" + m_sModName + "::" + sKey, sValue); + return CHTTPSock::SendCookie("Mod::" + m_sModName + "::" + sKey, sValue); } - return CHTTPSock::SetCookie(sKey, sValue); + return CHTTPSock::SendCookie(sKey, sValue); } void CWebSock::OnPageRequest(const CString& sURI) { @@ -516,10 +516,8 @@ void CWebSock::OnPageRequest(const CString& sURI) { } CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CString& sPageRet) { - bool bNoCookie = (GetCookie("SessionId").empty()); - m_spSession = GetSession(); - SetCookie("SessionId", m_spSession->GetId()); + SendCookie("SessionId", m_spSession->GetId()); if (m_spSession->IsLoggedIn()) { m_sUser = m_spSession->GetUser()->GetUserName(); @@ -528,7 +526,7 @@ CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CS // Handle the static pages that don't require a login if (sURI == "/") { - if(!m_bLoggedIn && GetParam("cookie_check").ToBool() && bNoCookie) { + if(!m_bLoggedIn && GetParam("cookie_check").ToBool() && GetRequestCookie("SessionId").empty()) { m_spSession->AddError("Your browser does not have cookies enabled for this site!"); } return PrintTemplate("index", sPageRet); @@ -657,12 +655,13 @@ CSmartPtr CWebSock::GetSession() { return m_spSession; } - CSmartPtr *pSession = m_mspSessions.GetItem(GetCookie("SessionId")); + const CString sCookieSessionId = GetRequestCookie("SessionId"); + CSmartPtr *pSession = m_mspSessions.GetItem(sCookieSessionId); if (pSession != NULL) { // Refresh the timeout m_mspSessions.AddItem((*pSession)->GetId(), *pSession); - DEBUG("Found existing session from cookie: [" + GetCookie("SessionId") + "] IsLoggedIn(" + CString((*pSession)->IsLoggedIn() ? "true" : "false") + ")"); + DEBUG("Found existing session from cookie: [" + sCookieSessionId + "] IsLoggedIn(" + CString((*pSession)->IsLoggedIn() ? "true" : "false") + ")"); return *pSession; } diff --git a/WebModules.h b/WebModules.h index 35b80d41..a471b60b 100644 --- a/WebModules.h +++ b/WebModules.h @@ -156,8 +156,8 @@ public: size_t GetAvailSkins(vector& vRet); CString GetSkinName(); - CString GetCookie(const CString& sKey) const; - bool SetCookie(const CString& sKey, const CString& sValue); + CString GetRequestCookie(const CString& sKey) const; + bool SendCookie(const CString& sKey, const CString& sValue); static void FinishUserSessions(const CUser& User) { m_mspSessions.FinishUserSessions(User);