From 832c8d0d80dc77682e376759aff339cb1f0ed5f3 Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Fri, 11 Feb 2022 11:54:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96mktime=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Http/HttpCookie.cpp | 91 ++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/src/Http/HttpCookie.cpp b/src/Http/HttpCookie.cpp index ce7a0f89..579c3542 100644 --- a/src/Http/HttpCookie.cpp +++ b/src/Http/HttpCookie.cpp @@ -10,7 +10,7 @@ #include "HttpCookie.h" #include "Util/util.h" -#include "Util/logger.h" +#include "Util/onceToken.h" #if defined(_WIN32) #include "Util/strptime_win.h" @@ -21,28 +21,75 @@ using namespace std; namespace mediakit { -void HttpCookie::setPath(const string &path){ +void HttpCookie::setPath(const string &path) { _path = path; } -void HttpCookie::setHost(const string &host){ + +void HttpCookie::setHost(const string &host) { _host = host; } -static time_t timeStrToInt(const string &date){ - struct tm tt; - strptime(date.data(),"%a, %b %d %Y %H:%M:%S %Z",&tt); - return mktime(&tt); + +static long s_gmtoff = 0; //时间差 +static onceToken s_token([]() { +#ifdef _WIN32 + TIME_ZONE_INFORMATION tzinfo; + DWORD dwStandardDaylight; + long bias; + dwStandardDaylight = GetTimeZoneInformation(&tzinfo); + bias = tzinfo.Bias; + if (dwStandardDaylight == TIME_ZONE_ID_STANDARD) { + bias += tzinfo.StandardBias; + } + if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT) { + bias += tzinfo.DaylightBias; + } + s_gmtoff = -bias * 60; //时间差(分钟) +#else + s_gmtoff = getLocalTime(time(nullptr)).tm_gmtoff; +#endif // _WIN32 +}); + +// from https://gmbabar.wordpress.com/2010/12/01/mktime-slow-use-custom-function/#comment-58 +static time_t time_to_epoch(const struct tm *ltm, int utcdiff) { + const int mon_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + long tyears, tdays, leaps, utc_hrs; + int i; + + tyears = ltm->tm_year - 70; // tm->tm_year is from 1900. + leaps = (tyears + 2) / 4; // no of next two lines until year 2100. + // i = (ltm->tm_year – 100) / 100; + // leaps -= ( (i/4)*3 + i%4 ); + tdays = 0; + for (i = 0; i < ltm->tm_mon; i++) + tdays += mon_days[i]; + + tdays += ltm->tm_mday - 1; // days of month passed. + tdays = tdays + (tyears * 365) + leaps; + + utc_hrs = ltm->tm_hour + utcdiff; // for your time zone. + return (tdays * 86400) + (utc_hrs * 3600) + (ltm->tm_min * 60) + ltm->tm_sec; } -void HttpCookie::setExpires(const string &expires,const string &server_date){ + +static time_t timeStrToInt(const string &date) { + struct tm tt; + strptime(date.data(), "%a, %b %d %Y %H:%M:%S %Z", &tt); + // mktime内部有使用互斥锁,非常影响性能 + return time_to_epoch(&tt, s_gmtoff / 3600); // mktime(&tt); +} + +void HttpCookie::setExpires(const string &expires, const string &server_date) { _expire = timeStrToInt(expires); - if(!server_date.empty()){ - _expire = time(NULL) + (_expire - timeStrToInt(server_date)); + if (!server_date.empty()) { + _expire = time(NULL) + (_expire - timeStrToInt(server_date)); } } -void HttpCookie::setKeyVal(const string &key,const string &val){ + +void HttpCookie::setKeyVal(const string &key, const string &val) { _key = key; _val = val; } -HttpCookie::operator bool (){ + +HttpCookie::operator bool() { return !_host.empty() && !_key.empty() && !_val.empty() && (_expire > time(NULL)); } @@ -50,19 +97,18 @@ const string &HttpCookie::getVal() const { return _val; } -const string &HttpCookie::getKey() const{ +const string &HttpCookie::getKey() const { return _key; } - -HttpCookieStorage &HttpCookieStorage::Instance(){ +HttpCookieStorage &HttpCookieStorage::Instance() { static HttpCookieStorage instance; return instance; } void HttpCookieStorage::set(const HttpCookie::Ptr &cookie) { lock_guard lck(_mtx_cookie); - if(!cookie || !(*cookie)){ + if (!cookie || !(*cookie)) { return; } _all_cookie[cookie->_host][cookie->_path][cookie->_key] = cookie; @@ -71,20 +117,20 @@ void HttpCookieStorage::set(const HttpCookie::Ptr &cookie) { vector HttpCookieStorage::get(const string &host, const string &path) { vector ret(0); lock_guard lck(_mtx_cookie); - auto it = _all_cookie.find(host); - if(it == _all_cookie.end()){ + auto it = _all_cookie.find(host); + if (it == _all_cookie.end()) { //未找到该host相关记录 return ret; } //遍历该host下所有path - for(auto &pr : it->second){ - if(path.find(pr.first) != 0){ + for (auto &pr : it->second) { + if (path.find(pr.first) != 0) { //这个path不匹配 continue; } //遍历该path下的各个cookie - for(auto it_cookie = pr.second.begin() ; it_cookie != pr.second.end() ; ){ - if(!*(it_cookie->second)){ + for (auto it_cookie = pr.second.begin(); it_cookie != pr.second.end();) { + if (!*(it_cookie->second)) { //该cookie已经过期,移除之 it_cookie = pr.second.erase(it_cookie); continue; @@ -97,5 +143,4 @@ vector HttpCookieStorage::get(const string &host, const string return ret; } - } /* namespace mediakit */