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
9443d68d
Commit
9443d68d
authored
Apr 18, 2023
by
xia-chu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
格式化代码
parent
f949c6de
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
165 行增加
和
175 行删除
+165
-175
server/WebHook.cpp
+165
-175
没有找到文件。
server/WebHook.cpp
查看文件 @
9443d68d
...
...
@@ -14,10 +14,10 @@
#include "Util/NoticeCenter.h"
#include "Common/config.h"
#include "Common/MediaSource.h"
#include "Http/HttpSession.h"
#include "Http/HttpRequester.h"
#include "Network/Session.h"
#include "Rtsp/RtspSession.h"
#include "Http/HttpSession.h"
#include "WebHook.h"
#include "WebApi.h"
...
...
@@ -29,33 +29,33 @@ using namespace mediakit;
namespace
Hook
{
#define HOOK_FIELD "hook."
const
string
kEnable
=
HOOK_FIELD
"enable"
;
const
string
kTimeoutSec
=
HOOK_FIELD
"timeoutSec"
;
const
string
kOnPublish
=
HOOK_FIELD
"on_publish"
;
const
string
kOnPlay
=
HOOK_FIELD
"on_play"
;
const
string
kOnFlowReport
=
HOOK_FIELD
"on_flow_report"
;
const
string
kOnRtspRealm
=
HOOK_FIELD
"on_rtsp_realm"
;
const
string
kOnRtspAuth
=
HOOK_FIELD
"on_rtsp_auth"
;
const
string
kOnStreamChanged
=
HOOK_FIELD
"on_stream_changed"
;
const
string
kOnStreamNotFound
=
HOOK_FIELD
"on_stream_not_found"
;
const
string
kOnRecordMp4
=
HOOK_FIELD
"on_record_mp4"
;
const
string
kOnRecordTs
=
HOOK_FIELD
"on_record_ts"
;
const
string
kOnShellLogin
=
HOOK_FIELD
"on_shell_login"
;
const
string
kOnStreamNoneReader
=
HOOK_FIELD
"on_stream_none_reader"
;
const
string
kOnHttpAccess
=
HOOK_FIELD
"on_http_access"
;
const
string
kOnServerStarted
=
HOOK_FIELD
"on_server_started"
;
const
string
kOnServerKeepalive
=
HOOK_FIELD
"on_server_keepalive"
;
const
string
kOnSendRtpStopped
=
HOOK_FIELD
"on_send_rtp_stopped"
;
const
string
kOnRtpServerTimeout
=
HOOK_FIELD
"on_rtp_server_timeout"
;
const
string
kAdminParams
=
HOOK_FIELD
"admin_params"
;
const
string
kAliveInterval
=
HOOK_FIELD
"alive_interval"
;
const
string
kRetry
=
HOOK_FIELD
"retry"
;
const
string
kRetryDelay
=
HOOK_FIELD
"retry_delay"
;
onceToken
token
([]()
{
const
string
kEnable
=
HOOK_FIELD
"enable"
;
const
string
kTimeoutSec
=
HOOK_FIELD
"timeoutSec"
;
const
string
kOnPublish
=
HOOK_FIELD
"on_publish"
;
const
string
kOnPlay
=
HOOK_FIELD
"on_play"
;
const
string
kOnFlowReport
=
HOOK_FIELD
"on_flow_report"
;
const
string
kOnRtspRealm
=
HOOK_FIELD
"on_rtsp_realm"
;
const
string
kOnRtspAuth
=
HOOK_FIELD
"on_rtsp_auth"
;
const
string
kOnStreamChanged
=
HOOK_FIELD
"on_stream_changed"
;
const
string
kOnStreamNotFound
=
HOOK_FIELD
"on_stream_not_found"
;
const
string
kOnRecordMp4
=
HOOK_FIELD
"on_record_mp4"
;
const
string
kOnRecordTs
=
HOOK_FIELD
"on_record_ts"
;
const
string
kOnShellLogin
=
HOOK_FIELD
"on_shell_login"
;
const
string
kOnStreamNoneReader
=
HOOK_FIELD
"on_stream_none_reader"
;
const
string
kOnHttpAccess
=
HOOK_FIELD
"on_http_access"
;
const
string
kOnServerStarted
=
HOOK_FIELD
"on_server_started"
;
const
string
kOnServerKeepalive
=
HOOK_FIELD
"on_server_keepalive"
;
const
string
kOnSendRtpStopped
=
HOOK_FIELD
"on_send_rtp_stopped"
;
const
string
kOnRtpServerTimeout
=
HOOK_FIELD
"on_rtp_server_timeout"
;
const
string
kAdminParams
=
HOOK_FIELD
"admin_params"
;
const
string
kAliveInterval
=
HOOK_FIELD
"alive_interval"
;
const
string
kRetry
=
HOOK_FIELD
"retry"
;
const
string
kRetryDelay
=
HOOK_FIELD
"retry_delay"
;
static
onceToken
token
([]()
{
mINI
::
Instance
()[
kEnable
]
=
false
;
mINI
::
Instance
()[
kTimeoutSec
]
=
10
;
//默认hook地址设置为空,采用默认行为(例如不鉴权)
//
默认hook地址设置为空,采用默认行为(例如不鉴权)
mINI
::
Instance
()[
kOnPublish
]
=
""
;
mINI
::
Instance
()[
kOnPlay
]
=
""
;
mINI
::
Instance
()[
kOnFlowReport
]
=
""
;
...
...
@@ -76,8 +76,8 @@ onceToken token([](){
mINI
::
Instance
()[
kAliveInterval
]
=
30.0
;
mINI
::
Instance
()[
kRetry
]
=
1
;
mINI
::
Instance
()[
kRetryDelay
]
=
3.0
;
}
,
nullptr
);
}
//
namespace Hook
});
}
//
namespace Hook
namespace
Cluster
{
#define CLUSTER_FIELD "cluster."
...
...
@@ -91,19 +91,18 @@ static onceToken token([]() {
mINI
::
Instance
()[
kRetryCount
]
=
3
;
});
}
//
namespace Cluster
}
//
namespace Cluster
static
void
parse_http_response
(
const
SockException
&
ex
,
const
Parser
&
res
,
const
function
<
void
(
const
Value
&
,
const
string
&
,
const
bool
&
)
>
&
fun
){
static
void
parse_http_response
(
const
SockException
&
ex
,
const
Parser
&
res
,
const
function
<
void
(
const
Value
&
,
const
string
&
,
bool
)
>
&
fun
)
{
bool
should_retry
=
true
;
if
(
ex
)
{
auto
errStr
=
StrPrinter
<<
"[network err]:"
<<
ex
.
what
()
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
return
;
}
if
(
res
.
Url
()
!=
"200"
)
{
auto
errStr
=
StrPrinter
<<
"[bad http status code]:"
<<
res
.
Url
()
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
return
;
}
Value
result
;
...
...
@@ -112,45 +111,45 @@ static void parse_http_response(const SockException &ex, const Parser &res,
ss
>>
result
;
}
catch
(
std
::
exception
&
ex
)
{
auto
errStr
=
StrPrinter
<<
"[parse json failed]:"
<<
ex
.
what
()
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
return
;
}
auto
code
=
result
[
"code"
];
if
(
!
code
.
isInt64
())
{
auto
errStr
=
StrPrinter
<<
"[json code]:"
<<
"code not int
:"
<<
code
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
auto
errStr
=
StrPrinter
<<
"[json code]:"
<<
"code not int
:"
<<
code
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
return
;
}
should_retry
=
false
;
if
(
code
.
asInt64
()
!=
0
)
{
auto
errStr
=
StrPrinter
<<
"[auth failed]: code:"
<<
code
<<
" msg:"
<<
result
[
"msg"
]
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
if
(
code
.
asInt64
()
!=
0
)
{
auto
errStr
=
StrPrinter
<<
"[auth failed]: code:"
<<
code
<<
" msg:"
<<
result
[
"msg"
]
<<
endl
;
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
return
;
}
try
{
fun
(
result
,
""
,
should_retry
);
fun
(
result
,
""
,
should_retry
);
}
catch
(
std
::
exception
&
ex
)
{
auto
errStr
=
StrPrinter
<<
"[do hook invoker failed]:"
<<
ex
.
what
()
<<
endl
;
//如果还是抛异常,那么再上抛异常
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
//
如果还是抛异常,那么再上抛异常
fun
(
Json
::
nullValue
,
errStr
,
should_retry
);
}
}
string
to_string
(
const
Value
&
value
){
string
to_string
(
const
Value
&
value
)
{
return
value
.
toStyledString
();
}
string
to_string
(
const
HttpArgs
&
value
){
string
to_string
(
const
HttpArgs
&
value
)
{
return
value
.
make
();
}
const
char
*
getContentType
(
const
Value
&
value
){
const
char
*
getContentType
(
const
Value
&
value
)
{
return
"application/json"
;
}
const
char
*
getContentType
(
const
HttpArgs
&
value
){
const
char
*
getContentType
(
const
HttpArgs
&
value
)
{
return
"application/x-www-form-urlencoded"
;
}
...
...
@@ -182,8 +181,8 @@ void do_http_hook(const string &url, const ArgsType &body, const function<void(c
}
Ticker
ticker
;
requester
->
startRequester
(
url
,
[
url
,
func
,
bodyStr
,
body
,
requester
,
ticker
,
retry
](
const
SockException
&
ex
,
const
Parser
&
res
)
mutable
{
onceToken
token
(
nullptr
,
[
&
]()
mutable
{
requester
.
reset
();
});
parse_http_response
(
ex
,
res
,
[
&
](
const
Value
&
obj
,
const
string
&
err
,
const
bool
&
should_retry
)
{
onceToken
token
(
nullptr
,
[
&
]()
mutable
{
requester
.
reset
();
});
parse_http_response
(
ex
,
res
,
[
&
](
const
Value
&
obj
,
const
string
&
err
,
bool
should_retry
)
{
if
(
!
err
.
empty
())
{
// hook失败
WarnL
<<
"hook "
<<
url
<<
" "
<<
ticker
.
elapsedTime
()
<<
"ms,failed"
<<
err
<<
":"
<<
bodyStr
;
...
...
@@ -193,12 +192,12 @@ void do_http_hook(const string &url, const ArgsType &body, const function<void(c
do_http_hook
(
url
,
body
,
func
,
retry
);
return
0
;
});
//重试不需要触发回调
//
重试不需要触发回调
return
;
}
}
else
if
(
ticker
.
elapsedTime
()
>
500
)
{
//hook成功,但是hook响应超过500ms,打印警告日志
//
hook成功,但是hook响应超过500ms,打印警告日志
DebugL
<<
"hook "
<<
url
<<
" "
<<
ticker
.
elapsedTime
()
<<
"ms,success:"
<<
bodyStr
;
}
...
...
@@ -214,7 +213,7 @@ void do_http_hook(const string &url, const ArgsType &body, const function<void(c
do_http_hook
(
url
,
body
,
func
,
hook_retry
);
}
static
ArgsType
make_json
(
const
MediaInfo
&
args
){
static
ArgsType
make_json
(
const
MediaInfo
&
args
)
{
ArgsType
body
;
body
[
"schema"
]
=
args
.
_schema
;
body
[
VHOST_KEY
]
=
args
.
_vhost
;
...
...
@@ -224,19 +223,19 @@ static ArgsType make_json(const MediaInfo &args){
return
body
;
}
static
void
reportServerStarted
(){
GET_CONFIG
(
bool
,
hook_enable
,
Hook
::
kEnable
);
GET_CONFIG
(
string
,
hook_server_started
,
Hook
::
kOnServerStarted
);
if
(
!
hook_enable
||
hook_server_started
.
empty
())
{
static
void
reportServerStarted
()
{
GET_CONFIG
(
bool
,
hook_enable
,
Hook
::
kEnable
);
GET_CONFIG
(
string
,
hook_server_started
,
Hook
::
kOnServerStarted
);
if
(
!
hook_enable
||
hook_server_started
.
empty
())
{
return
;
}
ArgsType
body
;
for
(
auto
&
pr
:
mINI
::
Instance
())
{
body
[
pr
.
first
]
=
(
string
&
)
pr
.
second
;
body
[
pr
.
first
]
=
(
string
&
)
pr
.
second
;
}
//执行hook
do_http_hook
(
hook_server_started
,
body
,
nullptr
);
//
执行hook
do_http_hook
(
hook_server_started
,
body
,
nullptr
);
}
// 服务器定时保活定时器
...
...
@@ -249,11 +248,11 @@ static void reportServerKeepalive() {
}
GET_CONFIG
(
float
,
alive_interval
,
Hook
::
kAliveInterval
);
g_keepalive_timer
=
std
::
make_shared
<
Timer
>
(
alive_interval
,
[]()
{
g_keepalive_timer
=
std
::
make_shared
<
Timer
>
(
alive_interval
,[]()
{
getStatisticJson
([](
const
Value
&
data
)
mutable
{
ArgsType
body
;
body
[
"data"
]
=
data
;
//执行hook
//
执行hook
do_http_hook
(
hook_server_keepalive
,
body
,
nullptr
);
});
return
true
;
...
...
@@ -268,13 +267,11 @@ static string getPullUrl(const string &origin_fmt, const MediaInfo &info) {
WarnL
<<
"get origin url failed, origin_fmt:"
<<
origin_fmt
;
return
""
;
}
//告知源站这是来自边沿站的拉流请求,如果未找到流请立即返回拉流失败
//
告知源站这是来自边沿站的拉流请求,如果未找到流请立即返回拉流失败
return
string
(
url
)
+
'?'
+
kEdgeServerParam
+
'&'
+
VHOST_KEY
+
'='
+
info
.
_vhost
+
'&'
+
info
.
_param_strs
;
}
static
void
pullStreamFromOrigin
(
const
vector
<
string
>&
urls
,
size_t
index
,
size_t
failed_cnt
,
const
MediaInfo
&
args
,
const
function
<
void
()
>
&
closePlayer
)
{
static
void
pullStreamFromOrigin
(
const
vector
<
string
>
&
urls
,
size_t
index
,
size_t
failed_cnt
,
const
MediaInfo
&
args
,
const
function
<
void
()
>
&
closePlayer
)
{
GET_CONFIG
(
float
,
cluster_timeout_sec
,
Cluster
::
kTimeoutSec
);
GET_CONFIG
(
int
,
retry_count
,
Cluster
::
kRetryCount
);
...
...
@@ -283,17 +280,16 @@ static void pullStreamFromOrigin(const vector<string>& urls, size_t index, size_
InfoL
<<
"pull stream from origin, failed_cnt: "
<<
failed_cnt
<<
", timeout_sec: "
<<
timeout_sec
<<
", url: "
<<
url
;
ProtocolOption
option
;
option
.
enable_hls
=
option
.
enable_hls
||
(
args
.
_schema
==
HLS_SCHEMA
);
option
.
enable_hls
=
option
.
enable_hls
||
(
args
.
_schema
==
HLS_SCHEMA
);
option
.
enable_mp4
=
false
;
addStreamProxy
(
args
.
_vhost
,
args
.
_app
,
args
.
_streamid
,
url
,
retry_count
,
option
,
Rtsp
::
RTP_TCP
,
timeout_sec
,
[
=
](
const
SockException
&
ex
,
const
string
&
key
)
mutable
{
addStreamProxy
(
args
.
_vhost
,
args
.
_app
,
args
.
_streamid
,
url
,
retry_count
,
option
,
Rtsp
::
RTP_TCP
,
timeout_sec
,
[
=
](
const
SockException
&
ex
,
const
string
&
key
)
mutable
{
if
(
!
ex
)
{
return
;
}
//拉流失败
//
拉流失败
if
(
++
failed_cnt
==
urls
.
size
())
{
//已经重试所有源站了
//
已经重试所有源站了
WarnL
<<
"pull stream from origin final failed: "
<<
url
;
closePlayer
();
return
;
...
...
@@ -319,38 +315,38 @@ static mINI jsonToMini(const Value &obj) {
return
ret
;
}
void
installWebHook
(){
GET_CONFIG
(
bool
,
hook_enable
,
Hook
::
kEnable
);
GET_CONFIG
(
string
,
hook_adminparams
,
Hook
::
kAdminParams
);
void
installWebHook
()
{
GET_CONFIG
(
bool
,
hook_enable
,
Hook
::
kEnable
);
GET_CONFIG
(
string
,
hook_adminparams
,
Hook
::
kAdminParams
);
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastMediaPublish
,
[](
BroadcastMediaPublishArgs
)
{
GET_CONFIG
(
string
,
hook_publish
,
Hook
::
kOnPublish
);
GET_CONFIG
(
string
,
hook_publish
,
Hook
::
kOnPublish
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_publish
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
invoker
(
""
,
ProtocolOption
());
return
;
}
//异步执行该hook api,防止阻塞NoticeCenter
//
异步执行该hook api,防止阻塞NoticeCenter
auto
body
=
make_json
(
args
);
body
[
"ip"
]
=
sender
.
get_peer_ip
();
body
[
"port"
]
=
sender
.
get_peer_port
();
body
[
"id"
]
=
sender
.
getIdentifier
();
body
[
"originType"
]
=
(
int
)
type
;
body
[
"originType"
]
=
(
int
)
type
;
body
[
"originTypeStr"
]
=
getOriginTypeString
(
type
);
//执行hook
//
执行hook
do_http_hook
(
hook_publish
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
mutable
{
if
(
err
.
empty
())
{
//推流鉴权成功
//
推流鉴权成功
invoker
(
err
,
ProtocolOption
(
jsonToMini
(
obj
)));
}
else
{
//推流鉴权失败
//
推流鉴权失败
invoker
(
err
,
ProtocolOption
());
}
});
});
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastMediaPlayed
,[](
BroadcastMediaPlayedArgs
)
{
GET_CONFIG
(
string
,
hook_play
,
Hook
::
kOnPlay
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_play
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastMediaPlayed
,
[](
BroadcastMediaPlayedArgs
)
{
GET_CONFIG
(
string
,
hook_play
,
Hook
::
kOnPlay
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_play
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
invoker
(
""
);
return
;
}
...
...
@@ -358,15 +354,13 @@ void installWebHook(){
body
[
"ip"
]
=
sender
.
get_peer_ip
();
body
[
"port"
]
=
sender
.
get_peer_port
();
body
[
"id"
]
=
sender
.
getIdentifier
();
//执行hook
do_http_hook
(
hook_play
,
body
,[
invoker
](
const
Value
&
obj
,
const
string
&
err
){
invoker
(
err
);
});
// 执行hook
do_http_hook
(
hook_play
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
invoker
(
err
);
});
});
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastFlowReport
,[](
BroadcastFlowReportArgs
)
{
GET_CONFIG
(
string
,
hook_flowreport
,
Hook
::
kOnFlowReport
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_flowreport
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastFlowReport
,
[](
BroadcastFlowReportArgs
)
{
GET_CONFIG
(
string
,
hook_flowreport
,
Hook
::
kOnFlowReport
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_flowreport
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
return
;
}
auto
body
=
make_json
(
args
);
...
...
@@ -376,18 +370,17 @@ void installWebHook(){
body
[
"ip"
]
=
sender
.
get_peer_ip
();
body
[
"port"
]
=
sender
.
get_peer_port
();
body
[
"id"
]
=
sender
.
getIdentifier
();
//执行hook
do_http_hook
(
hook_flowreport
,
body
,
nullptr
);
//
执行hook
do_http_hook
(
hook_flowreport
,
body
,
nullptr
);
});
static
const
string
unAuthedRealm
=
"unAuthedRealm"
;
//监听kBroadcastOnGetRtspRealm事件决定rtsp链接是否需要鉴权(传统的rtsp鉴权方案)才能访问
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastOnGetRtspRealm
,[](
BroadcastOnGetRtspRealmArgs
)
{
GET_CONFIG
(
string
,
hook_rtsp_realm
,
Hook
::
kOnRtspRealm
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_rtsp_realm
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
//无需认证
//
监听kBroadcastOnGetRtspRealm事件决定rtsp链接是否需要鉴权(传统的rtsp鉴权方案)才能访问
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastOnGetRtspRealm
,
[](
BroadcastOnGetRtspRealmArgs
)
{
GET_CONFIG
(
string
,
hook_rtsp_realm
,
Hook
::
kOnRtspRealm
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_rtsp_realm
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
//
无需认证
invoker
(
""
);
return
;
}
...
...
@@ -395,10 +388,10 @@ void installWebHook(){
body
[
"ip"
]
=
sender
.
get_peer_ip
();
body
[
"port"
]
=
sender
.
get_peer_port
();
body
[
"id"
]
=
sender
.
getIdentifier
();
//执行hook
do_http_hook
(
hook_rtsp_realm
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
if
(
!
err
.
empty
())
{
//如果接口访问失败,那么该rtsp流认证失败
//
执行hook
do_http_hook
(
hook_rtsp_realm
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
if
(
!
err
.
empty
())
{
//
如果接口访问失败,那么该rtsp流认证失败
invoker
(
unAuthedRealm
);
return
;
}
...
...
@@ -406,12 +399,12 @@ void installWebHook(){
});
});
//监听kBroadcastOnRtspAuth事件返回正确的rtsp鉴权用户密码
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastOnRtspAuth
,[](
BroadcastOnRtspAuthArgs
)
{
GET_CONFIG
(
string
,
hook_rtsp_auth
,
Hook
::
kOnRtspAuth
);
if
(
unAuthedRealm
==
realm
||
!
hook_enable
||
hook_rtsp_auth
.
empty
())
{
//认证失败
invoker
(
false
,
makeRandStr
(
12
));
//
监听kBroadcastOnRtspAuth事件返回正确的rtsp鉴权用户密码
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastOnRtspAuth
,
[](
BroadcastOnRtspAuthArgs
)
{
GET_CONFIG
(
string
,
hook_rtsp_auth
,
Hook
::
kOnRtspAuth
);
if
(
unAuthedRealm
==
realm
||
!
hook_enable
||
hook_rtsp_auth
.
empty
())
{
//
认证失败
invoker
(
false
,
makeRandStr
(
12
));
return
;
}
auto
body
=
make_json
(
args
);
...
...
@@ -421,22 +414,21 @@ void installWebHook(){
body
[
"user_name"
]
=
user_name
;
body
[
"must_no_encrypt"
]
=
must_no_encrypt
;
body
[
"realm"
]
=
realm
;
//执行hook
do_http_hook
(
hook_rtsp_auth
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
if
(
!
err
.
empty
())
{
//认证失败
invoker
(
false
,
makeRandStr
(
12
));
//
执行hook
do_http_hook
(
hook_rtsp_auth
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
if
(
!
err
.
empty
())
{
//
认证失败
invoker
(
false
,
makeRandStr
(
12
));
return
;
}
invoker
(
obj
[
"encrypted"
].
asBool
(),
obj
[
"passwd"
].
asString
());
invoker
(
obj
[
"encrypted"
].
asBool
(),
obj
[
"passwd"
].
asString
());
});
});
//监听rtsp、rtmp源注册或注销事件
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastMediaChanged
,[](
BroadcastMediaChangedArgs
){
GET_CONFIG
(
string
,
hook_stream_chaned
,
Hook
::
kOnStreamChanged
);
if
(
!
hook_enable
||
hook_stream_chaned
.
empty
()){
// 监听rtsp、rtmp源注册或注销事件
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastMediaChanged
,
[](
BroadcastMediaChangedArgs
)
{
GET_CONFIG
(
string
,
hook_stream_chaned
,
Hook
::
kOnStreamChanged
);
if
(
!
hook_enable
||
hook_stream_chaned
.
empty
())
{
return
;
}
ArgsType
body
;
...
...
@@ -450,8 +442,8 @@ void installWebHook(){
body
[
"stream"
]
=
sender
.
getId
();
body
[
"regist"
]
=
bRegist
;
}
//执行hook
do_http_hook
(
hook_stream_chaned
,
body
,
nullptr
);
//
执行hook
do_http_hook
(
hook_stream_chaned
,
body
,
nullptr
);
});
GET_CONFIG_FUNC
(
vector
<
string
>
,
origin_urls
,
Cluster
::
kOriginUrl
,
[](
const
string
&
str
)
{
...
...
@@ -465,10 +457,10 @@ void installWebHook(){
return
ret
;
});
//监听播放失败(未找到特定的流)事件
//
监听播放失败(未找到特定的流)事件
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastNotFoundStream
,
[](
BroadcastNotFoundStreamArgs
)
{
if
(
!
origin_urls
.
empty
())
{
//设置了源站,那么尝试溯源
//
设置了源站,那么尝试溯源
static
atomic
<
uint8_t
>
s_index
{
0
};
pullStreamFromOrigin
(
origin_urls
,
s_index
.
load
(),
0
,
args
,
closePlayer
);
++
s_index
;
...
...
@@ -476,7 +468,7 @@ void installWebHook(){
}
if
(
start_with
(
args
.
_param_strs
,
kEdgeServerParam
))
{
//源站收到来自边沿站的溯源请求,流不存在时立即返回拉流失败
//
源站收到来自边沿站的溯源请求,流不存在时立即返回拉流失败
closePlayer
();
return
;
}
...
...
@@ -498,14 +490,14 @@ void installWebHook(){
}
};
//执行hook
//
执行hook
do_http_hook
(
hook_stream_not_found
,
body
,
res_cb
);
});
static
auto
getRecordInfo
=
[](
const
RecordInfo
&
info
)
{
ArgsType
body
;
body
[
"start_time"
]
=
(
Json
::
UInt64
)
info
.
start_time
;
body
[
"file_size"
]
=
(
Json
::
UInt64
)
info
.
file_size
;
body
[
"start_time"
]
=
(
Json
::
UInt64
)
info
.
start_time
;
body
[
"file_size"
]
=
(
Json
::
UInt64
)
info
.
file_size
;
body
[
"time_len"
]
=
info
.
time_len
;
body
[
"file_path"
]
=
info
.
file_path
;
body
[
"file_name"
]
=
info
.
file_name
;
...
...
@@ -518,19 +510,19 @@ void installWebHook(){
};
#ifdef ENABLE_MP4
//录制mp4文件成功后广播
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastRecordMP4
,[](
BroadcastRecordMP4Args
)
{
GET_CONFIG
(
string
,
hook_record_mp4
,
Hook
::
kOnRecordMp4
);
//
录制mp4文件成功后广播
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastRecordMP4
,
[](
BroadcastRecordMP4Args
)
{
GET_CONFIG
(
string
,
hook_record_mp4
,
Hook
::
kOnRecordMp4
);
if
(
!
hook_enable
||
hook_record_mp4
.
empty
())
{
return
;
}
//执行hook
//
执行hook
do_http_hook
(
hook_record_mp4
,
getRecordInfo
(
info
),
nullptr
);
});
#endif //ENABLE_MP4
#endif //
ENABLE_MP4
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastRecordTs
,
[](
BroadcastRecordTsArgs
)
{
GET_CONFIG
(
string
,
hook_record_ts
,
Hook
::
kOnRecordTs
);
GET_CONFIG
(
string
,
hook_record_ts
,
Hook
::
kOnRecordTs
);
if
(
!
hook_enable
||
hook_record_ts
.
empty
())
{
return
;
}
...
...
@@ -538,9 +530,9 @@ void installWebHook(){
do_http_hook
(
hook_record_ts
,
getRecordInfo
(
info
),
nullptr
);
});
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastShellLogin
,[](
BroadcastShellLoginArgs
)
{
GET_CONFIG
(
string
,
hook_shell_login
,
Hook
::
kOnShellLogin
);
if
(
!
hook_enable
||
hook_shell_login
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastShellLogin
,
[](
BroadcastShellLoginArgs
)
{
GET_CONFIG
(
string
,
hook_shell_login
,
Hook
::
kOnShellLogin
);
if
(
!
hook_enable
||
hook_shell_login
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
)
{
invoker
(
""
);
return
;
}
...
...
@@ -551,21 +543,19 @@ void installWebHook(){
body
[
"user_name"
]
=
user_name
;
body
[
"passwd"
]
=
passwd
;
//执行hook
do_http_hook
(
hook_shell_login
,
body
,
[
invoker
](
const
Value
&
,
const
string
&
err
){
invoker
(
err
);
});
// 执行hook
do_http_hook
(
hook_shell_login
,
body
,
[
invoker
](
const
Value
&
,
const
string
&
err
)
{
invoker
(
err
);
});
});
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastStreamNoneReader
,
[](
BroadcastStreamNoneReaderArgs
)
{
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastStreamNoneReader
,
[](
BroadcastStreamNoneReaderArgs
)
{
if
(
!
origin_urls
.
empty
())
{
//边沿站无人观看时立即停止溯源
//
边沿站无人观看时立即停止溯源
sender
.
close
(
false
);
WarnL
<<
"无人观看主动关闭流:"
<<
sender
.
getOriginUrl
();
return
;
}
GET_CONFIG
(
string
,
hook_stream_none_reader
,
Hook
::
kOnStreamNoneReader
);
if
(
!
hook_enable
||
hook_stream_none_reader
.
empty
())
{
GET_CONFIG
(
string
,
hook_stream_none_reader
,
Hook
::
kOnStreamNoneReader
);
if
(
!
hook_enable
||
hook_stream_none_reader
.
empty
())
{
return
;
}
...
...
@@ -575,11 +565,11 @@ void installWebHook(){
body
[
"app"
]
=
sender
.
getApp
();
body
[
"stream"
]
=
sender
.
getId
();
weak_ptr
<
MediaSource
>
weakSrc
=
sender
.
shared_from_this
();
//执行hook
do_http_hook
(
hook_stream_none_reader
,
body
,
[
weakSrc
](
const
Value
&
obj
,
const
string
&
err
)
{
//
执行hook
do_http_hook
(
hook_stream_none_reader
,
body
,
[
weakSrc
](
const
Value
&
obj
,
const
string
&
err
)
{
bool
flag
=
obj
[
"close"
].
asBool
();
auto
strongSrc
=
weakSrc
.
lock
();
if
(
!
flag
||
!
err
.
empty
()
||
!
strongSrc
)
{
if
(
!
flag
||
!
err
.
empty
()
||
!
strongSrc
)
{
return
;
}
strongSrc
->
close
(
false
);
...
...
@@ -603,7 +593,7 @@ void installWebHook(){
body
[
"originUrl"
]
=
sender
.
getOriginUrl
(
MediaSource
::
NullMediaSource
());
body
[
"msg"
]
=
ex
.
what
();
body
[
"err"
]
=
ex
.
getErrCode
();
//执行hook
//
执行hook
do_http_hook
(
hook_send_rtp_stopped
,
body
,
nullptr
);
});
...
...
@@ -615,24 +605,24 @@ void installWebHook(){
* 4、cookie中记录的url参数是否跟本次url参数一致,如果一致直接返回客户端错误码
* 5、触发kBroadcastHttpAccess事件
*/
//开发者应该通过该事件判定http客户端是否有权限访问http服务器上的特定文件
//ZLMediaKit会记录本次鉴权的结果至cookie
//如果鉴权成功,在cookie有效期内,那么下次客户端再访问授权目录时,ZLMediaKit会直接返回文件
//如果鉴权失败,在cookie有效期内,如果http url参数不变(否则会立即再次触发鉴权事件),ZLMediaKit会直接返回错误码
//如果用户客户端不支持cookie,那么ZLMediaKit会根据url参数查找cookie并追踪用户,
//如果没有url参数,客户端又不支持cookie,那么会根据ip和端口追踪用户
//追踪用户的目的是为了缓存上次鉴权结果,减少鉴权次数,提高性能
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastHttpAccess
,[](
BroadcastHttpAccessArgs
)
{
GET_CONFIG
(
string
,
hook_http_access
,
Hook
::
kOnHttpAccess
);
if
(
sender
.
get_peer_ip
()
==
"127.0.0.1"
||
parser
.
Params
()
==
hook_adminparams
)
{
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
invoker
(
""
,
""
,
60
*
60
);
//
开发者应该通过该事件判定http客户端是否有权限访问http服务器上的特定文件
//
ZLMediaKit会记录本次鉴权的结果至cookie
//
如果鉴权成功,在cookie有效期内,那么下次客户端再访问授权目录时,ZLMediaKit会直接返回文件
//
如果鉴权失败,在cookie有效期内,如果http url参数不变(否则会立即再次触发鉴权事件),ZLMediaKit会直接返回错误码
//
如果用户客户端不支持cookie,那么ZLMediaKit会根据url参数查找cookie并追踪用户,
//
如果没有url参数,客户端又不支持cookie,那么会根据ip和端口追踪用户
//
追踪用户的目的是为了缓存上次鉴权结果,减少鉴权次数,提高性能
NoticeCenter
::
Instance
().
addListener
(
&
web_hook_tag
,
Broadcast
::
kBroadcastHttpAccess
,
[](
BroadcastHttpAccessArgs
)
{
GET_CONFIG
(
string
,
hook_http_access
,
Hook
::
kOnHttpAccess
);
if
(
sender
.
get_peer_ip
()
==
"127.0.0.1"
||
parser
.
Params
()
==
hook_adminparams
)
{
//
如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
invoker
(
""
,
""
,
60
*
60
);
return
;
}
if
(
!
hook_enable
||
hook_http_access
.
empty
())
{
//未开启http文件访问鉴权,那么允许访问,但是每次访问都要鉴权;
//因为后续随时都可能开启鉴权(重载配置文件后可能重新开启鉴权)
invoker
(
""
,
""
,
0
);
if
(
!
hook_enable
||
hook_http_access
.
empty
())
{
//
未开启http文件访问鉴权,那么允许访问,但是每次访问都要鉴权;
//
因为后续随时都可能开启鉴权(重载配置文件后可能重新开启鉴权)
invoker
(
""
,
""
,
0
);
return
;
}
...
...
@@ -643,20 +633,20 @@ void installWebHook(){
body
[
"path"
]
=
path
;
body
[
"is_dir"
]
=
is_dir
;
body
[
"params"
]
=
parser
.
Params
();
for
(
auto
&
pr
:
parser
.
getHeader
())
{
for
(
auto
&
pr
:
parser
.
getHeader
())
{
body
[
string
(
"header."
)
+
pr
.
first
]
=
pr
.
second
;
}
//执行hook
do_http_hook
(
hook_http_access
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
if
(
!
err
.
empty
())
{
//如果接口访问失败,那么仅限本次没有访问http服务器的权限
invoker
(
err
,
""
,
0
);
//
执行hook
do_http_hook
(
hook_http_access
,
body
,
[
invoker
](
const
Value
&
obj
,
const
string
&
err
)
{
if
(
!
err
.
empty
())
{
//
如果接口访问失败,那么仅限本次没有访问http服务器的权限
invoker
(
err
,
""
,
0
);
return
;
}
//err参数代表不能访问的原因,空则代表可以访问
//path参数是该客户端能访问或被禁止的顶端目录,如果path为空字符串,则表述为当前目录
//second参数规定该cookie超时时间,如果second为0,本次鉴权结果不缓存
invoker
(
obj
[
"err"
].
asString
(),
obj
[
"path"
].
asString
(),
obj
[
"second"
].
asInt
());
//
err参数代表不能访问的原因,空则代表可以访问
//
path参数是该客户端能访问或被禁止的顶端目录,如果path为空字符串,则表述为当前目录
//
second参数规定该cookie超时时间,如果second为0,本次鉴权结果不缓存
invoker
(
obj
[
"err"
].
asString
(),
obj
[
"path"
].
asString
(),
obj
[
"second"
].
asInt
());
});
});
...
...
@@ -675,14 +665,14 @@ void installWebHook(){
do_http_hook
(
rtp_server_timeout
,
body
);
});
//汇报服务器重新启动
//
汇报服务器重新启动
reportServerStarted
();
//定时上报保活
//
定时上报保活
reportServerKeepalive
();
}
void
unInstallWebHook
(){
void
unInstallWebHook
()
{
g_keepalive_timer
.
reset
();
NoticeCenter
::
Instance
().
delListener
(
&
web_hook_tag
);
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论