mirror of
https://gitee.com/ldcsaa/HP-Socket.git
synced 2024-12-05 13:17:53 +08:00
200 lines
7.7 KiB
C++
200 lines
7.7 KiB
C++
/*
|
|
* Copyright: JessMA Open Source (ldcsaa@gmail.com)
|
|
*
|
|
* Author : Bruce Liang
|
|
* Website : https://github.com/ldcsaa
|
|
* Project : https://github.com/ldcsaa/HP-Socket
|
|
* Blog : http://www.cnblogs.com/ldcsaa
|
|
* Wiki : http://www.oschina.net/p/hp-socket
|
|
* QQ Group : 44636872, 75375912
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "../Include/HPSocket/HPTypeDef.h"
|
|
|
|
#ifdef _HTTP_SUPPORT
|
|
|
|
#include "Common/RWLock.h"
|
|
|
|
#define COOKIE_DOMAIN "domain"
|
|
#define COOKIE_PATH "path"
|
|
#define COOKIE_EXPIRES "expires"
|
|
#define COOKIE_MAX_AGE "Max-Age"
|
|
#define COOKIE_HTTPONLY "HttpOnly"
|
|
#define COOKIE_SECURE "secure"
|
|
#define COOKIE_SAMESITE "SameSite"
|
|
#define COOKIE_SAMESITE_STRICT "Strict"
|
|
#define COOKIE_SAMESITE_LAX "Lax"
|
|
#define COOKIE_SAMESITE_NONE "None"
|
|
#define COOKIE_DEFAULT_PATH "/"
|
|
#define COOKIE_FIELD_SEP ";"
|
|
#define COOKIE_DOMAIN_SEP_CHAR '.'
|
|
#define COOKIE_PATH_SEP_CHAR '/'
|
|
#define COOKIE_KV_SEP_CHAR '='
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable: 4503)
|
|
|
|
class CCookie
|
|
{
|
|
public:
|
|
enum EnSameSite
|
|
{
|
|
SS_UNKNOWN = 0,
|
|
SS_STRICT = 1,
|
|
SS_LAX = 2,
|
|
SS_NONE = 3
|
|
};
|
|
|
|
CStringA name;
|
|
CStringA value;
|
|
CStringA domain;
|
|
CStringA path;
|
|
__time64_t expires;
|
|
BOOL httpOnly;
|
|
BOOL secure;
|
|
EnSameSite sameSite;
|
|
|
|
CCookie(LPCSTR lpszName = nullptr, LPCSTR lpszValue = nullptr, LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, EnSameSite enSameSite = SS_UNKNOWN)
|
|
: name (lpszName)
|
|
, value (lpszValue)
|
|
, domain (lpszDomain)
|
|
, path (lpszPath)
|
|
, expires (MaxAgeToExpires(iMaxAge))
|
|
, httpOnly (bHttpOnly)
|
|
, secure (bSecure)
|
|
, sameSite (enSameSite)
|
|
{
|
|
AdjustDomain(domain);
|
|
AdjustPath(path);
|
|
}
|
|
|
|
static __time64_t CurrentUTCTime() {return _time64(nullptr);}
|
|
static __time64_t MaxAgeToExpires(int iMaxAge) {return iMaxAge > 0 ? _time64(nullptr) + iMaxAge : (iMaxAge < 0 ? -1 : 0);}
|
|
static int ExpiresToMaxAge(__time64_t tmExpires) {if(tmExpires < 0) return -1; __time64_t tmDiff = tmExpires - _time64(nullptr); return (tmDiff > 0 ? (int)tmDiff : 0);}
|
|
|
|
static __time64_t GetUTCTime(tm& t, int iSecondOffsetTZ);
|
|
static void ParseFieldKV(const CStringA& strField, CStringA& strKey, CStringA& strVal, char chSep);
|
|
static BOOL ParseExpires(LPCSTR lpszExpires, __time64_t& tmExpires);
|
|
static BOOL AdjustDomain(CStringA& strDomain, LPCSTR lpszDefaultDomain = nullptr);
|
|
static BOOL AdjustPath(CStringA& strPath, LPCSTR lpszDefaultPath = nullptr);
|
|
static CStringA MakeExpiresStr(__time64_t tmExpires);
|
|
static BOOL MakeExpiresStr(char lpszBuff[], int& iBuffLen, __time64_t tmExpires);
|
|
static CCookie* FromString(const CStringA& strCookie, LPCSTR lpszDefaultDomain = nullptr, LPCSTR lpszDefaultPath = nullptr);
|
|
static CStringA ToString(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, EnSameSite enSameSite = SS_UNKNOWN);
|
|
static BOOL ToString(char lpszBuff[], int& iBuffLen, LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, EnSameSite enSameSite = SS_UNKNOWN);
|
|
|
|
CStringA ToString();
|
|
BOOL Match(LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure);
|
|
BOOL IsSameDomain(LPCSTR lpszDomain);
|
|
|
|
BOOL IsTransient() const {return expires < 0;}
|
|
BOOL IsExpired() const {return !IsTransient() && expires <= _time64(nullptr);}
|
|
BOOL IsValid() const {return !name.IsEmpty() && !domain.IsEmpty() && !path.IsEmpty();}
|
|
};
|
|
|
|
struct ccookie_hash_func
|
|
{
|
|
struct hash
|
|
{
|
|
size_t operator() (const CCookie& c) const
|
|
{
|
|
return hash_value((LPCSTR)(c.name));
|
|
}
|
|
};
|
|
|
|
struct equal_to
|
|
{
|
|
bool operator () (const CCookie& cA, const CCookie& cB) const
|
|
{
|
|
return (cA.name == cB.name);
|
|
}
|
|
};
|
|
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------------------- //
|
|
|
|
typedef unordered_set<const CCookie*> CCookiePtrSet;
|
|
typedef CCookiePtrSet::const_iterator CCookiePtrSetCI;
|
|
typedef CCookiePtrSet::iterator CCookiePtrSetI;
|
|
|
|
typedef unordered_set<CCookie,
|
|
ccookie_hash_func::hash, ccookie_hash_func::equal_to> CCookieSet;
|
|
typedef CCookieSet::const_iterator CCookieSetCI;
|
|
typedef CCookieSet::iterator CCookieSetI;
|
|
|
|
typedef unordered_map<CStringA, CCookieSet,
|
|
cstringa_hash_func::hash, cstringa_hash_func::equal_to> CCookiePathMap;
|
|
typedef CCookiePathMap::const_iterator CCookiePathMapCI;
|
|
typedef CCookiePathMap::iterator CCookiePathMapI;
|
|
|
|
typedef unordered_map<CStringA, CCookiePathMap,
|
|
cstringa_nc_hash_func::hash, cstringa_nc_hash_func::equal_to> CCookieDomainMap;
|
|
typedef CCookieDomainMap::const_iterator CCookieDomainMapCI;
|
|
typedef CCookieDomainMap::iterator CCookieDomainMapI;
|
|
|
|
class CCookieMgr
|
|
{
|
|
public:
|
|
BOOL LoadFromFile(LPCSTR lpszFile, BOOL bKeepExists = TRUE);
|
|
BOOL SaveToFile(LPCSTR lpszFile, BOOL bKeepExists = TRUE);
|
|
|
|
BOOL ClearCookies(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
|
|
BOOL RemoveExpiredCookies(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
|
|
|
|
BOOL GetCookies(CCookieSet& cookies, LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure);
|
|
BOOL SetCookie(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, CCookie::EnSameSite enSameSite = CCookie::SS_UNKNOWN, BOOL bOnlyUpdateValueIfExists = TRUE);
|
|
BOOL SetCookie(const CStringA& strCookie, BOOL bOnlyUpdateValueIfExists = TRUE);
|
|
BOOL SetCookie(const CCookie& cookie, BOOL bOnlyUpdateValueIfExists = TRUE);
|
|
BOOL DeleteCookie(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName);
|
|
BOOL DeleteCookie(const CCookie& cookie);
|
|
|
|
private:
|
|
void ClearDomainCookiesNoLock(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
|
|
void ClearPathCookiesNoLock(CCookiePathMap& paths, LPCSTR lpszPath = nullptr);
|
|
void RemoveExpiredCookiesNoLock(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
|
|
void RemoveDomainExpiredCookiesNoLock(CCookiePathMap& paths, LPCSTR lpszPath = nullptr);
|
|
void RemovePathExpiredCookiesNoLock(CCookieSet& cookies);
|
|
const CCookie* GetCookieNoLock(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName);
|
|
const CCookie* GetCookieNoLock(const CCookie& cookie);
|
|
void MatchCookiesNoLock(CCookieSet& cookies, LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp = TRUE, BOOL bSecure = FALSE);
|
|
BOOL SetCookieNoLock(const CCookie& cookie, BOOL bOnlyUpdateValueIfExists = TRUE);
|
|
BOOL DeleteCookieNoLock(const CCookie& cookie);
|
|
CCookieSet* GetCookieSetNoLock(LPCSTR lpszDomain, LPCSTR lpszPath);
|
|
|
|
private:
|
|
static BOOL LoadDomainAndPath(LPSTR lpszBuff, CStringA& strDomain, CStringA& strPath);
|
|
static BOOL LoadCookie(LPSTR lpszBuff, LPCSTR lpszDomain, LPCSTR lpszPath, CCookie& cookie);
|
|
static BOOL AdjustDomainAndPath(LPCSTR& lpszDomain, LPCSTR& lpszPath, CStringA& strDomain, CStringA& strPath, BOOL bKeepNull = TRUE);
|
|
|
|
public:
|
|
CCookieMgr(BOOL bEnableThirdPartyCookie = TRUE);
|
|
|
|
void SetEnableThirdPartyCookie (BOOL bEnableThirdPartyCookie = TRUE) {m_bEnableThirdPartyCookie = bEnableThirdPartyCookie;}
|
|
BOOL IsEnableThirdPartyCookie () {return m_bEnableThirdPartyCookie;}
|
|
|
|
private:
|
|
CSimpleRWLock m_cs;
|
|
CCookieDomainMap m_cookies;
|
|
BOOL m_bEnableThirdPartyCookie;
|
|
};
|
|
|
|
extern CCookieMgr g_CookieMgr;
|
|
|
|
#pragma warning(pop)
|
|
|
|
#endif |