diff --git a/server/WebHook.cpp b/server/WebHook.cpp index 77ddebee..3df2807f 100755 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -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"; +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([](){ +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 &fun){ +static void parse_http_response(const SockException &ex, const Parser &res, const function &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 :"<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 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(alive_interval, []() { + g_keepalive_timer = std::make_shared(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& urls, size_t index, size_t failed_cnt, const MediaInfo &args, - const function &closePlayer) { - +static void pullStreamFromOrigin(const vector &urls, size_t index, size_t failed_cnt, const MediaInfo &args, const function &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& 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, 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 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 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); }