mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 12:37:09 +08:00
http cookie减少互斥锁,优化性能
This commit is contained in:
parent
c510f3765a
commit
36f24527a4
@ -8,10 +8,10 @@
|
|||||||
* may be found in the AUTHORS file in the root of the source tree.
|
* may be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Util/util.h"
|
|
||||||
#include "Util/MD5.h"
|
|
||||||
#include "Common/config.h"
|
|
||||||
#include "HttpCookieManager.h"
|
#include "HttpCookieManager.h"
|
||||||
|
#include "Common/config.h"
|
||||||
|
#include "Util/MD5.h"
|
||||||
|
#include "Util/util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
@ -19,27 +19,25 @@ using namespace toolkit;
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
//////////////////////////////HttpServerCookie////////////////////////////////////
|
//////////////////////////////HttpServerCookie////////////////////////////////////
|
||||||
HttpServerCookie::HttpServerCookie(const std::shared_ptr<HttpCookieManager> &manager,
|
HttpServerCookie::HttpServerCookie(
|
||||||
const string &cookie_name,
|
const std::shared_ptr<HttpCookieManager> &manager, const string &cookie_name, const string &uid,
|
||||||
const string &uid,
|
const string &cookie, uint64_t max_elapsed) {
|
||||||
const string &cookie,
|
|
||||||
uint64_t max_elapsed){
|
|
||||||
_uid = uid;
|
_uid = uid;
|
||||||
_max_elapsed = max_elapsed;
|
_max_elapsed = max_elapsed;
|
||||||
_cookie_uuid = cookie;
|
_cookie_uuid = cookie;
|
||||||
_cookie_name = cookie_name;
|
_cookie_name = cookie_name;
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
manager->onAddCookie(_cookie_name,_uid,_cookie_uuid);
|
manager->onAddCookie(_cookie_name, _uid, _cookie_uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServerCookie::~HttpServerCookie() {
|
HttpServerCookie::~HttpServerCookie() {
|
||||||
auto strongManager = _manager.lock();
|
auto strongManager = _manager.lock();
|
||||||
if(strongManager){
|
if (strongManager) {
|
||||||
strongManager->onDelCookie(_cookie_name,_uid,_cookie_uuid);
|
strongManager->onDelCookie(_cookie_name, _uid, _cookie_uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string & HttpServerCookie::getUid() const{
|
const string &HttpServerCookie::getUid() const {
|
||||||
return _uid;
|
return _uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +45,11 @@ string HttpServerCookie::getCookie(const string &path) const {
|
|||||||
return (StrPrinter << _cookie_name << "=" << _cookie_uuid << ";expires=" << cookieExpireTime() << ";path=" << path);
|
return (StrPrinter << _cookie_name << "=" << _cookie_uuid << ";expires=" << cookieExpireTime() << ";path=" << path);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& HttpServerCookie::getCookie() const {
|
const string &HttpServerCookie::getCookie() const {
|
||||||
return _cookie_uuid;
|
return _cookie_uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& HttpServerCookie::getCookieName() const{
|
const string &HttpServerCookie::getCookieName() const {
|
||||||
return _cookie_name;
|
return _cookie_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,11 +61,11 @@ bool HttpServerCookie::isExpired() {
|
|||||||
return _ticker.elapsedTime() > _max_elapsed * 1000;
|
return _ticker.elapsedTime() > _max_elapsed * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<lock_guard<recursive_mutex> > HttpServerCookie::getLock(){
|
void HttpServerCookie::setAttach(std::shared_ptr<void> attach) {
|
||||||
return std::make_shared<lock_guard<recursive_mutex> >(_mtx);
|
_attach = std::move(attach);
|
||||||
}
|
}
|
||||||
|
|
||||||
string HttpServerCookie::cookieExpireTime() const{
|
string HttpServerCookie::cookieExpireTime() const {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
time_t tt = time(NULL) + _max_elapsed;
|
time_t tt = time(NULL) + _max_elapsed;
|
||||||
strftime(buf, sizeof buf, "%a, %b %d %Y %H:%M:%S GMT", gmtime(&tt));
|
strftime(buf, sizeof buf, "%a, %b %d %Y %H:%M:%S GMT", gmtime(&tt));
|
||||||
@ -78,10 +76,13 @@ INSTANCE_IMP(HttpCookieManager);
|
|||||||
|
|
||||||
HttpCookieManager::HttpCookieManager() {
|
HttpCookieManager::HttpCookieManager() {
|
||||||
//定时删除过期的cookie,防止内存膨胀
|
//定时删除过期的cookie,防止内存膨胀
|
||||||
_timer = std::make_shared<Timer>(10.0f,[this](){
|
_timer = std::make_shared<Timer>(
|
||||||
onManager();
|
10.0f,
|
||||||
return true;
|
[this]() {
|
||||||
}, nullptr);
|
onManager();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpCookieManager::~HttpCookieManager() {
|
HttpCookieManager::~HttpCookieManager() {
|
||||||
@ -91,11 +92,11 @@ HttpCookieManager::~HttpCookieManager() {
|
|||||||
void HttpCookieManager::onManager() {
|
void HttpCookieManager::onManager() {
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
//先遍历所有类型
|
//先遍历所有类型
|
||||||
for(auto it_name = _map_cookie.begin() ; it_name != _map_cookie.end() ;){
|
for (auto it_name = _map_cookie.begin(); it_name != _map_cookie.end();) {
|
||||||
//再遍历该类型下的所有cookie
|
//再遍历该类型下的所有cookie
|
||||||
for (auto it_cookie = it_name->second.begin() ; it_cookie != it_name->second.end() ; ){
|
for (auto it_cookie = it_name->second.begin(); it_cookie != it_name->second.end();) {
|
||||||
if(it_cookie->second->isExpired()){
|
if (it_cookie->second->isExpired()) {
|
||||||
//cookie过期,移除记录
|
// cookie过期,移除记录
|
||||||
DebugL << it_cookie->second->getUid() << " cookie过期:" << it_cookie->second->getCookie();
|
DebugL << it_cookie->second->getUid() << " cookie过期:" << it_cookie->second->getCookie();
|
||||||
it_cookie = it_name->second.erase(it_cookie);
|
it_cookie = it_name->second.erase(it_cookie);
|
||||||
continue;
|
continue;
|
||||||
@ -103,7 +104,7 @@ void HttpCookieManager::onManager() {
|
|||||||
++it_cookie;
|
++it_cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(it_name->second.empty()){
|
if (it_name->second.empty()) {
|
||||||
//该类型下没有任何cooki记录,移除之
|
//该类型下没有任何cooki记录,移除之
|
||||||
DebugL << "该path下没有任何cooki记录:" << it_name->first;
|
DebugL << "该path下没有任何cooki记录:" << it_name->first;
|
||||||
it_name = _map_cookie.erase(it_name);
|
it_name = _map_cookie.erase(it_name);
|
||||||
@ -113,36 +114,38 @@ void HttpCookieManager::onManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServerCookie::Ptr HttpCookieManager::addCookie(const string &cookie_name,const string &uidIn,uint64_t max_elapsed,int max_client) {
|
HttpServerCookie::Ptr HttpCookieManager::addCookie(const string &cookie_name, const string &uid_in,
|
||||||
|
uint64_t max_elapsed, std::shared_ptr<void> attach, int max_client) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
auto cookie = _geneator.obtain();
|
auto cookie = _geneator.obtain();
|
||||||
auto uid = uidIn.empty() ? cookie : uidIn;
|
auto uid = uid_in.empty() ? cookie : uid_in;
|
||||||
auto oldCookie = getOldestCookie(cookie_name , uid, max_client);
|
auto oldCookie = getOldestCookie(cookie_name, uid, max_client);
|
||||||
if(!oldCookie.empty()){
|
if (!oldCookie.empty()) {
|
||||||
//假如该账号已经登录了,那么删除老的cookie。
|
//假如该账号已经登录了,那么删除老的cookie。
|
||||||
//目的是实现单账号多地登录时挤占登录
|
//目的是实现单账号多地登录时挤占登录
|
||||||
delCookie(cookie_name,oldCookie);
|
delCookie(cookie_name, oldCookie);
|
||||||
}
|
}
|
||||||
HttpServerCookie::Ptr data(new HttpServerCookie(shared_from_this(),cookie_name,uid,cookie,max_elapsed));
|
HttpServerCookie::Ptr data(new HttpServerCookie(shared_from_this(), cookie_name, uid, cookie, max_elapsed));
|
||||||
|
data->setAttach(std::move(attach));
|
||||||
//保存该账号下的新cookie
|
//保存该账号下的新cookie
|
||||||
_map_cookie[cookie_name][cookie] = data;
|
_map_cookie[cookie_name][cookie] = data;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,const string &cookie) {
|
HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name, const string &cookie) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
auto it_name = _map_cookie.find(cookie_name);
|
auto it_name = _map_cookie.find(cookie_name);
|
||||||
if(it_name == _map_cookie.end()){
|
if (it_name == _map_cookie.end()) {
|
||||||
//不存在该类型的cookie
|
//不存在该类型的cookie
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto it_cookie = it_name->second.find(cookie);
|
auto it_cookie = it_name->second.find(cookie);
|
||||||
if(it_cookie == it_name->second.end()){
|
if (it_cookie == it_name->second.end()) {
|
||||||
//该类型下没有对应的cookie
|
//该类型下没有对应的cookie
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if(it_cookie->second->isExpired()){
|
if (it_cookie->second->isExpired()) {
|
||||||
//cookie过期
|
// cookie过期
|
||||||
DebugL << "cookie过期:" << it_cookie->second->getCookie();
|
DebugL << "cookie过期:" << it_cookie->second->getCookie();
|
||||||
it_name->second.erase(it_cookie);
|
it_name->second.erase(it_cookie);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -150,7 +153,7 @@ HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,con
|
|||||||
return it_cookie->second;
|
return it_cookie->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,const StrCaseMap &http_header) {
|
HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name, const StrCaseMap &http_header) {
|
||||||
auto it = http_header.find("Cookie");
|
auto it = http_header.find("Cookie");
|
||||||
if (it == http_header.end()) {
|
if (it == http_header.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -159,100 +162,100 @@ HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,con
|
|||||||
if (!cookie.size()) {
|
if (!cookie.size()) {
|
||||||
cookie = FindField(it->second.data(), (cookie_name + "=").data(), nullptr);
|
cookie = FindField(it->second.data(), (cookie_name + "=").data(), nullptr);
|
||||||
}
|
}
|
||||||
if(cookie.empty()){
|
if (cookie.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return HttpCookieManager::Instance().getCookie(cookie_name , cookie);
|
return HttpCookieManager::Instance().getCookie(cookie_name, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServerCookie::Ptr HttpCookieManager::getCookieByUid(const string &cookie_name,const string &uid){
|
HttpServerCookie::Ptr HttpCookieManager::getCookieByUid(const string &cookie_name, const string &uid) {
|
||||||
if(cookie_name.empty() || uid.empty()){
|
if (cookie_name.empty() || uid.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto cookie = getOldestCookie(cookie_name,uid);
|
auto cookie = getOldestCookie(cookie_name, uid);
|
||||||
if(cookie.empty()){
|
if (cookie.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return getCookie(cookie_name,cookie);
|
return getCookie(cookie_name, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpCookieManager::delCookie(const HttpServerCookie::Ptr &cookie) {
|
bool HttpCookieManager::delCookie(const HttpServerCookie::Ptr &cookie) {
|
||||||
if(!cookie){
|
if (!cookie) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return delCookie(cookie->getCookieName(),cookie->getCookie());
|
return delCookie(cookie->getCookieName(), cookie->getCookie());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpCookieManager::delCookie(const string &cookie_name,const string &cookie) {
|
bool HttpCookieManager::delCookie(const string &cookie_name, const string &cookie) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
auto it_name = _map_cookie.find(cookie_name);
|
auto it_name = _map_cookie.find(cookie_name);
|
||||||
if(it_name == _map_cookie.end()){
|
if (it_name == _map_cookie.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return it_name->second.erase(cookie);
|
return it_name->second.erase(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpCookieManager::onAddCookie(const string &cookie_name,const string &uid,const string &cookie){
|
void HttpCookieManager::onAddCookie(const string &cookie_name, const string &uid, const string &cookie) {
|
||||||
//添加新的cookie,我们记录下这个uid下有哪些cookie,目的是实现单账号多地登录时挤占登录
|
//添加新的cookie,我们记录下这个uid下有哪些cookie,目的是实现单账号多地登录时挤占登录
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
//相同用户下可以存在多个cookie(意味多地登录),这些cookie根据登录时间的早晚依次排序
|
//相同用户下可以存在多个cookie(意味多地登录),这些cookie根据登录时间的早晚依次排序
|
||||||
_map_uid_to_cookie[cookie_name][uid][getCurrentMillisecond()] = cookie;
|
_map_uid_to_cookie[cookie_name][uid][getCurrentMillisecond()] = cookie;
|
||||||
}
|
}
|
||||||
void HttpCookieManager::onDelCookie(const string &cookie_name,const string &uid,const string &cookie){
|
|
||||||
|
void HttpCookieManager::onDelCookie(const string &cookie_name, const string &uid, const string &cookie) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
//回收随机字符串
|
//回收随机字符串
|
||||||
_geneator.release(cookie);
|
_geneator.release(cookie);
|
||||||
|
|
||||||
auto it_name = _map_uid_to_cookie.find(cookie_name);
|
auto it_name = _map_uid_to_cookie.find(cookie_name);
|
||||||
if(it_name == _map_uid_to_cookie.end()){
|
if (it_name == _map_uid_to_cookie.end()) {
|
||||||
//该类型下未有任意用户登录
|
//该类型下未有任意用户登录
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto it_uid = it_name->second.find(uid);
|
auto it_uid = it_name->second.find(uid);
|
||||||
if(it_uid == it_name->second.end()){
|
if (it_uid == it_name->second.end()) {
|
||||||
//该用户尚未登录
|
//该用户尚未登录
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//遍历同一名用户下的所有客户端,移除命中的客户端
|
//遍历同一名用户下的所有客户端,移除命中的客户端
|
||||||
for(auto it_cookie = it_uid->second.begin() ; it_cookie != it_uid->second.end() ; ++it_cookie ){
|
for (auto it_cookie = it_uid->second.begin(); it_cookie != it_uid->second.end(); ++it_cookie) {
|
||||||
if(it_cookie->second != cookie) {
|
if (it_cookie->second != cookie) {
|
||||||
//不是该cookie
|
//不是该cookie
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//移除该用户名下的某个cookie,这个设备cookie将失效
|
//移除该用户名下的某个cookie,这个设备cookie将失效
|
||||||
it_uid->second.erase(it_cookie);
|
it_uid->second.erase(it_cookie);
|
||||||
|
|
||||||
if(it_uid->second.size() != 0) {
|
if (it_uid->second.size() != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//该用户名下没有任何设备在线,移除之
|
//该用户名下没有任何设备在线,移除之
|
||||||
it_name->second.erase(it_uid);
|
it_name->second.erase(it_uid);
|
||||||
|
|
||||||
if(it_name->second.size() != 0) {
|
if (it_name->second.size() != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//该类型下未有任何用户在线,移除之
|
//该类型下未有任何用户在线,移除之
|
||||||
_map_uid_to_cookie.erase(it_name);
|
_map_uid_to_cookie.erase(it_name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string HttpCookieManager::getOldestCookie(const string &cookie_name,const string &uid, int max_client){
|
string HttpCookieManager::getOldestCookie(const string &cookie_name, const string &uid, int max_client) {
|
||||||
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
lock_guard<recursive_mutex> lck(_mtx_cookie);
|
||||||
auto it_name = _map_uid_to_cookie.find(cookie_name);
|
auto it_name = _map_uid_to_cookie.find(cookie_name);
|
||||||
if(it_name == _map_uid_to_cookie.end()){
|
if (it_name == _map_uid_to_cookie.end()) {
|
||||||
//不存在该类型的cookie
|
//不存在该类型的cookie
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
auto it_uid = it_name->second.find(uid);
|
auto it_uid = it_name->second.find(uid);
|
||||||
if(it_uid == it_name->second.end()){
|
if (it_uid == it_name->second.end()) {
|
||||||
//该用户从未登录过
|
//该用户从未登录过
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if(it_uid->second.size() < MAX(1,max_client)){
|
if (it_uid->second.size() < MAX(1, max_client)) {
|
||||||
//同一名用户下,客户端个数还没达到限制个数
|
//同一名用户下,客户端个数还没达到限制个数
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -261,28 +264,29 @@ string HttpCookieManager::getOldestCookie(const string &cookie_name,const string
|
|||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////RandStrGeneator////////////////////////////////////
|
/////////////////////////////////RandStrGeneator////////////////////////////////////
|
||||||
string RandStrGeneator::obtain(){
|
string RandStrGeneator::obtain() {
|
||||||
//获取唯一的防膨胀的随机字符串
|
//获取唯一的防膨胀的随机字符串
|
||||||
while (true){
|
while (true) {
|
||||||
auto str = obtain_l();
|
auto str = obtain_l();
|
||||||
if(_obtained.find(str) == _obtained.end()){
|
if (_obtained.find(str) == _obtained.end()) {
|
||||||
//没有重复
|
//没有重复
|
||||||
_obtained.emplace(str);
|
_obtained.emplace(str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void RandStrGeneator::release(const string &str){
|
|
||||||
|
void RandStrGeneator::release(const string &str) {
|
||||||
//从防膨胀库中移除
|
//从防膨胀库中移除
|
||||||
_obtained.erase(str);
|
_obtained.erase(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
string RandStrGeneator::obtain_l(){
|
string RandStrGeneator::obtain_l() {
|
||||||
//12个伪随机字节 + 4个递增的整形字节,然后md5即为随机字符串
|
// 12个伪随机字节 + 4个递增的整形字节,然后md5即为随机字符串
|
||||||
auto str = makeRandStr(12,false);
|
auto str = makeRandStr(12, false);
|
||||||
str.append((char *)&_index, sizeof(_index));
|
str.append((char *)&_index, sizeof(_index));
|
||||||
++_index;
|
++_index;
|
||||||
return MD5(str).hexdigest();
|
return MD5(str).hexdigest();
|
||||||
}
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
} // namespace mediakit
|
@ -11,13 +11,13 @@
|
|||||||
#ifndef SRC_HTTP_COOKIEMANAGER_H
|
#ifndef SRC_HTTP_COOKIEMANAGER_H
|
||||||
#define SRC_HTTP_COOKIEMANAGER_H
|
#define SRC_HTTP_COOKIEMANAGER_H
|
||||||
|
|
||||||
#include <memory>
|
#include "Common/Parser.h"
|
||||||
#include <unordered_map>
|
#include "Network/Socket.h"
|
||||||
|
#include "Util/TimeTicker.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include <memory>
|
||||||
#include "Network/Socket.h"
|
#include <unordered_map>
|
||||||
#include "Common/Parser.h"
|
|
||||||
|
|
||||||
#define COOKIE_DEFAULT_LIFE (7 * 24 * 60 * 60)
|
#define COOKIE_DEFAULT_LIFE (7 * 24 * 60 * 60)
|
||||||
|
|
||||||
@ -28,9 +28,9 @@ class HttpCookieManager;
|
|||||||
/**
|
/**
|
||||||
* cookie对象,用于保存cookie的一些相关属性
|
* cookie对象,用于保存cookie的一些相关属性
|
||||||
*/
|
*/
|
||||||
class HttpServerCookie : public toolkit::AnyStorage , public toolkit::noncopyable{
|
class HttpServerCookie : public toolkit::noncopyable {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<HttpServerCookie> Ptr;
|
using Ptr = std::shared_ptr<HttpServerCookie>;
|
||||||
/**
|
/**
|
||||||
* 构建cookie
|
* 构建cookie
|
||||||
* @param manager cookie管理者对象
|
* @param manager cookie管理者对象
|
||||||
@ -40,12 +40,10 @@ public:
|
|||||||
* @param max_elapsed 最大过期时间,单位秒
|
* @param max_elapsed 最大过期时间,单位秒
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HttpServerCookie(const std::shared_ptr<HttpCookieManager> &manager,
|
HttpServerCookie(
|
||||||
const std::string &cookie_name,
|
const std::shared_ptr<HttpCookieManager> &manager, const std::string &cookie_name, const std::string &uid,
|
||||||
const std::string &uid,
|
const std::string &cookie, uint64_t max_elapsed);
|
||||||
const std::string &cookie,
|
~HttpServerCookie();
|
||||||
uint64_t max_elapsed);
|
|
||||||
~HttpServerCookie() ;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取uid
|
* 获取uid
|
||||||
@ -65,13 +63,13 @@ public:
|
|||||||
* 获取cookie随机字符串
|
* 获取cookie随机字符串
|
||||||
* @return cookie随机字符串
|
* @return cookie随机字符串
|
||||||
*/
|
*/
|
||||||
const std::string& getCookie() const;
|
const std::string &getCookie() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取该cookie名
|
* 获取该cookie名
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::string& getCookieName() const;
|
const std::string &getCookieName() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新该cookie的过期时间,可以让此cookie不失效
|
* 更新该cookie的过期时间,可以让此cookie不失效
|
||||||
@ -85,26 +83,35 @@ public:
|
|||||||
bool isExpired();
|
bool isExpired();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取区域锁
|
* 设置附加数据
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<std::lock_guard<std::recursive_mutex> > getLock();
|
void setAttach(std::shared_ptr<void> attach);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 获取附加数据
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
const T& getAttach() const {
|
||||||
|
return *static_cast<const T *>(_attach.get());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string cookieExpireTime() const ;
|
std::string cookieExpireTime() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _uid;
|
std::string _uid;
|
||||||
std::string _cookie_name;
|
std::string _cookie_name;
|
||||||
std::string _cookie_uuid;
|
std::string _cookie_uuid;
|
||||||
uint64_t _max_elapsed;
|
uint64_t _max_elapsed;
|
||||||
toolkit::Ticker _ticker;
|
toolkit::Ticker _ticker;
|
||||||
std::recursive_mutex _mtx;
|
std::shared_ptr<void> _attach;
|
||||||
std::weak_ptr<HttpCookieManager> _manager;
|
std::weak_ptr<HttpCookieManager> _manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cookie随机字符串生成器
|
* cookie随机字符串生成器
|
||||||
*/
|
*/
|
||||||
class RandStrGeneator{
|
class RandStrGeneator {
|
||||||
public:
|
public:
|
||||||
RandStrGeneator() = default;
|
RandStrGeneator() = default;
|
||||||
~RandStrGeneator() = default;
|
~RandStrGeneator() = default;
|
||||||
@ -120,8 +127,10 @@ public:
|
|||||||
* @param str 随机字符串
|
* @param str 随机字符串
|
||||||
*/
|
*/
|
||||||
void release(const std::string &str);
|
void release(const std::string &str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string obtain_l();
|
std::string obtain_l();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//碰撞库
|
//碰撞库
|
||||||
std::unordered_set<std::string> _obtained;
|
std::unordered_set<std::string> _obtained;
|
||||||
@ -135,8 +144,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
class HttpCookieManager : public std::enable_shared_from_this<HttpCookieManager> {
|
class HttpCookieManager : public std::enable_shared_from_this<HttpCookieManager> {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<HttpCookieManager> Ptr;
|
|
||||||
friend class HttpServerCookie;
|
friend class HttpServerCookie;
|
||||||
|
using Ptr = std::shared_ptr<HttpCookieManager>;
|
||||||
~HttpCookieManager();
|
~HttpCookieManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,7 +161,10 @@ public:
|
|||||||
* @param max_elapsed 该cookie过期时间,单位秒
|
* @param max_elapsed 该cookie过期时间,单位秒
|
||||||
* @return cookie对象
|
* @return cookie对象
|
||||||
*/
|
*/
|
||||||
HttpServerCookie::Ptr addCookie(const std::string &cookie_name,const std::string &uid, uint64_t max_elapsed = COOKIE_DEFAULT_LIFE,int max_client = 1);
|
HttpServerCookie::Ptr addCookie(
|
||||||
|
const std::string &cookie_name, const std::string &uid, uint64_t max_elapsed = COOKIE_DEFAULT_LIFE,
|
||||||
|
std::shared_ptr<void> attach = nullptr,
|
||||||
|
int max_client = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据cookie随机字符串查找cookie对象
|
* 根据cookie随机字符串查找cookie对象
|
||||||
@ -160,7 +172,7 @@ public:
|
|||||||
* @param cookie cookie随机字符串
|
* @param cookie cookie随机字符串
|
||||||
* @return cookie对象,可以为nullptr
|
* @return cookie对象,可以为nullptr
|
||||||
*/
|
*/
|
||||||
HttpServerCookie::Ptr getCookie(const std::string &cookie_name,const std::string &cookie);
|
HttpServerCookie::Ptr getCookie(const std::string &cookie_name, const std::string &cookie);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从http头中获取cookie对象
|
* 从http头中获取cookie对象
|
||||||
@ -168,7 +180,7 @@ public:
|
|||||||
* @param http_header http头
|
* @param http_header http头
|
||||||
* @return cookie对象
|
* @return cookie对象
|
||||||
*/
|
*/
|
||||||
HttpServerCookie::Ptr getCookie(const std::string &cookie_name,const StrCaseMap &http_header);
|
HttpServerCookie::Ptr getCookie(const std::string &cookie_name, const StrCaseMap &http_header);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据uid获取cookie
|
* 根据uid获取cookie
|
||||||
@ -176,7 +188,7 @@ public:
|
|||||||
* @param uid 用户id
|
* @param uid 用户id
|
||||||
* @return cookie对象
|
* @return cookie对象
|
||||||
*/
|
*/
|
||||||
HttpServerCookie::Ptr getCookieByUid(const std::string &cookie_name,const std::string &uid);
|
HttpServerCookie::Ptr getCookieByUid(const std::string &cookie_name, const std::string &uid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除cookie,用户登出时使用
|
* 删除cookie,用户登出时使用
|
||||||
@ -184,8 +196,10 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool delCookie(const HttpServerCookie::Ptr &cookie);
|
bool delCookie(const HttpServerCookie::Ptr &cookie);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HttpCookieManager();
|
HttpCookieManager();
|
||||||
|
|
||||||
void onManager();
|
void onManager();
|
||||||
/**
|
/**
|
||||||
* 构造cookie对象时触发,目的是记录某账号下多个cookie
|
* 构造cookie对象时触发,目的是记录某账号下多个cookie
|
||||||
@ -193,7 +207,7 @@ private:
|
|||||||
* @param uid 用户id
|
* @param uid 用户id
|
||||||
* @param cookie cookie随机字符串
|
* @param cookie cookie随机字符串
|
||||||
*/
|
*/
|
||||||
void onAddCookie(const std::string &cookie_name,const std::string &uid,const std::string &cookie);
|
void onAddCookie(const std::string &cookie_name, const std::string &uid, const std::string &cookie);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 析构cookie对象时触发
|
* 析构cookie对象时触发
|
||||||
@ -201,7 +215,7 @@ private:
|
|||||||
* @param uid 用户id
|
* @param uid 用户id
|
||||||
* @param cookie cookie随机字符串
|
* @param cookie cookie随机字符串
|
||||||
*/
|
*/
|
||||||
void onDelCookie(const std::string &cookie_name,const std::string &uid,const std::string &cookie);
|
void onDelCookie(const std::string &cookie_name, const std::string &uid, const std::string &cookie);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取某用户名下最先登录时的cookie,目的是实现某用户下最多登录若干个设备
|
* 获取某用户名下最先登录时的cookie,目的是实现某用户下最多登录若干个设备
|
||||||
@ -210,7 +224,7 @@ private:
|
|||||||
* @param max_client 最多登录的设备个数
|
* @param max_client 最多登录的设备个数
|
||||||
* @return 最早的cookie随机字符串
|
* @return 最早的cookie随机字符串
|
||||||
*/
|
*/
|
||||||
std::string getOldestCookie(const std::string &cookie_name,const std::string &uid, int max_client = 1);
|
std::string getOldestCookie(const std::string &cookie_name, const std::string &uid, int max_client = 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除cookie
|
* 删除cookie
|
||||||
@ -218,16 +232,21 @@ private:
|
|||||||
* @param cookie cookie随机字符串
|
* @param cookie cookie随机字符串
|
||||||
* @return 成功true
|
* @return 成功true
|
||||||
*/
|
*/
|
||||||
bool delCookie(const std::string &cookie_name,const std::string &cookie);
|
bool delCookie(const std::string &cookie_name, const std::string &cookie);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string/*cookie_name*/,std::unordered_map<std::string/*cookie*/,HttpServerCookie::Ptr/*cookie_data*/> >_map_cookie;
|
std::unordered_map<
|
||||||
std::unordered_map<std::string/*cookie_name*/,std::unordered_map<std::string/*uid*/,std::map<uint64_t/*cookie time stamp*/,std::string/*cookie*/> > >_map_uid_to_cookie;
|
std::string /*cookie_name*/, std::unordered_map<std::string /*cookie*/, HttpServerCookie::Ptr /*cookie_data*/>>
|
||||||
|
_map_cookie;
|
||||||
|
std::unordered_map<
|
||||||
|
std::string /*cookie_name*/,
|
||||||
|
std::unordered_map<std::string /*uid*/, std::map<uint64_t /*cookie time stamp*/, std::string /*cookie*/>>>
|
||||||
|
_map_uid_to_cookie;
|
||||||
std::recursive_mutex _mtx_cookie;
|
std::recursive_mutex _mtx_cookie;
|
||||||
toolkit::Timer::Ptr _timer;
|
toolkit::Timer::Ptr _timer;
|
||||||
RandStrGeneator _geneator;
|
RandStrGeneator _geneator;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
} // namespace mediakit
|
||||||
|
|
||||||
|
#endif // SRC_HTTP_COOKIEMANAGER_H
|
||||||
#endif //SRC_HTTP_COOKIEMANAGER_H
|
|
||||||
|
@ -33,9 +33,6 @@ static const string kCookieName = "ZL_COOKIE";
|
|||||||
static const string kHlsSuffix = "/hls.m3u8";
|
static const string kHlsSuffix = "/hls.m3u8";
|
||||||
|
|
||||||
class HttpCookieAttachment {
|
class HttpCookieAttachment {
|
||||||
public:
|
|
||||||
HttpCookieAttachment() {};
|
|
||||||
~HttpCookieAttachment() {};
|
|
||||||
public:
|
public:
|
||||||
//cookie生效作用域,本cookie只对该目录下的文件生效
|
//cookie生效作用域,本cookie只对该目录下的文件生效
|
||||||
string _path;
|
string _path;
|
||||||
@ -265,13 +262,12 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
|
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
//找到了cookie,对cookie上锁先
|
//找到了cookie,对cookie上锁先
|
||||||
auto lck = cookie->getLock();
|
auto& attach = cookie->getAttach<HttpCookieAttachment>();
|
||||||
auto attachment = (*cookie)[kCookieName].get<HttpCookieAttachment>();
|
if (path.find(attach._path) == 0) {
|
||||||
if (path.find(attachment._path) == 0) {
|
|
||||||
//上次cookie是限定本目录
|
//上次cookie是限定本目录
|
||||||
if (attachment._err_msg.empty()) {
|
if (attach._err_msg.empty()) {
|
||||||
//上次鉴权成功
|
//上次鉴权成功
|
||||||
if (attachment._is_hls) {
|
if (attach._is_hls) {
|
||||||
//如果播放的是hls,那么刷新hls的cookie(获取ts文件也会刷新)
|
//如果播放的是hls,那么刷新hls的cookie(获取ts文件也会刷新)
|
||||||
cookie->updateTime();
|
cookie->updateTime();
|
||||||
cookie_from_header = false;
|
cookie_from_header = false;
|
||||||
@ -282,7 +278,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
//上次鉴权失败,但是如果url参数发生变更,那么也重新鉴权下
|
//上次鉴权失败,但是如果url参数发生变更,那么也重新鉴权下
|
||||||
if (parser.Params().empty() || parser.Params() == cookie->getUid()) {
|
if (parser.Params().empty() || parser.Params() == cookie->getUid()) {
|
||||||
//url参数未变,或者本来就没有url参数,那么判断本次请求为重复请求,无访问权限
|
//url参数未变,或者本来就没有url参数,那么判断本次请求为重复请求,无访问权限
|
||||||
callback(attachment._err_msg, cookie_from_header ? nullptr : cookie);
|
callback(attach._err_msg, cookie_from_header ? nullptr : cookie);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,9 +297,9 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
|
|
||||||
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
|
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
|
||||||
HttpSession::HttpAccessPathInvoker accessPathInvoker = [callback, uid, path, is_dir, is_hls, mediaInfo, info]
|
HttpSession::HttpAccessPathInvoker accessPathInvoker = [callback, uid, path, is_dir, is_hls, mediaInfo, info]
|
||||||
(const string &errMsg, const string &cookie_path_in, int cookieLifeSecond) {
|
(const string &err_msg, const string &cookie_path_in, int life_second) {
|
||||||
HttpServerCookie::Ptr cookie;
|
HttpServerCookie::Ptr cookie;
|
||||||
if (cookieLifeSecond) {
|
if (life_second) {
|
||||||
//本次鉴权设置了有效期,我们把鉴权结果缓存在cookie中
|
//本次鉴权设置了有效期,我们把鉴权结果缓存在cookie中
|
||||||
string cookie_path = cookie_path_in;
|
string cookie_path = cookie_path_in;
|
||||||
if (cookie_path.empty()) {
|
if (cookie_path.empty()) {
|
||||||
@ -311,26 +307,22 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
cookie_path = is_dir ? path : path.substr(0, path.rfind("/") + 1);
|
cookie_path = is_dir ? path : path.substr(0, path.rfind("/") + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie = HttpCookieManager::Instance().addCookie(kCookieName, uid, cookieLifeSecond);
|
auto attach = std::make_shared<HttpCookieAttachment>();
|
||||||
//对cookie上锁
|
|
||||||
auto lck = cookie->getLock();
|
|
||||||
HttpCookieAttachment attachment;
|
|
||||||
//记录用户能访问的路径
|
//记录用户能访问的路径
|
||||||
attachment._path = cookie_path;
|
attach->_path = cookie_path;
|
||||||
//记录能否访问
|
//记录能否访问
|
||||||
attachment._err_msg = errMsg;
|
attach->_err_msg = err_msg;
|
||||||
//记录访问的是否为hls
|
//记录访问的是否为hls
|
||||||
attachment._is_hls = is_hls;
|
attach->_is_hls = is_hls;
|
||||||
if (is_hls) {
|
if (is_hls) {
|
||||||
//hls相关信息
|
// hls相关信息
|
||||||
attachment._hls_data = std::make_shared<HlsCookieData>(mediaInfo, info);
|
attach->_hls_data = std::make_shared<HlsCookieData>(mediaInfo, info);
|
||||||
//hls未查找MediaSource
|
// hls未查找MediaSource
|
||||||
attachment._have_find_media_source = false;
|
attach->_have_find_media_source = false;
|
||||||
}
|
}
|
||||||
(*cookie)[kCookieName].set<HttpCookieAttachment>(std::move(attachment));
|
callback(err_msg, HttpCookieManager::Instance().addCookie(kCookieName, uid, life_second, attach));
|
||||||
callback(errMsg, cookie);
|
|
||||||
} else {
|
} else {
|
||||||
callback(errMsg, nullptr);
|
callback(err_msg, nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -401,8 +393,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
//文件鉴权失败
|
//文件鉴权失败
|
||||||
StrCaseMap headerOut;
|
StrCaseMap headerOut;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
auto lck = cookie->getLock();
|
headerOut["Set-Cookie"] = cookie->getAttach<HttpCookieAttachment>()._path;
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
|
||||||
}
|
}
|
||||||
cb(401, "text/html", headerOut, std::make_shared<HttpStringBody>(errMsg));
|
cb(401, "text/html", headerOut, std::make_shared<HttpStringBody>(errMsg));
|
||||||
return;
|
return;
|
||||||
@ -411,15 +402,13 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
auto response_file = [file_exist, is_hls](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) {
|
auto response_file = [file_exist, is_hls](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) {
|
||||||
StrCaseMap httpHeader;
|
StrCaseMap httpHeader;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
auto lck = cookie->getLock();
|
httpHeader["Set-Cookie"] = cookie->getAttach<HttpCookieAttachment>()._path;
|
||||||
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
|
||||||
}
|
}
|
||||||
HttpSession::HttpResponseInvoker invoker = [&](int code, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
HttpSession::HttpResponseInvoker invoker = [&](int code, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
||||||
if (cookie && file_exist) {
|
if (cookie && file_exist) {
|
||||||
auto lck = cookie->getLock();
|
auto& attach = cookie->getAttach<HttpCookieAttachment>();
|
||||||
auto is_hls = (*cookie)[kCookieName].get<HttpCookieAttachment>()._is_hls;
|
if (attach._is_hls) {
|
||||||
if (is_hls) {
|
attach._hls_data->addByteUsage(body->remainSize());
|
||||||
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(body->remainSize());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cb(code, HttpFileManager::getContentType(strFile.data()), headerOut, body);
|
cb(code, HttpFileManager::getContentType(strFile.data()), headerOut, body);
|
||||||
@ -436,10 +425,10 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
//是hls直播,判断HLS直播流是否已经注册
|
//是hls直播,判断HLS直播流是否已经注册
|
||||||
bool have_find_media_src = false;
|
bool have_find_media_src = false;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
auto lck = cookie->getLock();
|
auto& attach = cookie->getAttach<HttpCookieAttachment>();
|
||||||
have_find_media_src = (*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source;
|
have_find_media_src = attach._have_find_media_source;
|
||||||
if (!have_find_media_src) {
|
if (!have_find_media_src) {
|
||||||
(*cookie)[kCookieName].get<HttpCookieAttachment>()._have_find_media_source = true;
|
const_cast<HttpCookieAttachment &>(attach)._have_find_media_source = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (have_find_media_src) {
|
if (have_find_media_src) {
|
||||||
@ -450,9 +439,8 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
//hls文件不存在,我们等待其生成并延后回复
|
//hls文件不存在,我们等待其生成并延后回复
|
||||||
MediaSource::findAsync(mediaInfo, strongSession, [response_file, cookie, cb, strFile, parser](const MediaSource::Ptr &src) {
|
MediaSource::findAsync(mediaInfo, strongSession, [response_file, cookie, cb, strFile, parser](const MediaSource::Ptr &src) {
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
auto lck = cookie->getLock();
|
|
||||||
//尝试添加HlsMediaSource的观看人数(HLS是按需生成的,这样可以触发HLS文件的生成)
|
//尝试添加HlsMediaSource的观看人数(HLS是按需生成的,这样可以触发HLS文件的生成)
|
||||||
(*cookie)[kCookieName].get<HttpCookieAttachment>()._hls_data->addByteUsage(0);
|
cookie->getAttach<HttpCookieAttachment>()._hls_data->addByteUsage(0);
|
||||||
}
|
}
|
||||||
if (src && File::is_file(strFile.data())) {
|
if (src && File::is_file(strFile.data())) {
|
||||||
//流和m3u8文件都存在,那么直接返回文件
|
//流和m3u8文件都存在,那么直接返回文件
|
||||||
@ -531,7 +519,7 @@ void HttpFileManager::onAccessPath(TcpSession &sender, Parser &parser, const Htt
|
|||||||
}
|
}
|
||||||
StrCaseMap headerOut;
|
StrCaseMap headerOut;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookieName].get<HttpCookieAttachment>()._path);
|
headerOut["Set-Cookie"] = cookie->getAttach<HttpCookieAttachment>()._path;
|
||||||
}
|
}
|
||||||
cb(errMsg.empty() ? 200 : 401, "text/html", headerOut, std::make_shared<HttpStringBody>(strMenu));
|
cb(errMsg.empty() ? 200 : 401, "text/html", headerOut, std::make_shared<HttpStringBody>(strMenu));
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user