工具项目

HttpCookie.h 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : http://www.jessma.org
  6. * Project : https://github.com/ldcsaa
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 75375912, 44636872
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #pragma once
  24. #include "HPTypeDef.h"
  25. #include "../Common/Src/RWLock.h"
  26. #ifdef _HTTP_SUPPORT
  27. #define COOKIE_DOMAIN "domain"
  28. #define COOKIE_PATH "path"
  29. #define COOKIE_EXPIRES "expires"
  30. #define COOKIE_MAX_AGE "Max-Age"
  31. #define COOKIE_HTTPONLY "HttpOnly"
  32. #define COOKIE_SECURE "secure"
  33. #define COOKIE_SAMESITE "SameSite"
  34. #define COOKIE_SAMESITE_STRICT "Strict"
  35. #define COOKIE_SAMESITE_LAX "Lax"
  36. #define COOKIE_DEFAULT_PATH "/"
  37. #define COOKIE_FIELD_SEP ";"
  38. #define COOKIE_DOMAIN_SEP_CHAR '.'
  39. #define COOKIE_PATH_SEP_CHAR '/'
  40. #define COOKIE_KV_SEP_CHAR '='
  41. #pragma warning(push)
  42. #pragma warning(disable: 4503)
  43. class CCookie
  44. {
  45. public:
  46. enum EnSameSite
  47. {
  48. SS_NONE = 0,
  49. SS_STRICT = 1,
  50. SS_LAX = 2
  51. };
  52. CStringA name;
  53. CStringA value;
  54. CStringA domain;
  55. CStringA path;
  56. __time64_t expires;
  57. BOOL httpOnly;
  58. BOOL secure;
  59. EnSameSite sameSite;
  60. 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_NONE)
  61. : name (lpszName)
  62. , value (lpszValue)
  63. , domain (lpszDomain)
  64. , path (lpszPath)
  65. , expires (MaxAgeToExpires(iMaxAge))
  66. , httpOnly (bHttpOnly)
  67. , secure (bSecure)
  68. , sameSite (enSameSite)
  69. {
  70. AdjustDomain(domain);
  71. AdjustPath(path);
  72. }
  73. static __time64_t CurrentUTCTime() {return _time64(nullptr);}
  74. static __time64_t MaxAgeToExpires(int iMaxAge) {return iMaxAge > 0 ? _time64(nullptr) + iMaxAge : (iMaxAge < 0 ? -1 : 0);}
  75. static int ExpiresToMaxAge(__time64_t tmExpires) {if(tmExpires < 0) return -1; __time64_t tmDiff = tmExpires - _time64(nullptr); return (tmDiff > 0 ? (int)tmDiff : 0);}
  76. static __time64_t GetUTCTime(tm& t, int iSecondOffsetTZ);
  77. static void ParseFieldKV(const CStringA& strField, CStringA& strKey, CStringA& strVal, char chSep);
  78. static BOOL ParseExpires(LPCSTR lpszExpires, __time64_t& tmExpires);
  79. static BOOL AdjustDomain(CStringA& strDomain, LPCSTR lpszDefaultDomain = nullptr);
  80. static BOOL AdjustPath(CStringA& strPath, LPCSTR lpszDefaultPath = nullptr);
  81. static CStringA MakeExpiresStr(__time64_t tmExpires);
  82. static BOOL MakeExpiresStr(char lpszBuff[], int& iBuffLen, __time64_t tmExpires);
  83. static CCookie* FromString(const CStringA& strCookie, LPCSTR lpszDefaultDomain = nullptr, LPCSTR lpszDefaultPath = nullptr);
  84. static CStringA ToString(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, EnSameSite enSameSite = SS_NONE);
  85. 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_NONE);
  86. CStringA ToString();
  87. BOOL Match(LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure);
  88. BOOL IsSameDomain(LPCSTR lpszDomain);
  89. BOOL IsTransient() const {return expires < 0;}
  90. BOOL IsExpired() const {return !IsTransient() && expires <= _time64(nullptr);}
  91. BOOL IsValid() const {return !name.IsEmpty() && !domain.IsEmpty() && !path.IsEmpty();}
  92. };
  93. struct ccookie_hash_func
  94. {
  95. struct hash
  96. {
  97. size_t operator() (const CCookie& c) const
  98. {
  99. return hash_value((LPCSTR)(c.name));
  100. }
  101. };
  102. struct equal_to
  103. {
  104. bool operator () (const CCookie& cA, const CCookie& cB) const
  105. {
  106. return (cA.name == cB.name);
  107. }
  108. };
  109. };
  110. // ------------------------------------------------------------------------------------------------------------- //
  111. typedef unordered_set<const CCookie*> CCookiePtrSet;
  112. typedef CCookiePtrSet::const_iterator CCookiePtrSetCI;
  113. typedef CCookiePtrSet::iterator CCookiePtrSetI;
  114. typedef unordered_set<CCookie,
  115. ccookie_hash_func::hash, ccookie_hash_func::equal_to> CCookieSet;
  116. typedef CCookieSet::const_iterator CCookieSetCI;
  117. typedef CCookieSet::iterator CCookieSetI;
  118. typedef unordered_map<CStringA, CCookieSet,
  119. cstringa_hash_func::hash, cstringa_hash_func::equal_to> CCookiePathMap;
  120. typedef CCookiePathMap::const_iterator CCookiePathMapCI;
  121. typedef CCookiePathMap::iterator CCookiePathMapI;
  122. typedef unordered_map<CStringA, CCookiePathMap,
  123. cstringa_nc_hash_func::hash, cstringa_nc_hash_func::equal_to> CCookieDomainMap;
  124. typedef CCookieDomainMap::const_iterator CCookieDomainMapCI;
  125. typedef CCookieDomainMap::iterator CCookieDomainMapI;
  126. class CCookieMgr
  127. {
  128. public:
  129. BOOL LoadFromFile(LPCSTR lpszFile, BOOL bKeepExists = TRUE);
  130. BOOL SaveToFile(LPCSTR lpszFile, BOOL bKeepExists = TRUE);
  131. BOOL ClearCookies(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
  132. BOOL RemoveExpiredCookies(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
  133. BOOL GetCookies(CCookieSet& cookies, LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp, BOOL bSecure);
  134. BOOL SetCookie(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, CCookie::EnSameSite enSameSite = CCookie::SS_NONE, BOOL bOnlyUpdateValueIfExists = TRUE);
  135. BOOL SetCookie(const CStringA& strCookie, BOOL bOnlyUpdateValueIfExists = TRUE);
  136. BOOL SetCookie(const CCookie& cookie, BOOL bOnlyUpdateValueIfExists = TRUE);
  137. BOOL DeleteCookie(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName);
  138. BOOL DeleteCookie(const CCookie& cookie);
  139. private:
  140. void ClearDomainCookiesNoLock(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
  141. void ClearPathCookiesNoLock(CCookiePathMap& paths, LPCSTR lpszPath = nullptr);
  142. void RemoveExpiredCookiesNoLock(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
  143. void RemoveDomainExpiredCookiesNoLock(CCookiePathMap& paths, LPCSTR lpszPath = nullptr);
  144. void RemovePathExpiredCookiesNoLock(CCookieSet& cookies);
  145. const CCookie* GetCookieNoLock(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName);
  146. const CCookie* GetCookieNoLock(const CCookie& cookie);
  147. void MatchCookiesNoLock(CCookieSet& cookies, LPCSTR lpszDomain, LPCSTR lpszPath, BOOL bHttp = TRUE, BOOL bSecure = FALSE);
  148. BOOL SetCookieNoLock(const CCookie& cookie, BOOL bOnlyUpdateValueIfExists = TRUE);
  149. BOOL DeleteCookieNoLock(const CCookie& cookie);
  150. CCookieSet* GetCookieSetNoLock(LPCSTR lpszDomain, LPCSTR lpszPath);
  151. private:
  152. static BOOL LoadDomainAndPath(LPSTR lpszBuff, CStringA& strDomain, CStringA& strPath);
  153. static BOOL LoadCookie(LPSTR lpszBuff, LPCSTR lpszDomain, LPCSTR lpszPath, CCookie& cookie);
  154. static BOOL AdjustDomainAndPath(LPCSTR& lpszDomain, LPCSTR& lpszPath, CStringA& strDomain, CStringA& strPath, BOOL bKeepNull = TRUE);
  155. public:
  156. CCookieMgr(BOOL bEnableThirdPartyCookie = TRUE);
  157. void SetEnableThirdPartyCookie (BOOL bEnableThirdPartyCookie = TRUE) {m_bEnableThirdPartyCookie = bEnableThirdPartyCookie;}
  158. BOOL IsEnableThirdPartyCookie () {return m_bEnableThirdPartyCookie;}
  159. private:
  160. CSimpleRWLock m_cs;
  161. CCookieDomainMap m_cookies;
  162. BOOL m_bEnableThirdPartyCookie;
  163. };
  164. extern CCookieMgr g_CookieMgr;
  165. #pragma warning(pop)
  166. #endif