Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
36f24527
Commit
36f24527
authored
Feb 11, 2022
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
http cookie减少互斥锁,优化性能
parent
c510f376
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
156 行增加
和
145 行删除
+156
-145
src/Http/HttpCookieManager.cpp
+75
-71
src/Http/HttpCookieManager.h
+54
-35
src/Http/HttpFileManager.cpp
+27
-39
没有找到文件。
src/Http/HttpCookieManager.cpp
查看文件 @
36f24527
...
...
@@ -8,10 +8,10 @@
* 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 "Common/config.h"
#include "Util/MD5.h"
#include "Util/util.h"
using
namespace
std
;
using
namespace
toolkit
;
...
...
@@ -19,27 +19,25 @@ using namespace toolkit;
namespace
mediakit
{
//////////////////////////////HttpServerCookie////////////////////////////////////
HttpServerCookie
::
HttpServerCookie
(
const
std
::
shared_ptr
<
HttpCookieManager
>
&
manager
,
const
string
&
cookie_name
,
const
string
&
uid
,
const
string
&
cookie
,
uint64_t
max_elapsed
){
HttpServerCookie
::
HttpServerCookie
(
const
std
::
shared_ptr
<
HttpCookieManager
>
&
manager
,
const
string
&
cookie_name
,
const
string
&
uid
,
const
string
&
cookie
,
uint64_t
max_elapsed
)
{
_uid
=
uid
;
_max_elapsed
=
max_elapsed
;
_cookie_uuid
=
cookie
;
_cookie_name
=
cookie_name
;
_manager
=
manager
;
manager
->
onAddCookie
(
_cookie_name
,
_uid
,
_cookie_uuid
);
manager
->
onAddCookie
(
_cookie_name
,
_uid
,
_cookie_uuid
);
}
HttpServerCookie
::~
HttpServerCookie
()
{
auto
strongManager
=
_manager
.
lock
();
if
(
strongManager
)
{
strongManager
->
onDelCookie
(
_cookie_name
,
_uid
,
_cookie_uuid
);
if
(
strongManager
)
{
strongManager
->
onDelCookie
(
_cookie_name
,
_uid
,
_cookie_uuid
);
}
}
const
string
&
HttpServerCookie
::
getUid
()
const
{
const
string
&
HttpServerCookie
::
getUid
()
const
{
return
_uid
;
}
...
...
@@ -47,11 +45,11 @@ string HttpServerCookie::getCookie(const string &path) const {
return
(
StrPrinter
<<
_cookie_name
<<
"="
<<
_cookie_uuid
<<
";expires="
<<
cookieExpireTime
()
<<
";path="
<<
path
);
}
const
string
&
HttpServerCookie
::
getCookie
()
const
{
const
string
&
HttpServerCookie
::
getCookie
()
const
{
return
_cookie_uuid
;
}
const
string
&
HttpServerCookie
::
getCookieName
()
const
{
const
string
&
HttpServerCookie
::
getCookieName
()
const
{
return
_cookie_name
;
}
...
...
@@ -63,11 +61,11 @@ bool HttpServerCookie::isExpired() {
return
_ticker
.
elapsedTime
()
>
_max_elapsed
*
1000
;
}
std
::
shared_ptr
<
lock_guard
<
recursive_mutex
>
>
HttpServerCookie
::
getLock
()
{
return
std
::
make_shared
<
lock_guard
<
recursive_mutex
>
>
(
_mtx
);
void
HttpServerCookie
::
setAttach
(
std
::
shared_ptr
<
void
>
attach
)
{
_attach
=
std
::
move
(
attach
);
}
string
HttpServerCookie
::
cookieExpireTime
()
const
{
string
HttpServerCookie
::
cookieExpireTime
()
const
{
char
buf
[
64
];
time_t
tt
=
time
(
NULL
)
+
_max_elapsed
;
strftime
(
buf
,
sizeof
buf
,
"%a, %b %d %Y %H:%M:%S GMT"
,
gmtime
(
&
tt
));
...
...
@@ -78,10 +76,13 @@ INSTANCE_IMP(HttpCookieManager);
HttpCookieManager
::
HttpCookieManager
()
{
//定时删除过期的cookie,防止内存膨胀
_timer
=
std
::
make_shared
<
Timer
>
(
10.0
f
,[
this
](){
onManager
();
return
true
;
},
nullptr
);
_timer
=
std
::
make_shared
<
Timer
>
(
10.0
f
,
[
this
]()
{
onManager
();
return
true
;
},
nullptr
);
}
HttpCookieManager
::~
HttpCookieManager
()
{
...
...
@@ -91,11 +92,11 @@ HttpCookieManager::~HttpCookieManager() {
void
HttpCookieManager
::
onManager
()
{
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
for
(
auto
it_cookie
=
it_name
->
second
.
begin
()
;
it_cookie
!=
it_name
->
second
.
end
()
;
)
{
if
(
it_cookie
->
second
->
isExpired
())
{
//cookie过期,移除记录
for
(
auto
it_cookie
=
it_name
->
second
.
begin
()
;
it_cookie
!=
it_name
->
second
.
end
();)
{
if
(
it_cookie
->
second
->
isExpired
())
{
//
cookie过期,移除记录
DebugL
<<
it_cookie
->
second
->
getUid
()
<<
" cookie过期:"
<<
it_cookie
->
second
->
getCookie
();
it_cookie
=
it_name
->
second
.
erase
(
it_cookie
);
continue
;
...
...
@@ -103,7 +104,7 @@ void HttpCookieManager::onManager() {
++
it_cookie
;
}
if
(
it_name
->
second
.
empty
())
{
if
(
it_name
->
second
.
empty
())
{
//该类型下没有任何cooki记录,移除之
DebugL
<<
"该path下没有任何cooki记录:"
<<
it_name
->
first
;
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
);
auto
cookie
=
_geneator
.
obtain
();
auto
uid
=
uid
In
.
empty
()
?
cookie
:
uidI
n
;
auto
oldCookie
=
getOldestCookie
(
cookie_name
,
uid
,
max_client
);
if
(
!
oldCookie
.
empty
())
{
auto
uid
=
uid
_in
.
empty
()
?
cookie
:
uid_i
n
;
auto
oldCookie
=
getOldestCookie
(
cookie_name
,
uid
,
max_client
);
if
(
!
oldCookie
.
empty
())
{
//假如该账号已经登录了,那么删除老的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
_map_cookie
[
cookie_name
][
cookie
]
=
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
);
auto
it_name
=
_map_cookie
.
find
(
cookie_name
);
if
(
it_name
==
_map_cookie
.
end
())
{
if
(
it_name
==
_map_cookie
.
end
())
{
//不存在该类型的cookie
return
nullptr
;
}
auto
it_cookie
=
it_name
->
second
.
find
(
cookie
);
if
(
it_cookie
==
it_name
->
second
.
end
())
{
if
(
it_cookie
==
it_name
->
second
.
end
())
{
//该类型下没有对应的cookie
return
nullptr
;
}
if
(
it_cookie
->
second
->
isExpired
())
{
//cookie过期
if
(
it_cookie
->
second
->
isExpired
())
{
//
cookie过期
DebugL
<<
"cookie过期:"
<<
it_cookie
->
second
->
getCookie
();
it_name
->
second
.
erase
(
it_cookie
);
return
nullptr
;
...
...
@@ -150,7 +153,7 @@ HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,con
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"
);
if
(
it
==
http_header
.
end
())
{
return
nullptr
;
...
...
@@ -159,100 +162,100 @@ HttpServerCookie::Ptr HttpCookieManager::getCookie(const string &cookie_name,con
if
(
!
cookie
.
size
())
{
cookie
=
FindField
(
it
->
second
.
data
(),
(
cookie_name
+
"="
).
data
(),
nullptr
);
}
if
(
cookie
.
empty
())
{
if
(
cookie
.
empty
())
{
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
)
{
if
(
cookie_name
.
empty
()
||
uid
.
empty
())
{
HttpServerCookie
::
Ptr
HttpCookieManager
::
getCookieByUid
(
const
string
&
cookie_name
,
const
string
&
uid
)
{
if
(
cookie_name
.
empty
()
||
uid
.
empty
())
{
return
nullptr
;
}
auto
cookie
=
getOldestCookie
(
cookie_name
,
uid
);
if
(
cookie
.
empty
())
{
auto
cookie
=
getOldestCookie
(
cookie_name
,
uid
);
if
(
cookie
.
empty
())
{
return
nullptr
;
}
return
getCookie
(
cookie_name
,
cookie
);
return
getCookie
(
cookie_name
,
cookie
);
}
bool
HttpCookieManager
::
delCookie
(
const
HttpServerCookie
::
Ptr
&
cookie
)
{
if
(
!
cookie
)
{
if
(
!
cookie
)
{
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
);
auto
it_name
=
_map_cookie
.
find
(
cookie_name
);
if
(
it_name
==
_map_cookie
.
end
())
{
if
(
it_name
==
_map_cookie
.
end
())
{
return
false
;
}
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,目的是实现单账号多地登录时挤占登录
lock_guard
<
recursive_mutex
>
lck
(
_mtx_cookie
);
//相同用户下可以存在多个cookie(意味多地登录),这些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
);
//回收随机字符串
_geneator
.
release
(
cookie
);
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
;
}
auto
it_uid
=
it_name
->
second
.
find
(
uid
);
if
(
it_uid
==
it_name
->
second
.
end
())
{
if
(
it_uid
==
it_name
->
second
.
end
())
{
//该用户尚未登录
return
;
}
//遍历同一名用户下的所有客户端,移除命中的客户端
for
(
auto
it_cookie
=
it_uid
->
second
.
begin
()
;
it_cookie
!=
it_uid
->
second
.
end
()
;
++
it_cookie
)
{
if
(
it_cookie
->
second
!=
cookie
)
{
for
(
auto
it_cookie
=
it_uid
->
second
.
begin
();
it_cookie
!=
it_uid
->
second
.
end
();
++
it_cookie
)
{
if
(
it_cookie
->
second
!=
cookie
)
{
//不是该cookie
continue
;
}
//移除该用户名下的某个cookie,这个设备cookie将失效
it_uid
->
second
.
erase
(
it_cookie
);
if
(
it_uid
->
second
.
size
()
!=
0
)
{
if
(
it_uid
->
second
.
size
()
!=
0
)
{
break
;
}
//该用户名下没有任何设备在线,移除之
it_name
->
second
.
erase
(
it_uid
);
if
(
it_name
->
second
.
size
()
!=
0
)
{
if
(
it_name
->
second
.
size
()
!=
0
)
{
break
;
}
//该类型下未有任何用户在线,移除之
_map_uid_to_cookie
.
erase
(
it_name
);
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
);
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
return
""
;
}
auto
it_uid
=
it_name
->
second
.
find
(
uid
);
if
(
it_uid
==
it_name
->
second
.
end
())
{
if
(
it_uid
==
it_name
->
second
.
end
())
{
//该用户从未登录过
return
""
;
}
if
(
it_uid
->
second
.
size
()
<
MAX
(
1
,
max_client
))
{
if
(
it_uid
->
second
.
size
()
<
MAX
(
1
,
max_client
))
{
//同一名用户下,客户端个数还没达到限制个数
return
""
;
}
...
...
@@ -261,28 +264,29 @@ string HttpCookieManager::getOldestCookie(const string &cookie_name,const string
}
/////////////////////////////////RandStrGeneator////////////////////////////////////
string
RandStrGeneator
::
obtain
(){
string
RandStrGeneator
::
obtain
()
{
//获取唯一的防膨胀的随机字符串
while
(
true
){
while
(
true
)
{
auto
str
=
obtain_l
();
if
(
_obtained
.
find
(
str
)
==
_obtained
.
end
())
{
if
(
_obtained
.
find
(
str
)
==
_obtained
.
end
())
{
//没有重复
_obtained
.
emplace
(
str
);
return
str
;
}
}
}
void
RandStrGeneator
::
release
(
const
string
&
str
){
void
RandStrGeneator
::
release
(
const
string
&
str
)
{
//从防膨胀库中移除
_obtained
.
erase
(
str
);
}
string
RandStrGeneator
::
obtain_l
(){
//12个伪随机字节 + 4个递增的整形字节,然后md5即为随机字符串
auto
str
=
makeRandStr
(
12
,
false
);
string
RandStrGeneator
::
obtain_l
()
{
//
12个伪随机字节 + 4个递增的整形字节,然后md5即为随机字符串
auto
str
=
makeRandStr
(
12
,
false
);
str
.
append
((
char
*
)
&
_index
,
sizeof
(
_index
));
++
_index
;
return
MD5
(
str
).
hexdigest
();
}
}
//
namespace
mediakit
\ No newline at end of file
}
//
namespace
mediakit
\ No newline at end of file
src/Http/HttpCookieManager.h
查看文件 @
36f24527
...
...
@@ -11,13 +11,13 @@
#ifndef SRC_HTTP_COOKIEMANAGER_H
#define SRC_HTTP_COOKIEMANAGER_H
#include <memory>
#include <unordered_map>
#include "Common/Parser.h"
#include "Network/Socket.h"
#include "Util/TimeTicker.h"
#include "Util/mini.h"
#include "Util/util.h"
#include "Util/TimeTicker.h"
#include "Network/Socket.h"
#include "Common/Parser.h"
#include <memory>
#include <unordered_map>
#define COOKIE_DEFAULT_LIFE (7 * 24 * 60 * 60)
...
...
@@ -28,9 +28,9 @@ class HttpCookieManager;
/**
* cookie对象,用于保存cookie的一些相关属性
*/
class
HttpServerCookie
:
public
toolkit
::
AnyStorage
,
public
toolkit
::
noncopyable
{
class
HttpServerCookie
:
public
toolkit
::
noncopyable
{
public
:
typedef
std
::
shared_ptr
<
HttpServerCookie
>
Ptr
;
using
Ptr
=
std
::
shared_ptr
<
HttpServerCookie
>
;
/**
* 构建cookie
* @param manager cookie管理者对象
...
...
@@ -40,12 +40,10 @@ public:
* @param max_elapsed 最大过期时间,单位秒
*/
HttpServerCookie
(
const
std
::
shared_ptr
<
HttpCookieManager
>
&
manager
,
const
std
::
string
&
cookie_name
,
const
std
::
string
&
uid
,
const
std
::
string
&
cookie
,
uint64_t
max_elapsed
);
~
HttpServerCookie
()
;
HttpServerCookie
(
const
std
::
shared_ptr
<
HttpCookieManager
>
&
manager
,
const
std
::
string
&
cookie_name
,
const
std
::
string
&
uid
,
const
std
::
string
&
cookie
,
uint64_t
max_elapsed
);
~
HttpServerCookie
();
/**
* 获取uid
...
...
@@ -65,13 +63,13 @@ public:
* 获取cookie随机字符串
* @return cookie随机字符串
*/
const
std
::
string
&
getCookie
()
const
;
const
std
::
string
&
getCookie
()
const
;
/**
* 获取该cookie名
* @return
*/
const
std
::
string
&
getCookieName
()
const
;
const
std
::
string
&
getCookieName
()
const
;
/**
* 更新该cookie的过期时间,可以让此cookie不失效
...
...
@@ -85,26 +83,35 @@ public:
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
:
std
::
string
cookieExpireTime
()
const
;
std
::
string
cookieExpireTime
()
const
;
private
:
std
::
string
_uid
;
std
::
string
_cookie_name
;
std
::
string
_cookie_uuid
;
uint64_t
_max_elapsed
;
toolkit
::
Ticker
_ticker
;
std
::
recursive_mutex
_mtx
;
std
::
shared_ptr
<
void
>
_attach
;
std
::
weak_ptr
<
HttpCookieManager
>
_manager
;
};
/**
* cookie随机字符串生成器
*/
class
RandStrGeneator
{
class
RandStrGeneator
{
public
:
RandStrGeneator
()
=
default
;
~
RandStrGeneator
()
=
default
;
...
...
@@ -120,8 +127,10 @@ public:
* @param str 随机字符串
*/
void
release
(
const
std
::
string
&
str
);
private
:
std
::
string
obtain_l
();
private
:
//碰撞库
std
::
unordered_set
<
std
::
string
>
_obtained
;
...
...
@@ -135,8 +144,8 @@ private:
*/
class
HttpCookieManager
:
public
std
::
enable_shared_from_this
<
HttpCookieManager
>
{
public
:
typedef
std
::
shared_ptr
<
HttpCookieManager
>
Ptr
;
friend
class
HttpServerCookie
;
using
Ptr
=
std
::
shared_ptr
<
HttpCookieManager
>
;
~
HttpCookieManager
();
/**
...
...
@@ -152,7 +161,10 @@ public:
* @param max_elapsed 该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对象
...
...
@@ -160,7 +172,7 @@ public:
* @param cookie cookie随机字符串
* @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对象
...
...
@@ -168,7 +180,7 @@ public:
* @param http_header http头
* @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
...
...
@@ -176,7 +188,7 @@ public:
* @param uid 用户id
* @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,用户登出时使用
...
...
@@ -184,8 +196,10 @@ public:
* @return
*/
bool
delCookie
(
const
HttpServerCookie
::
Ptr
&
cookie
);
private
:
HttpCookieManager
();
void
onManager
();
/**
* 构造cookie对象时触发,目的是记录某账号下多个cookie
...
...
@@ -193,7 +207,7 @@ private:
* @param uid 用户id
* @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对象时触发
...
...
@@ -201,7 +215,7 @@ private:
* @param uid 用户id
* @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,目的是实现某用户下最多登录若干个设备
...
...
@@ -210,7 +224,7 @@ private:
* @param max_client 最多登录的设备个数
* @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
...
...
@@ -218,16 +232,21 @@ private:
* @param cookie cookie随机字符串
* @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
:
std
::
unordered_map
<
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
::
unordered_map
<
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
;
toolkit
::
Timer
::
Ptr
_timer
;
RandStrGeneator
_geneator
;
};
}
//namespace mediakit
}
// namespace mediakit
#endif //SRC_HTTP_COOKIEMANAGER_H
#endif //
SRC_HTTP_COOKIEMANAGER_H
src/Http/HttpFileManager.cpp
查看文件 @
36f24527
...
...
@@ -34,9 +34,6 @@ static const string kHlsSuffix = "/hls.m3u8";
class
HttpCookieAttachment
{
public
:
HttpCookieAttachment
()
{};
~
HttpCookieAttachment
()
{};
public
:
//cookie生效作用域,本cookie只对该目录下的文件生效
string
_path
;
//上次鉴权失败信息,为空则上次鉴权成功
...
...
@@ -265,13 +262,12 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
if
(
cookie
)
{
//找到了cookie,对cookie上锁先
auto
lck
=
cookie
->
getLock
();
auto
attachment
=
(
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
();
if
(
path
.
find
(
attachment
.
_path
)
==
0
)
{
auto
&
attach
=
cookie
->
getAttach
<
HttpCookieAttachment
>
();
if
(
path
.
find
(
attach
.
_path
)
==
0
)
{
//上次cookie是限定本目录
if
(
attach
ment
.
_err_msg
.
empty
())
{
if
(
attach
.
_err_msg
.
empty
())
{
//上次鉴权成功
if
(
attach
ment
.
_is_hls
)
{
if
(
attach
.
_is_hls
)
{
//如果播放的是hls,那么刷新hls的cookie(获取ts文件也会刷新)
cookie
->
updateTime
();
cookie_from_header
=
false
;
...
...
@@ -282,7 +278,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
//上次鉴权失败,但是如果url参数发生变更,那么也重新鉴权下
if
(
parser
.
Params
().
empty
()
||
parser
.
Params
()
==
cookie
->
getUid
())
{
//url参数未变,或者本来就没有url参数,那么判断本次请求为重复请求,无访问权限
callback
(
attach
ment
.
_err_msg
,
cookie_from_header
?
nullptr
:
cookie
);
callback
(
attach
.
_err_msg
,
cookie_from_header
?
nullptr
:
cookie
);
return
;
}
}
...
...
@@ -301,9 +297,9 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
HttpSession
::
HttpAccessPathInvoker
accessPathInvoker
=
[
callback
,
uid
,
path
,
is_dir
,
is_hls
,
mediaInfo
,
info
]
(
const
string
&
err
Msg
,
const
string
&
cookie_path_in
,
int
cookieLifeS
econd
)
{
(
const
string
&
err
_msg
,
const
string
&
cookie_path_in
,
int
life_s
econd
)
{
HttpServerCookie
::
Ptr
cookie
;
if
(
cookieLifeS
econd
)
{
if
(
life_s
econd
)
{
//本次鉴权设置了有效期,我们把鉴权结果缓存在cookie中
string
cookie_path
=
cookie_path_in
;
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
=
HttpCookieManager
::
Instance
().
addCookie
(
kCookieName
,
uid
,
cookieLifeSecond
);
//对cookie上锁
auto
lck
=
cookie
->
getLock
();
HttpCookieAttachment
attachment
;
auto
attach
=
std
::
make_shared
<
HttpCookieAttachment
>
();
//记录用户能访问的路径
attach
ment
.
_path
=
cookie_path
;
attach
->
_path
=
cookie_path
;
//记录能否访问
attach
ment
.
_err_msg
=
errM
sg
;
attach
->
_err_msg
=
err_m
sg
;
//记录访问的是否为hls
attach
ment
.
_is_hls
=
is_hls
;
attach
->
_is_hls
=
is_hls
;
if
(
is_hls
)
{
//hls相关信息
attach
ment
.
_hls_data
=
std
::
make_shared
<
HlsCookieData
>
(
mediaInfo
,
info
);
//hls未查找MediaSource
attach
ment
.
_have_find_media_source
=
false
;
//
hls相关信息
attach
->
_hls_data
=
std
::
make_shared
<
HlsCookieData
>
(
mediaInfo
,
info
);
//
hls未查找MediaSource
attach
->
_have_find_media_source
=
false
;
}
(
*
cookie
)[
kCookieName
].
set
<
HttpCookieAttachment
>
(
std
::
move
(
attachment
));
callback
(
errMsg
,
cookie
);
callback
(
err_msg
,
HttpCookieManager
::
Instance
().
addCookie
(
kCookieName
,
uid
,
life_second
,
attach
));
}
else
{
callback
(
err
M
sg
,
nullptr
);
callback
(
err
_m
sg
,
nullptr
);
}
};
...
...
@@ -401,8 +393,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
//文件鉴权失败
StrCaseMap
headerOut
;
if
(
cookie
)
{
auto
lck
=
cookie
->
getLock
();
headerOut
[
"Set-Cookie"
]
=
cookie
->
getCookie
((
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
().
_path
);
headerOut
[
"Set-Cookie"
]
=
cookie
->
getAttach
<
HttpCookieAttachment
>
().
_path
;
}
cb
(
401
,
"text/html"
,
headerOut
,
std
::
make_shared
<
HttpStringBody
>
(
errMsg
));
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
)
{
StrCaseMap
httpHeader
;
if
(
cookie
)
{
auto
lck
=
cookie
->
getLock
();
httpHeader
[
"Set-Cookie"
]
=
cookie
->
getCookie
((
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
().
_path
);
httpHeader
[
"Set-Cookie"
]
=
cookie
->
getAttach
<
HttpCookieAttachment
>
().
_path
;
}
HttpSession
::
HttpResponseInvoker
invoker
=
[
&
](
int
code
,
const
StrCaseMap
&
headerOut
,
const
HttpBody
::
Ptr
&
body
)
{
if
(
cookie
&&
file_exist
)
{
auto
lck
=
cookie
->
getLock
();
auto
is_hls
=
(
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
().
_is_hls
;
if
(
is_hls
)
{
(
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
().
_hls_data
->
addByteUsage
(
body
->
remainSize
());
auto
&
attach
=
cookie
->
getAttach
<
HttpCookieAttachment
>
();
if
(
attach
.
_is_hls
)
{
attach
.
_hls_data
->
addByteUsage
(
body
->
remainSize
());
}
}
cb
(
code
,
HttpFileManager
::
getContentType
(
strFile
.
data
()),
headerOut
,
body
);
...
...
@@ -436,10 +425,10 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
//是hls直播,判断HLS直播流是否已经注册
bool
have_find_media_src
=
false
;
if
(
cookie
)
{
auto
lck
=
cookie
->
getLock
();
have_find_media_src
=
(
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
()
.
_have_find_media_source
;
auto
&
attach
=
cookie
->
getAttach
<
HttpCookieAttachment
>
();
have_find_media_src
=
attach
.
_have_find_media_source
;
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
)
{
...
...
@@ -450,9 +439,8 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
//hls文件不存在,我们等待其生成并延后回复
MediaSource
::
findAsync
(
mediaInfo
,
strongSession
,
[
response_file
,
cookie
,
cb
,
strFile
,
parser
](
const
MediaSource
::
Ptr
&
src
)
{
if
(
cookie
)
{
auto
lck
=
cookie
->
getLock
();
//尝试添加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
()))
{
//流和m3u8文件都存在,那么直接返回文件
...
...
@@ -531,7 +519,7 @@ void HttpFileManager::onAccessPath(TcpSession &sender, Parser &parser, const Htt
}
StrCaseMap
headerOut
;
if
(
cookie
)
{
headerOut
[
"Set-Cookie"
]
=
cookie
->
get
Cookie
((
*
cookie
)[
kCookieName
].
get
<
HttpCookieAttachment
>
().
_path
)
;
headerOut
[
"Set-Cookie"
]
=
cookie
->
get
Attach
<
HttpCookieAttachment
>
().
_path
;
}
cb
(
errMsg
.
empty
()
?
200
:
401
,
"text/html"
,
headerOut
,
std
::
make_shared
<
HttpStringBody
>
(
strMenu
));
});
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论