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
42fe7e3d
Commit
42fe7e3d
authored
Jun 13, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
服务器cookie不再强制关联path
parent
23d793c9
全部展开
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
61 行增加
和
55 行删除
+61
-55
src/Http/HttpCookieManager.cpp
+0
-0
src/Http/HttpCookieManager.h
+48
-42
src/Http/HttpSession.cpp
+11
-11
src/Http/HttpSession.h
+2
-2
没有找到文件。
src/Http/CookieManager.cpp
→
src/Http/
Http
CookieManager.cpp
查看文件 @
42fe7e3d
差异被折叠。
点击展开。
src/Http/CookieManager.h
→
src/Http/
Http
CookieManager.h
查看文件 @
42fe7e3d
...
...
@@ -40,25 +40,31 @@ using namespace mediakit;
#define COOKIE_DEFAULT_LIFE (7 * 24 * 60 * 60)
class
CookieManager
;
namespace
mediakit
{
class
HttpCookieManager
;
/**
* cookie对象,用于保存cookie的一些相关属性
*/
class
CookieData
:
public
mINI
,
public
noncopyable
{
class
HttpServerCookie
:
public
mINI
,
public
noncopyable
{
public
:
typedef
std
::
shared_ptr
<
CookieData
>
Ptr
;
typedef
std
::
shared_ptr
<
HttpServerCookie
>
Ptr
;
/**
* 构建cookie
* @param manager cookie管理者对象
* @param cookie
cookie随机字符串
* @param cookie
_name cookie名,例如MY_SESSION
* @param uid 用户唯一id
* @param cookie cookie随机字符串
* @param max_elapsed 最大过期时间,单位秒
* @param path http路径,譬如/index/files/
*/
CookieData
(
const
std
::
shared_ptr
<
CookieManager
>
&
manager
,
const
string
&
cookie
,
const
string
&
uid
,
uint64_t
max_elapsed
,
const
string
&
path
);
~
CookieData
()
;
HttpServerCookie
(
const
std
::
shared_ptr
<
HttpCookieManager
>
&
manager
,
const
string
&
cookie_name
,
const
string
&
uid
,
const
string
&
cookie
,
uint64_t
max_elapsed
);
~
HttpServerCookie
()
;
/**
* 获取uid
...
...
@@ -69,9 +75,10 @@ public:
/**
* 获取http中Set-Cookie字段的值
* @param cookie_name 该cookie的名称,譬如 MY_SESSION
* @param path http访问路径
* @return 例如 MY_SESSION=XXXXXX;expires=Wed, Jun 12 2019 06:30:48 GMT;path=/index/files/
*/
string
getCookie
(
const
string
&
cookie_name
)
const
;
string
getCookie
(
const
string
&
path
)
const
;
/**
* 获取cookie随机字符串
...
...
@@ -80,10 +87,10 @@ public:
const
string
&
getCookie
()
const
;
/**
* 获取该cookie
对应的path
* 获取该cookie
名
* @return
*/
const
string
&
get
Path
()
const
;
const
string
&
get
CookieName
()
const
;
/**
* 更新该cookie的过期时间,可以让此cookie不失效
...
...
@@ -99,20 +106,20 @@ private:
string
cookieExpireTime
()
const
;
private
:
string
_uid
;
string
_
path
;
string
_
cookie_name
;
string
_cookie_uuid
;
uint64_t
_max_elapsed
;
Ticker
_ticker
;
std
::
weak_ptr
<
CookieManager
>
_manager
;
std
::
weak_ptr
<
Http
CookieManager
>
_manager
;
};
/**
* cookie随机字符串生成器
*/
class
Cookie
Geneator
{
class
RandStr
Geneator
{
public
:
Cookie
Geneator
()
=
default
;
~
Cookie
Geneator
()
=
default
;
RandStr
Geneator
()
=
default
;
~
RandStr
Geneator
()
=
default
;
/**
* 获取不碰撞的随机字符串
...
...
@@ -138,95 +145,94 @@ private:
* cookie管理器,用于管理cookie的生成以及过期管理,同时实现了同账号异地挤占登录功能
* 该对象实现了同账号最多登录若干个设备
*/
class
CookieManager
:
public
std
::
enable_shared_from_this
<
CookieManager
>
{
class
HttpCookieManager
:
public
std
::
enable_shared_from_this
<
Http
CookieManager
>
{
public
:
typedef
std
::
shared_ptr
<
CookieManager
>
Ptr
;
friend
class
CookieData
;
~
CookieManager
();
typedef
std
::
shared_ptr
<
Http
CookieManager
>
Ptr
;
friend
class
HttpServerCookie
;
~
Http
CookieManager
();
/**
* 获取单例
*/
static
CookieManager
&
Instance
();
static
Http
CookieManager
&
Instance
();
/**
* 添加cookie
* @param cookie_name cookie名,例如MY_SESSION
* @param uid 用户id,如果为空则为匿名登录
* @param max_client 该账号最多登录多少个设备
* @param max_elapsed 该cookie过期时间,单位秒
* @param path 该cookie对应的http路径
* @return cookie对象
*/
CookieData
::
Ptr
addCookie
(
const
string
&
uid
,
int
max_client
,
uint64_t
max_elapsed
=
COOKIE_DEFAULT_LIFE
,
const
string
&
path
=
"/"
);
HttpServerCookie
::
Ptr
addCookie
(
const
string
&
cookie_name
,
const
string
&
uid
,
uint64_t
max_elapsed
=
COOKIE_DEFAULT_LIFE
,
int
max_client
=
1
);
/**
* 根据cookie随机字符串查找cookie对象
* @param cookie_name cookie名,例如MY_SESSION
* @param cookie cookie随机字符串
* @param path 该cookie对应的http路径
* @return cookie对象,可以为nullptr
*/
CookieData
::
Ptr
getCookie
(
const
string
&
cookie
,
const
string
&
path
=
"/"
);
HttpServerCookie
::
Ptr
getCookie
(
const
string
&
cookie_name
,
const
string
&
cookie
);
/**
* 从http头中获取cookie对象
* @param cookie_name cookie名,例如MY_SESSION
* @param http_header http头
* @param cookie_name cookie名
* @param path http路径
* @return cookie对象
*/
CookieData
::
Ptr
getCookie
(
const
StrCaseMap
&
http_header
,
const
string
&
cookie_name
,
const
string
&
path
=
"/"
);
HttpServerCookie
::
Ptr
getCookie
(
const
string
&
cookie_name
,
const
StrCaseMap
&
http_header
);
/**
* 删除cookie,用户登出时使用
* @param cookie cookie对象,可以为nullptr
* @return
*/
bool
delCookie
(
const
CookieData
::
Ptr
&
cookie
);
bool
delCookie
(
const
HttpServerCookie
::
Ptr
&
cookie
);
/**
* 获取某用户名下最先登录时的cookie,目的是实现某用户下最多登录若干个设备
* @param
path http路径
* @param
cookie_name cookie名,例如MY_SESSION
* @param uid 用户id
* @param max_client 最多登录的设备个数
* @return 最早的cookie随机字符串
*/
string
getOldestCookie
(
const
string
&
uid
,
int
max_client
,
const
string
&
path
=
"/"
);
string
getOldestCookie
(
const
string
&
cookie_name
,
const
string
&
uid
,
int
max_client
=
1
);
private
:
CookieManager
();
Http
CookieManager
();
void
onManager
();
/**
* 构造cookie对象时触发,目的是记录某账号下多个cookie
* @param
path http路径
* @param
cookie_name cookie名,例如MY_SESSION
* @param uid 用户id
* @param cookie cookie随机字符串
*/
void
onAddCookie
(
const
string
&
path
,
const
string
&
uid
,
const
string
&
cookie
);
void
onAddCookie
(
const
string
&
cookie_name
,
const
string
&
uid
,
const
string
&
cookie
);
/**
* 析构cookie对象时触发
* @param
path http路径
* @param
cookie_name cookie名,例如MY_SESSION
* @param uid 用户id
* @param cookie cookie随机字符串
*/
void
onDelCookie
(
const
string
&
path
,
const
string
&
uid
,
const
string
&
cookie
);
void
onDelCookie
(
const
string
&
cookie_name
,
const
string
&
uid
,
const
string
&
cookie
);
/**
* 删除cookie
* @param
path http路径
* @param
cookie_name cookie名,例如MY_SESSION
* @param cookie cookie随机字符串
* @return 成功true
*/
bool
delCookie
(
const
string
&
path
,
const
string
&
cookie
);
bool
delCookie
(
const
string
&
cookie_name
,
const
string
&
cookie
);
private
:
unordered_map
<
string
/*
path*/
,
unordered_map
<
string
/*cookie*/
,
CookieData
::
Ptr
/*cookie_data*/
>
>
_map_cookie
;
unordered_map
<
string
/*
path
*/
,
unordered_map
<
string
/*uid*/
,
map
<
uint64_t
/*cookie time stamp*/
,
string
/*cookie*/
>
>
>
_map_uid_to_cookie
;
unordered_map
<
string
/*
cookie_name*/
,
unordered_map
<
string
/*cookie*/
,
HttpServerCookie
::
Ptr
/*cookie_data*/
>
>
_map_cookie
;
unordered_map
<
string
/*
cookie_name
*/
,
unordered_map
<
string
/*uid*/
,
map
<
uint64_t
/*cookie time stamp*/
,
string
/*cookie*/
>
>
>
_map_uid_to_cookie
;
recursive_mutex
_mtx_cookie
;
Timer
::
Ptr
_timer
;
Cookie
Geneator
_geneator
;
RandStr
Geneator
_geneator
;
};
}
//namespace mediakit
#endif //SRC_HTTP_COOKIEMANAGER_H
src/Http/HttpSession.cpp
查看文件 @
42fe7e3d
...
...
@@ -51,7 +51,6 @@ namespace mediakit {
static
int
kSockFlags
=
SOCKET_DEFAULE_FLAGS
|
FLAG_MORE
;
static
const
string
kCookieName
=
"ZL_COOKIE"
;
static
const
string
kAccessPathKey
=
"kAccessPathKey"
;
static
int
kMaxClientPerUid
=
1
;
static
const
string
kAccessDirUnauthorized
=
"你没有权限访问该目录"
;
static
const
string
kAccessFileUnauthorized
=
"你没有权限访问该文件"
;
...
...
@@ -331,7 +330,7 @@ inline string HttpSession::getClientUid(){
NoticeCenter
::
Instance
().
emitEventNoCopy
(
Broadcast
::
kBroadcastTrackHttpClient
,
_parser
,
uid
,
*
this
);
return
uid
;
}
inline
void
HttpSession
::
canAccessPath
(
const
string
&
path_in
,
bool
is_dir
,
const
function
<
void
(
bool
canAccess
,
const
CookieData
::
Ptr
&
cookie
)
>
&
callback_in
){
inline
void
HttpSession
::
canAccessPath
(
const
string
&
path_in
,
bool
is_dir
,
const
function
<
void
(
bool
canAccess
,
const
HttpServerCookie
::
Ptr
&
cookie
)
>
&
callback_in
){
if
(
NoticeCenter
::
Instance
().
listenerSize
(
Broadcast
::
kBroadcastHttpAccess
)
==
0
){
//该事件无人监听,那么就不做cookie查找这样费时的操作
callback_in
(
true
,
nullptr
);
...
...
@@ -340,7 +339,7 @@ inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const f
auto
path
=
path_in
;
replace
(
const_cast
<
string
&>
(
path
),
"//"
,
"/"
);
auto
callback
=
[
callback_in
,
this
](
bool
canAccess
,
const
CookieData
::
Ptr
&
cookie
){
auto
callback
=
[
callback_in
,
this
](
bool
canAccess
,
const
HttpServerCookie
::
Ptr
&
cookie
){
try
{
callback_in
(
canAccess
,
cookie
);
}
catch
(
SockException
&
ex
){
...
...
@@ -353,7 +352,7 @@ inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const f
};
//根据http头中的cookie字段获取cookie
auto
cookie
=
CookieManager
::
Instance
().
getCookie
(
_parser
.
getValues
(),
kCookieName
);
auto
cookie
=
HttpCookieManager
::
Instance
().
getCookie
(
kCookieName
,
_parser
.
getValues
()
);
if
(
cookie
)
{
//判断该用户是否有权限访问该目录,并且不再设置客户端cookie
callback
(
!
(
*
cookie
)[
kAccessPathKey
].
empty
()
&&
path
.
find
((
*
cookie
)[
kAccessPathKey
])
==
0
,
nullptr
);
...
...
@@ -362,10 +361,10 @@ inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const f
//根据该用户的用户名获取cookie
string
uid
=
getClientUid
();
auto
cookie_str
=
CookieManager
::
Instance
().
getOldestCookie
(
uid
,
kMaxClientPerU
id
);
auto
cookie_str
=
HttpCookieManager
::
Instance
().
getOldestCookie
(
kCookieName
,
u
id
);
if
(
!
cookie_str
.
empty
()){
//该用户已经登录过了,但是它(http客户端)貌似不支持cookie,所以我们只能通过它的用户名获取cookie
cookie
=
CookieManager
::
Instance
().
getCookie
(
cookie_str
);
cookie
=
HttpCookieManager
::
Instance
().
getCookie
(
kCookieName
,
cookie_str
);
if
(
cookie
)
{
//判断该用户是否有权限访问该目录,并且不再设置客户端cookie
callback
(
!
(
*
cookie
)[
kAccessPathKey
].
empty
()
&&
path
.
find
((
*
cookie
)[
kAccessPathKey
])
==
0
,
nullptr
);
...
...
@@ -390,12 +389,13 @@ inline void HttpSession::canAccessPath(const string &path_in,bool is_dir,const f
}
if
(
cookieLifeSecond
){
//我们给用户生成追踪cookie
auto
cookie
=
CookieManager
::
Instance
().
addCookie
(
uid
,
kMaxClientPerUid
,
cookieLifeSecond
);
auto
cookie
=
HttpCookieManager
::
Instance
().
addCookie
(
kCookieName
,
uid
,
cookieLifeSecond
);
//记录用户能访问的路径
(
*
cookie
)[
kAccessPathKey
]
=
accessPath
;
//判断该用户是否有权限访问该目录,并且设置客户端cookie
callback
(
!
accessPath
.
empty
()
&&
path
.
find
(
accessPath
)
==
0
,
cookie
);
}
else
{
//仅限本次访问文件
callback
(
!
accessPath
.
empty
()
&&
path
.
find
(
accessPath
)
==
0
,
nullptr
);
}
});
...
...
@@ -462,13 +462,13 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
}
//判断是否有权限访问该目录
canAccessPath
(
_parser
.
Url
(),
true
,[
this
,
bClose
,
strFile
,
strMeun
](
bool
canAccess
,
const
CookieData
::
Ptr
&
cookie
){
canAccessPath
(
_parser
.
Url
(),
true
,[
this
,
bClose
,
strFile
,
strMeun
](
bool
canAccess
,
const
HttpServerCookie
::
Ptr
&
cookie
){
if
(
!
canAccess
){
const_cast
<
string
&>
(
strMeun
)
=
kAccessDirUnauthorized
;
}
auto
headerOut
=
makeHttpHeader
(
bClose
,
strMeun
.
size
());
if
(
cookie
){
headerOut
[
"Set-Cookie"
]
=
cookie
->
getCookie
(
kCookieName
);
headerOut
[
"Set-Cookie"
]
=
cookie
->
getCookie
(
(
*
cookie
)[
kAccessPathKey
]
);
}
sendResponse
(
canAccess
?
"200 OK"
:
"401 Unauthorized"
,
headerOut
,
strMeun
);
throw
SockException
(
bClose
?
Err_shutdown
:
Err_success
,
"close connection after access folder"
);
...
...
@@ -499,7 +499,7 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
auto
parser
=
_parser
;
//判断是否有权限访问该文件
canAccessPath
(
_parser
.
Url
(),
false
,[
this
,
parser
,
tFileStat
,
pFilePtr
,
bClose
,
strFile
](
bool
canAccess
,
const
CookieData
::
Ptr
&
cookie
){
canAccessPath
(
_parser
.
Url
(),
false
,[
this
,
parser
,
tFileStat
,
pFilePtr
,
bClose
,
strFile
](
bool
canAccess
,
const
HttpServerCookie
::
Ptr
&
cookie
){
//判断是不是分节下载
auto
&
strRange
=
parser
[
"Range"
];
int64_t
iRangeStart
=
0
,
iRangeEnd
=
0
;
...
...
@@ -530,7 +530,7 @@ inline void HttpSession::Handle_Req_GET(int64_t &content_len) {
}
if
(
cookie
){
httpHeader
[
"Set-Cookie"
]
=
cookie
->
getCookie
(
kCookieName
);
httpHeader
[
"Set-Cookie"
]
=
cookie
->
getCookie
(
(
*
cookie
)[
kAccessPathKey
]
);
}
//先回复HTTP头部分
sendResponse
(
canAccess
?
pcHttpResult
:
"401 Unauthorized"
,
httpHeader
,
canAccess
?
""
:
kAccessFileUnauthorized
);
...
...
src/Http/HttpSession.h
查看文件 @
42fe7e3d
...
...
@@ -35,7 +35,7 @@
#include "RtmpMuxer/FlvMuxer.h"
#include "HttpRequestSplitter.h"
#include "WebSocketSplitter.h"
#include "CookieManager.h"
#include "
Http
CookieManager.h"
using
namespace
std
;
using
namespace
toolkit
;
...
...
@@ -119,7 +119,7 @@ private:
* @param is_dir path是否为目录
* @param callback 有权限或无权限的回调
*/
inline
void
canAccessPath
(
const
string
&
path
,
bool
is_dir
,
const
function
<
void
(
bool
canAccess
,
const
CookieData
::
Ptr
&
cookie
)
>
&
callback
);
inline
void
canAccessPath
(
const
string
&
path
,
bool
is_dir
,
const
function
<
void
(
bool
canAccess
,
const
HttpServerCookie
::
Ptr
&
cookie
)
>
&
callback
);
//获取用户唯一识别id,我们默认为ip+端口号
inline
string
getClientUid
();
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论