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
3 years ago
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
http cookie减少互斥锁,优化性能
parent
c510f376
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
81 行增加
和
74 行删除
+81
-74
src/Http/HttpCookieManager.cpp
+0
-0
src/Http/HttpCookieManager.h
+54
-35
src/Http/HttpFileManager.cpp
+27
-39
没有找到文件。
src/Http/HttpCookieManager.cpp
查看文件 @
36f24527
差异被折叠。
点击展开。
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
This diff is collapsed.
Click to expand it.
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
));
});
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论