| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944 |
- /*
- * Copyright: JessMA Open Source (ldcsaa@gmail.com)
- *
- * Author : Bruce Liang
- * Website : http://www.jessma.org
- * Project : https://github.com/ldcsaa
- * Blog : http://www.cnblogs.com/ldcsaa
- * Wiki : http://www.oschina.net/p/hp-socket
- * QQ Group : 75375912, 44636872
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #include "stdafx.h"
- #include "HttpCookie.h"
- #ifdef _HTTP_SUPPORT
- #pragma warning(disable: 4503)
- static const char* s_short_week[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- static const char* s_short_month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
- CCookieMgr g_CookieMgr;
- CCookie* CCookie::FromString(const CStringA& strCookie, LPCSTR lpszDefaultDomain, LPCSTR lpszDefaultPath)
- {
- CStringA strName;
- CStringA strValue;
- CStringA strDomain;
- CStringA strPath;
- int iMaxAge = -1;
- BOOL bHttpOnly = FALSE;
- BOOL bSecure = FALSE;
- EnSameSite enSameSite = SS_NONE;
- int i = 0;
- int iStart = 0;
- while(TRUE)
- {
- CStringA strField = strCookie.Tokenize(COOKIE_FIELD_SEP, iStart);
- strField.Trim();
- if(strField.IsEmpty())
- break;
- if(i == 0)
- {
- ParseFieldKV(strField, strName, strValue, COOKIE_KV_SEP_CHAR);
- if(strName.IsEmpty())
- return nullptr;
- }
- else
- {
- CStringA strKey;
- CStringA strVal;
- ParseFieldKV(strField, strKey, strVal, COOKIE_KV_SEP_CHAR);
- if(strKey.CompareNoCase(COOKIE_DOMAIN) == 0)
- strDomain = strVal;
- else if(strKey.CompareNoCase(COOKIE_PATH) == 0)
- strPath = strVal;
- else if(strKey.CompareNoCase(COOKIE_MAX_AGE) == 0 && !strVal.IsEmpty())
- iMaxAge = atoi(strVal);
- else if(strKey.CompareNoCase(COOKIE_EXPIRES) == 0 && !strVal.IsEmpty() && iMaxAge == -1)
- {
- __time64_t tmExpires = -1;
- if(!ParseExpires(strVal, tmExpires))
- return nullptr;
- iMaxAge = ExpiresToMaxAge(tmExpires);
- }
- else if(strKey.CompareNoCase(COOKIE_HTTPONLY) == 0)
- bHttpOnly = TRUE;
- else if(strKey.CompareNoCase(COOKIE_SECURE) == 0)
- bSecure = TRUE;
- else if(strKey.CompareNoCase(COOKIE_SAMESITE) == 0)
- {
- if(strVal.IsEmpty() || strVal.CompareNoCase(COOKIE_SAMESITE_STRICT) == 0)
- enSameSite = SS_STRICT;
- else if(strVal.CompareNoCase(COOKIE_SAMESITE_LAX) == 0)
- enSameSite = SS_LAX;
- }
- }
- ++i;
- }
- if(!AdjustDomain(strDomain, lpszDefaultDomain) || !AdjustPath(strPath, lpszDefaultPath))
- return nullptr;
- CCookie* pCookie = new CCookie(strName, strValue, strDomain, strPath, iMaxAge, bHttpOnly, bSecure, enSameSite);
- ASSERT(pCookie->IsValid());
- return pCookie;
- }
- CStringA CCookie::ToString(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge, BOOL bHttpOnly, BOOL bSecure, EnSameSite enSameSite)
- {
- CCookie cookie(lpszName, lpszValue, lpszDomain, lpszPath, iMaxAge, bHttpOnly, bSecure, enSameSite);
- return cookie.ToString();
- }
- BOOL CCookie::ToString(char lpszBuff[], int& iBuffLen, LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge, BOOL bHttpOnly, BOOL bSecure, EnSameSite enSameSite)
- {
- BOOL isOK = FALSE;
- CStringA str = ToString(lpszName, lpszValue, lpszDomain, lpszPath, iMaxAge, bHttpOnly, bSecure, enSameSite);
- int iLength = str.GetLength() + 1;
- if(lpszBuff && iBuffLen >= iLength)
- {
- memcpy(lpszBuff, (LPCSTR)str, iLength * sizeof(char));
- isOK = TRUE;
- }
- iBuffLen = iLength;
- return isOK;
- }
- CStringA CCookie::ToString()
- {
- ASSERT(!name.IsEmpty());
- CStringA strCookie;
- strCookie.AppendFormat("%s=%s", name, value);
- if(!domain.IsEmpty())
- strCookie.AppendFormat("; %s=%s", COOKIE_DOMAIN, domain);
- if(!path.IsEmpty())
- strCookie.AppendFormat("; %s=%s", COOKIE_PATH, path);
- if(expires >= 0)
- strCookie.AppendFormat("; %s=%s", COOKIE_EXPIRES, MakeExpiresStr(expires));
- if(httpOnly)
- strCookie.AppendFormat("; %s", COOKIE_HTTPONLY);
- if(secure)
- strCookie.AppendFormat("; %s", COOKIE_SECURE);
- if(sameSite != SS_NONE)
- strCookie.AppendFormat("; %s=%s", COOKIE_SAMESITE, sameSite == SS_LAX ? COOKIE_SAMESITE_LAX : COOKIE_SAMESITE_STRICT);
- return strCookie;
- }
- BOOL CCookie::Match(LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure)
- {
- int iLen = (int)strlen(lpszDomain);
- int iDiff = iLen - domain.GetLength();
- if(iDiff < 0 || _stricmp(lpszDomain + iDiff, domain) != 0)
- return FALSE;
- if(iDiff > 0 && *(lpszDomain + iDiff - 1) != COOKIE_DOMAIN_SEP_CHAR)
- return FALSE;
- if(strncmp(lpszPath, path, path.GetLength()) != 0)
- return FALSE;
- return (bHttp || !httpOnly) && (bSecure || !secure);
- }
- BOOL CCookie::IsSameDomain(LPCSTR lpszDomain)
- {
- int iLen = (int)strlen(lpszDomain);
- int iDiff = iLen - domain.GetLength();
- LPCSTR lpszLong, lpszShort;
- if(iDiff < 0)
- {
- lpszLong = (LPCSTR)domain + iDiff;
- lpszShort = lpszDomain;
- }
- else
- {
- lpszLong = lpszDomain + iDiff;
- lpszShort = (LPCSTR)domain;
- }
- if(_stricmp(lpszLong, lpszShort) != 0)
- return FALSE;
- if(iDiff != 0 && *(lpszLong - 1) != COOKIE_DOMAIN_SEP_CHAR)
- return FALSE;
- return TRUE;
- }
- void CCookie::ParseFieldKV(const CStringA& strField, CStringA& strKey, CStringA& strVal, char chSep)
- {
- int i = strField.Find(chSep);
- if(i < 0)
- strKey = strField;
- else
- {
- strKey = strField.Left(i);
- strVal = strField.Mid(i + 1);
- strVal.Trim();
- }
- strKey.Trim();
- }
- BOOL CCookie::ParseExpires(LPCSTR lpszExpires, __time64_t& tmExpires)
- {
- int iLength = (int)strlen(lpszExpires);
- if(iLength == 0 || iLength > 50)
- return FALSE;
- char szMonth[10];
- char szZone[10];
- tm t = {0};
- if(sscanf_s(lpszExpires, "%*[^, ]%*[, ]%2d%*[-/ ]%[^-/ ]%*[-/ ]%4d %2d:%2d:%2d %s",
- &t.tm_mday, szMonth, (UINT)_countof(szMonth), &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec, szZone, (UINT)_countof(szZone)) != 7)
- return FALSE;
- if(t.tm_year < 70)
- t.tm_year += 100;
- else if (t.tm_year > 100)
- t.tm_year -= 1900;
- int i = 0;
- int size = _countof(s_short_month);
- for(; i < size; i++)
- {
- if(_strnicmp(szMonth, s_short_month[i], 3) == 0)
- break;
- }
- if(i == size)
- return FALSE;
- t.tm_mon = i;
- CStringA strZone = szZone;
- int iZone = 0;
- int iMix = 0;
- int iPos = strZone.Find('+');
- if(iPos >= 0)
- iMix = 1;
- else
- {
- iPos = strZone.Find('-');
- if(iPos >= 0)
- iMix = -1;
- }
- if(iPos >= 0)
- {
- strZone = strZone.Mid(iPos + 1);
- strZone.Remove(':');
- int val = atoi(strZone);
- if(val > 0)
- {
- int minutes = val % 100;
- int hours = val / 100;
- iZone = iMix * (minutes * 60 + hours * 3600);
- }
- }
- tmExpires = GetUTCTime(t, iZone);
- return tmExpires >= 0;
- }
- BOOL CCookie::AdjustDomain(CStringA& strDomain, LPCSTR lpszDefaultDomain)
- {
- if(strDomain.IsEmpty() && lpszDefaultDomain)
- strDomain = lpszDefaultDomain;
- strDomain.TrimLeft(COOKIE_DOMAIN_SEP_CHAR).MakeLower();
- return !strDomain.IsEmpty();
- }
- BOOL CCookie::AdjustPath(CStringA& strPath, LPCSTR lpszDefaultPath)
- {
- if(strPath.IsEmpty() && lpszDefaultPath)
- strPath = lpszDefaultPath;
- int iLength = strPath.GetLength();
- if(iLength == 0)
- return FALSE;
- if(strPath.GetAt(iLength - 1) != COOKIE_PATH_SEP_CHAR)
- {
- int iPos = strPath.ReverseFind(COOKIE_PATH_SEP_CHAR);
- if(iPos >= 0)
- strPath = strPath.Left(iPos + 1);
- else
- strPath.Empty();
- }
- if(!strPath.IsEmpty() && strPath.GetAt(0) != COOKIE_PATH_SEP_CHAR)
- strPath.Insert(0, COOKIE_PATH_SEP_CHAR);
- return !strPath.IsEmpty();
- }
- __time64_t CCookie::GetUTCTime(tm& t, int iSecondOffsetTZ)
- {
- __time64_t v = _mkgmtime64(&t);
- if(v >= 0) v -= iSecondOffsetTZ;
- return v;
- }
- CStringA CCookie::MakeExpiresStr(__time64_t tmExpires)
- {
- ASSERT( tmExpires >= 0);
- if(tmExpires < 1) tmExpires = 1;
- tm t;
- VERIFY(_gmtime64_s(&t, &tmExpires) == 0);
- CStringA str;
- str.Format("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
- s_short_week[t.tm_wday], t.tm_mday, s_short_month[t.tm_mon], t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec);
- return str;
- }
- BOOL CCookie::MakeExpiresStr(char lpszBuff[], int& iBuffLen, __time64_t tmExpires)
- {
- BOOL isOK = FALSE;
- CStringA str = MakeExpiresStr(tmExpires);
- int iLength = str.GetLength() + 1;
- if(lpszBuff && iBuffLen >= iLength)
- {
- memcpy(lpszBuff, (LPCSTR)str, iLength * sizeof(char));
- isOK = TRUE;
- }
- iBuffLen = iLength;
- return isOK;
- }
- // ------------------------------------------------------------------------------------------------------------- //
- BOOL CCookieMgr::LoadFromFile(LPCSTR lpszFile, BOOL bKeepExists)
- {
- BOOL isOK = FALSE;
- FILE* pFile = nullptr;
- if(fopen_s(&pFile, lpszFile, "r") != NO_ERROR)
- {
- ::SetLastError(errno == ENOENT ? ERROR_FILE_NOT_FOUND : (errno == EACCES ? ERROR_ACCESS_DENIED : ERROR_OPEN_FAILED));
- goto _ERROR_END;
- }
- {
- CStringA strDomain;
- CStringA strPath;
- CCookie cookie;
- char szBuffer[8192];
- int iBufferSize = _countof(szBuffer);
- __time64_t tmCurrent = _time64(nullptr);
- CCookieSet* pCookieSet = nullptr;
- CWriteLock locallock(m_cs);
- if(!bKeepExists)
- ClearDomainCookiesNoLock();
- while(fgets(szBuffer, iBufferSize, pFile) != nullptr)
- {
- char c = szBuffer[0];
- if(c == '\n' || c == '\r')
- continue;
- else if(c != '\t')
- {
- if(!LoadDomainAndPath(szBuffer, strDomain, strPath))
- goto _ERROR_END;
- pCookieSet = GetCookieSetNoLock(strDomain, strPath);
- }
- else
- {
- if(!LoadCookie(szBuffer, strDomain, strPath, cookie))
- goto _ERROR_END;
- if(cookie.expires <= tmCurrent)
- continue;
- if(pCookieSet)
- {
- if(bKeepExists)
- {
- CCookieSetCI it = pCookieSet->find(cookie);
- if(it != pCookieSet->end())
- continue;
- }
- pCookieSet->emplace(move(cookie));
- }
- else
- {
- SetCookieNoLock(cookie, FALSE);
- pCookieSet = GetCookieSetNoLock(strDomain, strPath);
- }
- }
- }
- if(!feof(pFile))
- {
- ::SetLastError(ERROR_READ_FAULT);
- goto _ERROR_END;
- }
- }
- isOK = TRUE;
- _ERROR_END:
- if(pFile) fclose(pFile);
- return isOK;
- }
- BOOL CCookieMgr::SaveToFile(LPCSTR lpszFile, BOOL bKeepExists)
- {
- if(bKeepExists)
- {
- if(!LoadFromFile(lpszFile, TRUE) && ::GetLastError() != ERROR_FILE_NOT_FOUND)
- return FALSE;
- }
- BOOL isOK = FALSE;
- FILE* pFile = nullptr;
- if(fopen_s(&pFile, lpszFile, "w") != NO_ERROR)
- {
- ::SetLastError(errno == ENOENT ? ERROR_FILE_NOT_FOUND : (errno == EACCES ? ERROR_ACCESS_DENIED : ERROR_OPEN_FAILED));
- goto _ERROR_END;
- }
- {
- __time64_t tmCurrent = _time64(nullptr);
- CReadLock locallock(m_cs);
- for(CCookieDomainMapCI it = m_cookies.begin(), end = m_cookies.end(); it != end; ++it)
- {
- const CStringA& strDomain = it->first;
- const CCookiePathMap& paths = it->second;
- for(CCookiePathMapCI it2 = paths.begin(), end2 = paths.end(); it2 != end2; ++it2)
- {
- const CStringA& strPath = it2->first;
- const CCookieSet& cookies = it2->second;
- if(fprintf_s(pFile, "%s %s\n", (LPCSTR)strDomain, (LPCSTR)strPath) < 0)
- {
- ::SetLastError(ERROR_WRITE_FAULT);
- goto _ERROR_END;
- }
- for(CCookieSetCI it3 = cookies.begin(), end3 = cookies.end(); it3 != end3; ++it3)
- {
- const CCookie& cookie = *it3;
- if(cookie.expires <= tmCurrent)
- continue;
- LPCSTR lpszValue = (LPCSTR)cookie.value;
- if(lpszValue[0] == 0)
- lpszValue = " ";
- if(fprintf_s(pFile, "\t%s;%s;%I64d;%d;%d;%d\n", (LPCSTR)cookie.name, lpszValue, cookie.expires, cookie.httpOnly, cookie.secure, cookie.sameSite) < 0)
- {
- ::SetLastError(ERROR_WRITE_FAULT);
- goto _ERROR_END;
- }
- }
- }
- }
- }
- isOK = TRUE;
- _ERROR_END:
- if(pFile) fclose(pFile);
- return isOK;
- }
- BOOL CCookieMgr::ClearCookies(LPCSTR lpszDomain, LPCSTR lpszPath)
- {
- CStringA strDomain;
- CStringA strPath;
- if(!AdjustDomainAndPath(lpszDomain, lpszPath, strDomain, strPath, TRUE))
- return FALSE;
- CWriteLock locallock(m_cs);
- ClearDomainCookiesNoLock(lpszDomain, lpszPath);
- return TRUE;
- }
- BOOL CCookieMgr::RemoveExpiredCookies(LPCSTR lpszDomain, LPCSTR lpszPath)
- {
- CStringA strDomain;
- CStringA strPath;
- if(!AdjustDomainAndPath(lpszDomain, lpszPath, strDomain, strPath, TRUE))
- return FALSE;
- CWriteLock locallock(m_cs);
- RemoveExpiredCookiesNoLock(lpszDomain, lpszPath);
- return TRUE;
- }
- BOOL CCookieMgr::GetCookies(CCookieSet& cookies, LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure)
- {
- ASSERT(lpszDomain && lpszPath);
- CStringA strDomain;
- CStringA strPath;
- if(!AdjustDomainAndPath(lpszDomain, lpszPath, strDomain, strPath, FALSE))
- return FALSE;
- list<LPCSTR> lsDomains(1, lpszDomain);
- list<CStringA> lsPaths(1, lpszPath);
- char c;
- LPCSTR lpszTemp = lpszDomain;
- while((c = *(++lpszTemp)) != 0)
- {
- if(c == COOKIE_DOMAIN_SEP_CHAR)
- {
- if((c = *(++lpszTemp)) != 0)
- lsDomains.push_back(lpszTemp);
- else
- break;
- }
- }
- lpszTemp = lpszPath + strlen(lpszPath) - 1;
- while(--lpszTemp >= lpszPath)
- {
- if((c = *lpszTemp) == COOKIE_PATH_SEP_CHAR)
- {
- *(LPSTR)(lpszTemp + 1) = 0;
- lsPaths.push_back(lpszPath);
- }
- }
- CReadLock locallock(m_cs);
- for(list<LPCSTR>::const_iterator it = lsDomains.begin(), end = lsDomains.end(); it != end; ++it)
- {
- for(list<CStringA>::const_iterator it2 = lsPaths.begin(), end2 = lsPaths.end(); it2 != end2; ++it2)
- MatchCookiesNoLock(cookies, *it, *it2, bHttp, bSecure);
- }
- return TRUE;
- }
- BOOL CCookieMgr::SetCookie(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge, BOOL bHttpOnly, BOOL bSecure, CCookie::EnSameSite enSameSite, BOOL bOnlyUpdateValueIfExists)
- {
- CCookie cookie(lpszName, lpszValue, lpszDomain, lpszPath, iMaxAge, bHttpOnly, bSecure, enSameSite);
- return SetCookie(cookie, bOnlyUpdateValueIfExists);
- }
- BOOL CCookieMgr::SetCookie(const CStringA& strCookie, BOOL bOnlyUpdateValueIfExists)
- {
- unique_ptr<CCookie> pCookie(CCookie::FromString(strCookie));
- if(!pCookie) return FALSE;
- return SetCookie(*pCookie, bOnlyUpdateValueIfExists);
- }
- BOOL CCookieMgr::SetCookie(const CCookie& cookie, BOOL bOnlyUpdateValueIfExists)
- {
- if(!cookie.IsValid()) return FALSE;
- CWriteLock locallock(m_cs);
- return SetCookieNoLock(cookie, bOnlyUpdateValueIfExists);
- }
- BOOL CCookieMgr::DeleteCookie(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName)
- {
- CCookie cookie(lpszName, nullptr, lpszDomain, lpszPath);
- return DeleteCookie(cookie);
- }
- BOOL CCookieMgr::DeleteCookie(const CCookie& cookie)
- {
- if(!cookie.IsValid()) return FALSE;
- CWriteLock locallock(m_cs);
- return DeleteCookieNoLock(cookie);
- }
- void CCookieMgr::ClearDomainCookiesNoLock(LPCSTR lpszDomain, LPCSTR lpszPath)
- {
- if(!lpszDomain && !lpszPath)
- m_cookies.clear();
- else if(!lpszPath)
- m_cookies.erase(lpszDomain);
- else
- {
- if(!lpszDomain)
- {
- for(CCookieDomainMapI it = m_cookies.begin(), end = m_cookies.end(); it != end; ++it)
- ClearPathCookiesNoLock(it->second, lpszPath);
- }
- else
- {
- CCookieDomainMapI it = m_cookies.find(lpszDomain);
- if(it != m_cookies.end())
- ClearPathCookiesNoLock(it->second, lpszPath);
- }
- }
- }
- void CCookieMgr::ClearPathCookiesNoLock(CCookiePathMap& paths, LPCSTR lpszPath)
- {
- if(!lpszPath)
- paths.clear();
- else
- {
- CCookiePathMapI it = paths.find(lpszPath);
- if(it != paths.end())
- paths.erase(it->first);
- }
- }
- void CCookieMgr::RemoveExpiredCookiesNoLock(LPCSTR lpszDomain, LPCSTR lpszPath)
- {
- if(!lpszDomain)
- {
- for(CCookieDomainMapI it = m_cookies.begin(), end = m_cookies.end(); it != end; ++it)
- RemoveDomainExpiredCookiesNoLock(it->second, lpszPath);
- }
- else
- {
- CCookieDomainMapI it = m_cookies.find(lpszDomain);
- if(it != m_cookies.end())
- RemoveDomainExpiredCookiesNoLock(it->second, lpszPath);
- }
- }
- void CCookieMgr::RemoveDomainExpiredCookiesNoLock(CCookiePathMap& paths, LPCSTR lpszPath)
- {
- if(!lpszPath)
- {
- for(CCookiePathMapI it = paths.begin(), end = paths.end(); it != end; ++it)
- RemovePathExpiredCookiesNoLock(it->second);
- }
- else
- {
- CCookiePathMapI it = paths.find(lpszPath);
- if(it != paths.end())
- RemovePathExpiredCookiesNoLock(it->second);
- }
- }
- void CCookieMgr::RemovePathExpiredCookiesNoLock(CCookieSet& cookies)
- {
- CCookiePtrSet ptrs;
- for(CCookieSetI it = cookies.begin(), end = cookies.end(); it != end; ++it)
- {
- if(it->IsExpired())
- ptrs.emplace(&*it);
- }
- if(!ptrs.empty())
- {
- for(CCookiePtrSetI it = ptrs.begin(), end = ptrs.end(); it != end; ++it)
- cookies.erase(**it);
- }
- }
- const CCookie* CCookieMgr::GetCookieNoLock(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName)
- {
- const CCookie cookie(lpszName, nullptr, lpszDomain, lpszPath);
- return GetCookieNoLock(cookie);
- }
- const CCookie* CCookieMgr::GetCookieNoLock(const CCookie& cookie)
- {
- const CCookie* pCookie = nullptr;
- CCookieDomainMapCI it = m_cookies.find(cookie.domain);
- if(it != m_cookies.end())
- {
- CCookiePathMapCI it2 = it->second.find(cookie.path);
- if(it2 != it->second.end())
- {
- CCookieSetCI it3 = it2->second.find(cookie);
- if(it3 != it2->second.end())
- pCookie = &*it3;
- }
- }
- return pCookie;
- }
- void CCookieMgr::MatchCookiesNoLock(CCookieSet& cookies, LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure)
- {
- CCookieDomainMapCI it = m_cookies.find(lpszDomain);
- if(it != m_cookies.end())
- {
- CCookiePathMapCI it2 = it->second.find(lpszPath);
- if(it2 != it->second.end())
- {
- for(CCookieSetCI it3 = it2->second.begin(), end3 = it2->second.end(); it3 != end3; ++it3)
- {
- const CCookie& cookie = *it3;
- if(!cookie.IsExpired() && (bHttp || !cookie.httpOnly) && (bSecure || !cookie.secure))
- cookies.emplace(cookie);
- }
- }
- }
- }
- BOOL CCookieMgr::SetCookieNoLock(const CCookie& cookie, BOOL bOnlyUpdateValueIfExists)
- {
- if(cookie.IsExpired())
- return DeleteCookieNoLock(cookie);
- CCookieDomainMapI it = m_cookies.find(cookie.domain);
- if(it == m_cookies.end())
- it = m_cookies.emplace(move(CCookieDomainMap::value_type(cookie.domain, move(CCookiePathMap())))).first;
- CCookiePathMapI it2 = it->second.find(cookie.path);
- if(it2 == it->second.end())
- it2 = it->second.emplace(move(CCookiePathMap::value_type(cookie.path, move(CCookieSet())))).first;
- CCookieSet& cookies = it2->second;
- CCookieSetI it3 = cookies.find(cookie);
- if(it3 != cookies.end())
- {
- if(bOnlyUpdateValueIfExists && !it3->IsExpired() && cookie.IsTransient())
- {
- ((CCookie*)&*it3)->value = cookie.value;
- return TRUE;
- }
-
- cookies.erase(*it3);
- }
- return cookies.emplace(cookie).second;
- }
- BOOL CCookieMgr::DeleteCookieNoLock(const CCookie& cookie)
- {
- BOOL isOK = FALSE;
- CCookieDomainMapI it = m_cookies.find(cookie.domain);
- if(it != m_cookies.end())
- {
- CCookiePathMapI it2 = it->second.find(cookie.path);
- if(it2 != it->second.end())
- {
- CCookieSetI it3 = it2->second.find(cookie);
- if(it3 != it2->second.end())
- {
- it2->second.erase(*it3);
- isOK = TRUE;
- }
- }
- }
- return isOK;
- }
- CCookieSet* CCookieMgr::GetCookieSetNoLock(LPCSTR lpszDomain, LPCSTR lpszPath)
- {
- CCookieSet* pCookieSet = nullptr;
- CCookieDomainMapI it = m_cookies.find(lpszDomain);
- if(it != m_cookies.end())
- {
- CCookiePathMapI it2 = it->second.find(lpszPath);
- if(it2 != it->second.end())
- pCookieSet = &(it2->second);
- }
- return pCookieSet;
- }
- BOOL CCookieMgr::LoadDomainAndPath(LPSTR lpszBuff, CStringA& strDomain, CStringA& strPath)
- {
- int i = 0;
- char* lpszCtx = nullptr;
- for(; i < 2; i++)
- {
- char* lpszToken = strtok_s(lpszBuff, " \n\r", &lpszCtx);
- if(!lpszToken)
- {
- ::SetLastError(ERROR_BAD_FORMAT);
- return FALSE;
- }
- if(i == 0)
- {
- strDomain = lpszToken;
- lpszBuff = nullptr;
- }
- else
- strPath = lpszToken;
- }
- if(!CCookie::AdjustDomain(strDomain))
- return FALSE;
- if(!CCookie::AdjustPath(strPath))
- return FALSE;
- return TRUE;
- }
- BOOL CCookieMgr::LoadCookie(LPSTR lpszBuff, LPCSTR lpszDomain, LPCSTR lpszPath, CCookie& cookie)
- {
- cookie.domain = lpszDomain;
- cookie.path = lpszPath;
- int i = 0;
- char* lpszCtx = nullptr;
- for(; i < 6; i++)
- {
- char* lpszToken = strtok_s(lpszBuff, "\t;\n\r", &lpszCtx);
- if(!lpszToken)
- {
- ::SetLastError(ERROR_BAD_FORMAT);
- return FALSE;
- }
- if(i == 0)
- {
- cookie.name = lpszToken;
- lpszBuff = nullptr;
- }
- else if(i == 1)
- cookie.value = lpszToken;
- else if(i == 2)
- cookie.expires = _atoi64(lpszToken);
- else if(i == 3)
- cookie.httpOnly = atoi(lpszToken);
- else if(i == 4)
- cookie.secure = atoi(lpszToken);
- else if(i == 5)
- cookie.sameSite = (CCookie::EnSameSite)atoi(lpszToken);
- }
- cookie.name.Trim();
- cookie.value.Trim();
- if(cookie.name.IsEmpty() || cookie.expires <= 0 || cookie.httpOnly < 0 || cookie.secure < 0 || cookie.sameSite < 0)
- {
- ::SetLastError(ERROR_INVALID_DATA);
- return FALSE;
- }
- return TRUE;
- }
- BOOL CCookieMgr::AdjustDomainAndPath(LPCSTR& lpszDomain, LPCSTR& lpszPath, CStringA& strDomain, CStringA& strPath, BOOL bKeepNull)
- {
- if(!bKeepNull || lpszDomain)
- {
- strDomain = lpszDomain;
- if(!CCookie::AdjustDomain(strDomain))
- return FALSE;
- lpszDomain = (LPCSTR)strDomain;
- }
- if(!bKeepNull || lpszPath)
- {
- strPath = lpszPath;
- if(!CCookie::AdjustPath(strPath))
- return FALSE;
- lpszPath = (LPCSTR)strPath;
- }
- return TRUE;
- }
- CCookieMgr::CCookieMgr(BOOL bEnableThirdPartyCookie)
- : m_bEnableThirdPartyCookie(bEnableThirdPartyCookie)
- {
- }
- #endif
|