mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 14:45:55 +08:00
整理webapi、webhook框架代码
This commit is contained in:
parent
781708f0a1
commit
f9f9cde2b4
223
server/WebApi.cpp
Normal file → Executable file
223
server/WebApi.cpp
Normal file → Executable file
@ -13,7 +13,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "jsoncpp/json.h"
|
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
#include "Util/onceToken.h"
|
#include "Util/onceToken.h"
|
||||||
@ -36,20 +35,11 @@
|
|||||||
#if defined(ENABLE_RTPPROXY)
|
#if defined(ENABLE_RTPPROXY)
|
||||||
#include "Rtp/RtpServer.h"
|
#include "Rtp/RtpServer.h"
|
||||||
#endif
|
#endif
|
||||||
using namespace Json;
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
using namespace mediakit;
|
using namespace mediakit;
|
||||||
|
|
||||||
namespace API {
|
namespace API {
|
||||||
typedef enum {
|
|
||||||
Exception = -400,//代码抛异常
|
|
||||||
InvalidArgs = -300,//参数不合法
|
|
||||||
SqlFailed = -200,//sql执行失败
|
|
||||||
AuthFailed = -100,//鉴权失败
|
|
||||||
OtherFailed = -1,//业务代码执行失败,
|
|
||||||
Success = 0//执行成功
|
|
||||||
} ApiErr;
|
|
||||||
|
|
||||||
#define API_FIELD "api."
|
#define API_FIELD "api."
|
||||||
const string kApiDebug = API_FIELD"apiDebug";
|
const string kApiDebug = API_FIELD"apiDebug";
|
||||||
const string kSecret = API_FIELD"secret";
|
const string kSecret = API_FIELD"secret";
|
||||||
@ -64,42 +54,7 @@ static onceToken token([]() {
|
|||||||
});
|
});
|
||||||
}//namespace API
|
}//namespace API
|
||||||
|
|
||||||
|
using HttpApi = function<void(const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender)>;
|
||||||
class ApiRetException: public std::runtime_error {
|
|
||||||
public:
|
|
||||||
ApiRetException(const char *str = "success" ,int code = API::Success):runtime_error(str){
|
|
||||||
_code = code;
|
|
||||||
}
|
|
||||||
~ApiRetException() = default;
|
|
||||||
int code(){ return _code; }
|
|
||||||
private:
|
|
||||||
int _code;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AuthException : public ApiRetException {
|
|
||||||
public:
|
|
||||||
AuthException(const char *str):ApiRetException(str,API::AuthFailed){}
|
|
||||||
~AuthException() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
class InvalidArgsException: public ApiRetException {
|
|
||||||
public:
|
|
||||||
InvalidArgsException(const char *str):ApiRetException(str,API::InvalidArgs){}
|
|
||||||
~InvalidArgsException() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SuccessException: public ApiRetException {
|
|
||||||
public:
|
|
||||||
SuccessException():ApiRetException("success",API::Success){}
|
|
||||||
~SuccessException() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define API_ARGS1 SockInfo &sender,HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val
|
|
||||||
#define API_ARGS2 API_ARGS1, const HttpSession::HttpResponseInvoker &invoker
|
|
||||||
#define API_ARGS_VALUE1 sender,headerIn,headerOut,allArgs,val
|
|
||||||
|
|
||||||
typedef map<string, variant, StrCaseCompare> ApiArgsType;
|
|
||||||
typedef function<void(const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender)> HttpApi;
|
|
||||||
//http api列表
|
//http api列表
|
||||||
static map<string, HttpApi> s_map_api;
|
static map<string, HttpApi> s_map_api;
|
||||||
|
|
||||||
@ -119,7 +74,7 @@ static void responseApi(int code, const string &msg, const HttpSession::HttpResp
|
|||||||
|
|
||||||
static ApiArgsType getAllArgs(const Parser &parser);
|
static ApiArgsType getAllArgs(const Parser &parser);
|
||||||
|
|
||||||
static HttpApi toApi(const function<void(API_ARGS2)> &cb) {
|
static HttpApi toApi(const function<void(API_ARGS_MAP_ASYNC)> &cb) {
|
||||||
return [cb](const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender) {
|
return [cb](const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender) {
|
||||||
GET_CONFIG(string, charSet, Http::kCharSet);
|
GET_CONFIG(string, charSet, Http::kCharSet);
|
||||||
HttpSession::KeyValue headerOut;
|
HttpSession::KeyValue headerOut;
|
||||||
@ -128,23 +83,62 @@ static HttpApi toApi(const function<void(API_ARGS2)> &cb) {
|
|||||||
Json::Value val;
|
Json::Value val;
|
||||||
val["code"] = API::Success;
|
val["code"] = API::Success;
|
||||||
|
|
||||||
|
//参数解析成map
|
||||||
auto args = getAllArgs(parser);
|
auto args = getAllArgs(parser);
|
||||||
cb(sender, parser.getHeader(), headerOut, args, val, invoker);
|
cb(sender, parser.getHeader(), headerOut, args, val, invoker);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static HttpApi toApi(const function<void(API_ARGS1)> &cb) {
|
static HttpApi toApi(const function<void(API_ARGS_MAP)> &cb) {
|
||||||
return toApi([cb](API_ARGS2) {
|
return toApi([cb](API_ARGS_MAP_ASYNC) {
|
||||||
cb(API_ARGS_VALUE1);
|
cb(API_ARGS_VALUE);
|
||||||
invoker("200 OK", headerOut, val.toStyledString());
|
invoker("200 OK", headerOut, val.toStyledString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FUNC>
|
static HttpApi toApi(const function<void(API_ARGS_JSON_ASYNC)> &cb) {
|
||||||
static void api_regist(const string &api_path, FUNC &&func) {
|
return [cb](const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, SockInfo &sender) {
|
||||||
s_map_api.emplace(api_path, toApi(std::move(func)));
|
GET_CONFIG(string, charSet, Http::kCharSet);
|
||||||
|
HttpSession::KeyValue headerOut;
|
||||||
|
headerOut["Content-Type"] = string("application/json; charset=") + charSet;
|
||||||
|
|
||||||
|
Json::Value out;
|
||||||
|
out["code"] = API::Success;
|
||||||
|
|
||||||
|
if (parser["Content-Type"].find("application/json") == string::npos) {
|
||||||
|
throw InvalidArgsException("该接口只支持json格式的请求");
|
||||||
|
}
|
||||||
|
//参数解析成json对象然后处理
|
||||||
|
Json::Value in;
|
||||||
|
Json::Reader reader;
|
||||||
|
reader.parse(parser.Content(), in);
|
||||||
|
|
||||||
|
cb(sender, parser.getHeader(), headerOut, in, out, invoker);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HttpApi toApi(const function<void(API_ARGS_JSON)> &cb) {
|
||||||
|
return toApi([cb](API_ARGS_JSON_ASYNC) {
|
||||||
|
cb(API_ARGS_VALUE);
|
||||||
|
invoker("200 OK", headerOut, val.toStyledString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_MAP)> &func) {
|
||||||
|
s_map_api.emplace(api_path, toApi(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_MAP_ASYNC)> &func) {
|
||||||
|
s_map_api.emplace(api_path, toApi(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_JSON)> &func) {
|
||||||
|
s_map_api.emplace(api_path, toApi(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_JSON_ASYNC)> &func) {
|
||||||
|
s_map_api.emplace(api_path, toApi(func));
|
||||||
|
}
|
||||||
|
|
||||||
//获取HTTP请求中url参数、content参数
|
//获取HTTP请求中url参数、content参数
|
||||||
static ApiArgsType getAllArgs(const Parser &parser) {
|
static ApiArgsType getAllArgs(const Parser &parser) {
|
||||||
@ -233,29 +227,6 @@ static inline void addHttpListener(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Args,typename First>
|
|
||||||
bool checkArgs(Args &&args,First &&first){
|
|
||||||
return !args[first].empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Args,typename First,typename ...KeyTypes>
|
|
||||||
bool checkArgs(Args &&args,First &&first,KeyTypes && ...keys){
|
|
||||||
return !args[first].empty() && checkArgs(std::forward<Args>(args),std::forward<KeyTypes>(keys)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_ARGS(...) \
|
|
||||||
if(!checkArgs(allArgs,##__VA_ARGS__)){ \
|
|
||||||
throw InvalidArgsException("缺少必要参数:" #__VA_ARGS__); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_SECRET() \
|
|
||||||
if(sender.get_peer_ip() != "127.0.0.1"){ \
|
|
||||||
CHECK_ARGS("secret"); \
|
|
||||||
if(api_secret != allArgs["secret"]){ \
|
|
||||||
throw AuthException("secret错误"); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
//拉流代理器列表
|
//拉流代理器列表
|
||||||
static unordered_map<string ,PlayerProxy::Ptr> s_proxyMap;
|
static unordered_map<string ,PlayerProxy::Ptr> s_proxyMap;
|
||||||
static recursive_mutex s_proxyMapMtx;
|
static recursive_mutex s_proxyMapMtx;
|
||||||
@ -285,7 +256,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//获取线程负载
|
//获取线程负载
|
||||||
//测试url http://127.0.0.1/index/api/getThreadsLoad
|
//测试url http://127.0.0.1/index/api/getThreadsLoad
|
||||||
api_regist("/index/api/getThreadsLoad",[](API_ARGS2){
|
api_regist("/index/api/getThreadsLoad",[](API_ARGS_MAP_ASYNC){
|
||||||
EventPollerPool::Instance().getExecutorDelay([invoker, headerOut](const vector<int> &vecDelay) {
|
EventPollerPool::Instance().getExecutorDelay([invoker, headerOut](const vector<int> &vecDelay) {
|
||||||
Value val;
|
Value val;
|
||||||
auto vec = EventPollerPool::Instance().getExecutorLoad();
|
auto vec = EventPollerPool::Instance().getExecutorLoad();
|
||||||
@ -303,7 +274,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//获取后台工作线程负载
|
//获取后台工作线程负载
|
||||||
//测试url http://127.0.0.1/index/api/getWorkThreadsLoad
|
//测试url http://127.0.0.1/index/api/getWorkThreadsLoad
|
||||||
api_regist("/index/api/getWorkThreadsLoad", [](API_ARGS2){
|
api_regist("/index/api/getWorkThreadsLoad", [](API_ARGS_MAP_ASYNC){
|
||||||
WorkThreadPool::Instance().getExecutorDelay([invoker, headerOut](const vector<int> &vecDelay) {
|
WorkThreadPool::Instance().getExecutorDelay([invoker, headerOut](const vector<int> &vecDelay) {
|
||||||
Value val;
|
Value val;
|
||||||
auto vec = WorkThreadPool::Instance().getExecutorLoad();
|
auto vec = WorkThreadPool::Instance().getExecutorLoad();
|
||||||
@ -321,7 +292,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//获取服务器配置
|
//获取服务器配置
|
||||||
//测试url http://127.0.0.1/index/api/getServerConfig
|
//测试url http://127.0.0.1/index/api/getServerConfig
|
||||||
api_regist("/index/api/getServerConfig",[](API_ARGS1){
|
api_regist("/index/api/getServerConfig",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
Value obj;
|
Value obj;
|
||||||
for (auto &pr : mINI::Instance()) {
|
for (auto &pr : mINI::Instance()) {
|
||||||
@ -333,7 +304,7 @@ void installWebApi() {
|
|||||||
//设置服务器配置
|
//设置服务器配置
|
||||||
//测试url(比如关闭http api调试) http://127.0.0.1/index/api/setServerConfig?api.apiDebug=0
|
//测试url(比如关闭http api调试) http://127.0.0.1/index/api/setServerConfig?api.apiDebug=0
|
||||||
//你也可以通过http post方式传参,可以通过application/x-www-form-urlencoded或application/json方式传参
|
//你也可以通过http post方式传参,可以通过application/x-www-form-urlencoded或application/json方式传参
|
||||||
api_regist("/index/api/setServerConfig",[](API_ARGS1){
|
api_regist("/index/api/setServerConfig",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
auto &ini = mINI::Instance();
|
auto &ini = mINI::Instance();
|
||||||
int changed = API::Success;
|
int changed = API::Success;
|
||||||
@ -357,7 +328,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
static auto s_get_api_list = [](API_ARGS1){
|
static auto s_get_api_list = [](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
for(auto &pr : s_map_api){
|
for(auto &pr : s_map_api){
|
||||||
val["data"].append(pr.first);
|
val["data"].append(pr.first);
|
||||||
@ -366,20 +337,20 @@ void installWebApi() {
|
|||||||
|
|
||||||
//获取服务器api列表
|
//获取服务器api列表
|
||||||
//测试url http://127.0.0.1/index/api/getApiList
|
//测试url http://127.0.0.1/index/api/getApiList
|
||||||
api_regist("/index/api/getApiList",[](API_ARGS1){
|
api_regist("/index/api/getApiList",[](API_ARGS_MAP){
|
||||||
s_get_api_list(API_ARGS_VALUE1);
|
s_get_api_list(API_ARGS_VALUE);
|
||||||
});
|
});
|
||||||
|
|
||||||
//获取服务器api列表
|
//获取服务器api列表
|
||||||
//测试url http://127.0.0.1/index/
|
//测试url http://127.0.0.1/index/
|
||||||
api_regist("/index/",[](API_ARGS1){
|
api_regist("/index/",[](API_ARGS_MAP){
|
||||||
s_get_api_list(API_ARGS_VALUE1);
|
s_get_api_list(API_ARGS_VALUE);
|
||||||
});
|
});
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
//重启服务器,只有Daemon方式才能重启,否则是直接关闭!
|
//重启服务器,只有Daemon方式才能重启,否则是直接关闭!
|
||||||
//测试url http://127.0.0.1/index/api/restartServer
|
//测试url http://127.0.0.1/index/api/restartServer
|
||||||
api_regist("/index/api/restartServer",[](API_ARGS1){
|
api_regist("/index/api/restartServer",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
EventPollerPool::Instance().getPoller()->doDelayTask(1000,[](){
|
EventPollerPool::Instance().getPoller()->doDelayTask(1000,[](){
|
||||||
//尝试正常退出
|
//尝试正常退出
|
||||||
@ -457,7 +428,7 @@ void installWebApi() {
|
|||||||
//测试url0(获取所有流) http://127.0.0.1/index/api/getMediaList
|
//测试url0(获取所有流) http://127.0.0.1/index/api/getMediaList
|
||||||
//测试url1(获取虚拟主机为"__defaultVost__"的流) http://127.0.0.1/index/api/getMediaList?vhost=__defaultVost__
|
//测试url1(获取虚拟主机为"__defaultVost__"的流) http://127.0.0.1/index/api/getMediaList?vhost=__defaultVost__
|
||||||
//测试url2(获取rtsp类型的流) http://127.0.0.1/index/api/getMediaList?schema=rtsp
|
//测试url2(获取rtsp类型的流) http://127.0.0.1/index/api/getMediaList?schema=rtsp
|
||||||
api_regist("/index/api/getMediaList",[](API_ARGS1){
|
api_regist("/index/api/getMediaList",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
//获取所有MediaSource列表
|
//获取所有MediaSource列表
|
||||||
MediaSource::for_each_media([&](const MediaSource::Ptr &media){
|
MediaSource::for_each_media([&](const MediaSource::Ptr &media){
|
||||||
@ -475,14 +446,14 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//测试url http://127.0.0.1/index/api/isMediaOnline?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
|
//测试url http://127.0.0.1/index/api/isMediaOnline?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
|
||||||
api_regist("/index/api/isMediaOnline",[](API_ARGS1){
|
api_regist("/index/api/isMediaOnline",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("schema","vhost","app","stream");
|
CHECK_ARGS("schema","vhost","app","stream");
|
||||||
val["online"] = (bool) (MediaSource::find(allArgs["schema"],allArgs["vhost"],allArgs["app"],allArgs["stream"]));
|
val["online"] = (bool) (MediaSource::find(allArgs["schema"],allArgs["vhost"],allArgs["app"],allArgs["stream"]));
|
||||||
});
|
});
|
||||||
|
|
||||||
//测试url http://127.0.0.1/index/api/getMediaInfo?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
|
//测试url http://127.0.0.1/index/api/getMediaInfo?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
|
||||||
api_regist("/index/api/getMediaInfo",[](API_ARGS1){
|
api_regist("/index/api/getMediaInfo",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("schema","vhost","app","stream");
|
CHECK_ARGS("schema","vhost","app","stream");
|
||||||
auto src = MediaSource::find(allArgs["schema"],allArgs["vhost"],allArgs["app"],allArgs["stream"]);
|
auto src = MediaSource::find(allArgs["schema"],allArgs["vhost"],allArgs["app"],allArgs["stream"]);
|
||||||
@ -497,7 +468,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//主动关断流,包括关断拉流、推流
|
//主动关断流,包括关断拉流、推流
|
||||||
//测试url http://127.0.0.1/index/api/close_stream?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs&force=1
|
//测试url http://127.0.0.1/index/api/close_stream?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs&force=1
|
||||||
api_regist("/index/api/close_stream",[](API_ARGS1){
|
api_regist("/index/api/close_stream",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("schema","vhost","app","stream");
|
CHECK_ARGS("schema","vhost","app","stream");
|
||||||
//踢掉推流器
|
//踢掉推流器
|
||||||
@ -519,7 +490,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//批量主动关断流,包括关断拉流、推流
|
//批量主动关断流,包括关断拉流、推流
|
||||||
//测试url http://127.0.0.1/index/api/close_streams?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs&force=1
|
//测试url http://127.0.0.1/index/api/close_streams?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs&force=1
|
||||||
api_regist("/index/api/close_streams",[](API_ARGS1){
|
api_regist("/index/api/close_streams",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
//筛选命中个数
|
//筛选命中个数
|
||||||
int count_hit = 0;
|
int count_hit = 0;
|
||||||
@ -555,7 +526,7 @@ void installWebApi() {
|
|||||||
//获取所有TcpSession列表信息
|
//获取所有TcpSession列表信息
|
||||||
//可以根据本地端口和远端ip来筛选
|
//可以根据本地端口和远端ip来筛选
|
||||||
//测试url(筛选某端口下的tcp会话) http://127.0.0.1/index/api/getAllSession?local_port=1935
|
//测试url(筛选某端口下的tcp会话) http://127.0.0.1/index/api/getAllSession?local_port=1935
|
||||||
api_regist("/index/api/getAllSession",[](API_ARGS1){
|
api_regist("/index/api/getAllSession",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
Value jsession;
|
Value jsession;
|
||||||
uint16_t local_port = allArgs["local_port"].as<uint16_t>();
|
uint16_t local_port = allArgs["local_port"].as<uint16_t>();
|
||||||
@ -580,7 +551,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//断开tcp连接,比如说可以断开rtsp、rtmp播放器等
|
//断开tcp连接,比如说可以断开rtsp、rtmp播放器等
|
||||||
//测试url http://127.0.0.1/index/api/kick_session?id=123456
|
//测试url http://127.0.0.1/index/api/kick_session?id=123456
|
||||||
api_regist("/index/api/kick_session",[](API_ARGS1){
|
api_regist("/index/api/kick_session",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("id");
|
CHECK_ARGS("id");
|
||||||
//踢掉tcp会话
|
//踢掉tcp会话
|
||||||
@ -594,7 +565,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//批量断开tcp连接,比如说可以断开rtsp、rtmp播放器等
|
//批量断开tcp连接,比如说可以断开rtsp、rtmp播放器等
|
||||||
//测试url http://127.0.0.1/index/api/kick_sessions?local_port=1935
|
//测试url http://127.0.0.1/index/api/kick_sessions?local_port=1935
|
||||||
api_regist("/index/api/kick_sessions",[](API_ARGS1){
|
api_regist("/index/api/kick_sessions",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
uint16_t local_port = allArgs["local_port"].as<uint16_t>();
|
uint16_t local_port = allArgs["local_port"].as<uint16_t>();
|
||||||
string &peer_ip = allArgs["peer_ip"];
|
string &peer_ip = allArgs["peer_ip"];
|
||||||
@ -658,7 +629,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//动态添加rtsp/rtmp拉流代理
|
//动态添加rtsp/rtmp拉流代理
|
||||||
//测试url http://127.0.0.1/index/api/addStreamProxy?vhost=__defaultVhost__&app=proxy&enable_rtsp=1&enable_rtmp=1&stream=0&url=rtmp://127.0.0.1/live/obs
|
//测试url http://127.0.0.1/index/api/addStreamProxy?vhost=__defaultVhost__&app=proxy&enable_rtsp=1&enable_rtmp=1&stream=0&url=rtmp://127.0.0.1/live/obs
|
||||||
api_regist("/index/api/addStreamProxy",[](API_ARGS2){
|
api_regist("/index/api/addStreamProxy",[](API_ARGS_MAP_ASYNC){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("vhost","app","stream","url");
|
CHECK_ARGS("vhost","app","stream","url");
|
||||||
addStreamProxy(allArgs["vhost"],
|
addStreamProxy(allArgs["vhost"],
|
||||||
@ -681,7 +652,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//关闭拉流代理
|
//关闭拉流代理
|
||||||
//测试url http://127.0.0.1/index/api/delStreamProxy?key=__defaultVhost__/proxy/0
|
//测试url http://127.0.0.1/index/api/delStreamProxy?key=__defaultVhost__/proxy/0
|
||||||
api_regist("/index/api/delStreamProxy",[](API_ARGS1){
|
api_regist("/index/api/delStreamProxy",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("key");
|
CHECK_ARGS("key");
|
||||||
lock_guard<recursive_mutex> lck(s_proxyMapMtx);
|
lock_guard<recursive_mutex> lck(s_proxyMapMtx);
|
||||||
@ -721,7 +692,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//动态添加rtsp/rtmp拉流代理
|
//动态添加rtsp/rtmp拉流代理
|
||||||
//测试url http://127.0.0.1/index/api/addFFmpegSource?src_url=http://live.hkstv.hk.lxdns.com/live/hks2/playlist.m3u8&dst_url=rtmp://127.0.0.1/live/hks2&timeout_ms=10000
|
//测试url http://127.0.0.1/index/api/addFFmpegSource?src_url=http://live.hkstv.hk.lxdns.com/live/hks2/playlist.m3u8&dst_url=rtmp://127.0.0.1/live/hks2&timeout_ms=10000
|
||||||
api_regist("/index/api/addFFmpegSource",[](API_ARGS2){
|
api_regist("/index/api/addFFmpegSource",[](API_ARGS_MAP_ASYNC){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("src_url","dst_url","timeout_ms");
|
CHECK_ARGS("src_url","dst_url","timeout_ms");
|
||||||
auto src_url = allArgs["src_url"];
|
auto src_url = allArgs["src_url"];
|
||||||
@ -744,7 +715,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//关闭拉流代理
|
//关闭拉流代理
|
||||||
//测试url http://127.0.0.1/index/api/delFFmepgSource?key=key
|
//测试url http://127.0.0.1/index/api/delFFmepgSource?key=key
|
||||||
api_regist("/index/api/delFFmpegSource",[](API_ARGS1){
|
api_regist("/index/api/delFFmpegSource",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("key");
|
CHECK_ARGS("key");
|
||||||
lock_guard<decltype(s_ffmpegMapMtx)> lck(s_ffmpegMapMtx);
|
lock_guard<decltype(s_ffmpegMapMtx)> lck(s_ffmpegMapMtx);
|
||||||
@ -753,13 +724,13 @@ void installWebApi() {
|
|||||||
|
|
||||||
//新增http api下载可执行程序文件接口
|
//新增http api下载可执行程序文件接口
|
||||||
//测试url http://127.0.0.1/index/api/downloadBin
|
//测试url http://127.0.0.1/index/api/downloadBin
|
||||||
api_regist("/index/api/downloadBin",[](API_ARGS2){
|
api_regist("/index/api/downloadBin",[](API_ARGS_MAP_ASYNC){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
invoker.responseFile(headerIn,StrCaseMap(),exePath());
|
invoker.responseFile(headerIn,StrCaseMap(),exePath());
|
||||||
});
|
});
|
||||||
|
|
||||||
#if defined(ENABLE_RTPPROXY)
|
#if defined(ENABLE_RTPPROXY)
|
||||||
api_regist("/index/api/getRtpInfo",[](API_ARGS1){
|
api_regist("/index/api/getRtpInfo",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("stream_id");
|
CHECK_ARGS("stream_id");
|
||||||
|
|
||||||
@ -775,7 +746,7 @@ void installWebApi() {
|
|||||||
val["local_ip"] = process->get_local_ip();
|
val["local_ip"] = process->get_local_ip();
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/openRtpServer",[](API_ARGS1){
|
api_regist("/index/api/openRtpServer",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("port", "enable_tcp", "stream_id");
|
CHECK_ARGS("port", "enable_tcp", "stream_id");
|
||||||
|
|
||||||
@ -801,7 +772,7 @@ void installWebApi() {
|
|||||||
val["port"] = server->getPort();
|
val["port"] = server->getPort();
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/closeRtpServer",[](API_ARGS1){
|
api_regist("/index/api/closeRtpServer",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("stream_id");
|
CHECK_ARGS("stream_id");
|
||||||
|
|
||||||
@ -816,7 +787,7 @@ void installWebApi() {
|
|||||||
val["hit"] = 1;
|
val["hit"] = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/listRtpServer",[](API_ARGS1){
|
api_regist("/index/api/listRtpServer",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
|
|
||||||
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
|
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
|
||||||
@ -828,7 +799,7 @@ void installWebApi() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/startSendRtp",[](API_ARGS2){
|
api_regist("/index/api/startSendRtp",[](API_ARGS_MAP_ASYNC){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("vhost", "app", "stream", "ssrc", "dst_url", "dst_port", "is_udp");
|
CHECK_ARGS("vhost", "app", "stream", "ssrc", "dst_url", "dst_port", "is_udp");
|
||||||
|
|
||||||
@ -847,7 +818,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/stopSendRtp",[](API_ARGS1){
|
api_regist("/index/api/stopSendRtp",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("vhost", "app", "stream");
|
CHECK_ARGS("vhost", "app", "stream");
|
||||||
|
|
||||||
@ -862,7 +833,7 @@ void installWebApi() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/pauseRtpCheck", [](API_ARGS1) {
|
api_regist("/index/api/pauseRtpCheck", [](API_ARGS_MAP) {
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("stream_id");
|
CHECK_ARGS("stream_id");
|
||||||
//只是暂停流的检查,流媒体服务器做为流负载服务,收流就转发,RTSP/RTMP有自己暂停协议
|
//只是暂停流的检查,流媒体服务器做为流负载服务,收流就转发,RTSP/RTMP有自己暂停协议
|
||||||
@ -877,7 +848,7 @@ void installWebApi() {
|
|||||||
val["hit"] = 1;
|
val["hit"] = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/api/resumeRtpCheck", [](API_ARGS1) {
|
api_regist("/index/api/resumeRtpCheck", [](API_ARGS_MAP) {
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("stream_id");
|
CHECK_ARGS("stream_id");
|
||||||
|
|
||||||
@ -895,7 +866,7 @@ void installWebApi() {
|
|||||||
#endif//ENABLE_RTPPROXY
|
#endif//ENABLE_RTPPROXY
|
||||||
|
|
||||||
// 开始录制hls或MP4
|
// 开始录制hls或MP4
|
||||||
api_regist("/index/api/startRecord",[](API_ARGS1){
|
api_regist("/index/api/startRecord",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("type","vhost","app","stream");
|
CHECK_ARGS("type","vhost","app","stream");
|
||||||
auto result = Recorder::startRecord((Recorder::type) allArgs["type"].as<int>(),
|
auto result = Recorder::startRecord((Recorder::type) allArgs["type"].as<int>(),
|
||||||
@ -909,7 +880,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 停止录制hls或MP4
|
// 停止录制hls或MP4
|
||||||
api_regist("/index/api/stopRecord",[](API_ARGS1){
|
api_regist("/index/api/stopRecord",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("type","vhost","app","stream");
|
CHECK_ARGS("type","vhost","app","stream");
|
||||||
auto result = Recorder::stopRecord((Recorder::type) allArgs["type"].as<int>(),
|
auto result = Recorder::stopRecord((Recorder::type) allArgs["type"].as<int>(),
|
||||||
@ -922,7 +893,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 获取hls或MP4录制状态
|
// 获取hls或MP4录制状态
|
||||||
api_regist("/index/api/isRecording",[](API_ARGS1){
|
api_regist("/index/api/isRecording",[](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("type","vhost","app","stream");
|
CHECK_ARGS("type","vhost","app","stream");
|
||||||
val["status"] = Recorder::isRecording((Recorder::type) allArgs["type"].as<int>(),
|
val["status"] = Recorder::isRecording((Recorder::type) allArgs["type"].as<int>(),
|
||||||
@ -933,7 +904,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//获取录像文件夹列表或mp4文件列表
|
//获取录像文件夹列表或mp4文件列表
|
||||||
//http://127.0.0.1/index/api/getMp4RecordFile?vhost=__defaultVhost__&app=live&stream=ss&period=2020-01
|
//http://127.0.0.1/index/api/getMp4RecordFile?vhost=__defaultVhost__&app=live&stream=ss&period=2020-01
|
||||||
api_regist("/index/api/getMp4RecordFile", [](API_ARGS1){
|
api_regist("/index/api/getMp4RecordFile", [](API_ARGS_MAP){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("vhost", "app", "stream");
|
CHECK_ARGS("vhost", "app", "stream");
|
||||||
auto record_path = Recorder::getRecordPath(Recorder::type_mp4, allArgs["vhost"], allArgs["app"],allArgs["stream"]);
|
auto record_path = Recorder::getRecordPath(Recorder::type_mp4, allArgs["vhost"], allArgs["app"],allArgs["stream"]);
|
||||||
@ -988,7 +959,7 @@ void installWebApi() {
|
|||||||
|
|
||||||
//获取截图缓存或者实时截图
|
//获取截图缓存或者实时截图
|
||||||
//http://127.0.0.1/index/api/getSnap?url=rtmp://127.0.0.1/record/robot.mp4&timeout_sec=10&expire_sec=3
|
//http://127.0.0.1/index/api/getSnap?url=rtmp://127.0.0.1/record/robot.mp4&timeout_sec=10&expire_sec=3
|
||||||
api_regist("/index/api/getSnap", [](API_ARGS2){
|
api_regist("/index/api/getSnap", [](API_ARGS_MAP_ASYNC){
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("url", "timeout_sec", "expire_sec");
|
CHECK_ARGS("url", "timeout_sec", "expire_sec");
|
||||||
GET_CONFIG(string, snap_root, API::kSnapRoot);
|
GET_CONFIG(string, snap_root, API::kSnapRoot);
|
||||||
@ -1051,7 +1022,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
////////////以下是注册的Hook API////////////
|
////////////以下是注册的Hook API////////////
|
||||||
api_regist("/index/hook/on_publish",[](API_ARGS1){
|
api_regist("/index/hook/on_publish",[](API_ARGS_MAP){
|
||||||
//开始推流事件
|
//开始推流事件
|
||||||
//转换成rtsp或rtmp
|
//转换成rtsp或rtmp
|
||||||
val["enableRtxp"] = true;
|
val["enableRtxp"] = true;
|
||||||
@ -1061,21 +1032,21 @@ void installWebApi() {
|
|||||||
val["enableMP4"] = false;
|
val["enableMP4"] = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_play",[](API_ARGS1){
|
api_regist("/index/hook/on_play",[](API_ARGS_MAP){
|
||||||
//开始播放事件
|
//开始播放事件
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_flow_report",[](API_ARGS1){
|
api_regist("/index/hook/on_flow_report",[](API_ARGS_MAP){
|
||||||
//流量统计hook api
|
//流量统计hook api
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_rtsp_realm",[](API_ARGS1){
|
api_regist("/index/hook/on_rtsp_realm",[](API_ARGS_MAP){
|
||||||
//rtsp是否需要鉴权,默认需要鉴权
|
//rtsp是否需要鉴权,默认需要鉴权
|
||||||
val["code"] = API::Success;
|
val["code"] = API::Success;
|
||||||
val["realm"] = "zlmediakit_reaml";
|
val["realm"] = "zlmediakit_reaml";
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_rtsp_auth",[](API_ARGS1){
|
api_regist("/index/hook/on_rtsp_auth",[](API_ARGS_MAP){
|
||||||
//rtsp鉴权密码,密码等于用户名
|
//rtsp鉴权密码,密码等于用户名
|
||||||
//rtsp可以有双重鉴权!后面还会触发on_play事件
|
//rtsp可以有双重鉴权!后面还会触发on_play事件
|
||||||
CHECK_ARGS("user_name");
|
CHECK_ARGS("user_name");
|
||||||
@ -1084,13 +1055,13 @@ void installWebApi() {
|
|||||||
val["passwd"] = allArgs["user_name"].data();
|
val["passwd"] = allArgs["user_name"].data();
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_stream_changed",[](API_ARGS1){
|
api_regist("/index/hook/on_stream_changed",[](API_ARGS_MAP){
|
||||||
//媒体注册或反注册事件
|
//媒体注册或反注册事件
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
api_regist("/index/hook/on_stream_not_found_ffmpeg",[](API_ARGS2){
|
api_regist("/index/hook/on_stream_not_found_ffmpeg",[](API_ARGS_MAP_ASYNC){
|
||||||
//媒体未找到事件,我们都及时拉流hks作为替代品,目的是为了测试按需拉流
|
//媒体未找到事件,我们都及时拉流hks作为替代品,目的是为了测试按需拉流
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("vhost","app","stream");
|
CHECK_ARGS("vhost","app","stream");
|
||||||
@ -1122,7 +1093,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
#endif//!defined(_WIN32)
|
#endif//!defined(_WIN32)
|
||||||
|
|
||||||
api_regist("/index/hook/on_stream_not_found",[](API_ARGS2){
|
api_regist("/index/hook/on_stream_not_found",[](API_ARGS_MAP_ASYNC){
|
||||||
//媒体未找到事件,我们都及时拉流hks作为替代品,目的是为了测试按需拉流
|
//媒体未找到事件,我们都及时拉流hks作为替代品,目的是为了测试按需拉流
|
||||||
CHECK_SECRET();
|
CHECK_SECRET();
|
||||||
CHECK_ARGS("vhost","app","stream");
|
CHECK_ARGS("vhost","app","stream");
|
||||||
@ -1146,15 +1117,15 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_record_mp4",[](API_ARGS1){
|
api_regist("/index/hook/on_record_mp4",[](API_ARGS_MAP){
|
||||||
//录制mp4分片完毕事件
|
//录制mp4分片完毕事件
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_shell_login",[](API_ARGS1){
|
api_regist("/index/hook/on_shell_login",[](API_ARGS_MAP){
|
||||||
//shell登录调试事件
|
//shell登录调试事件
|
||||||
});
|
});
|
||||||
|
|
||||||
api_regist("/index/hook/on_stream_none_reader",[](API_ARGS1){
|
api_regist("/index/hook/on_stream_none_reader",[](API_ARGS_MAP){
|
||||||
//无人观看流默认关闭
|
//无人观看流默认关闭
|
||||||
val["close"] = true;
|
val["close"] = true;
|
||||||
});
|
});
|
||||||
@ -1164,7 +1135,7 @@ void installWebApi() {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
api_regist("/index/hook/on_http_access",[](API_ARGS1){
|
api_regist("/index/hook/on_http_access",[](API_ARGS_MAP){
|
||||||
//在这里根据allArgs["params"](url参数)来判断该http客户端是否有权限访问该文件
|
//在这里根据allArgs["params"](url参数)来判断该http客户端是否有权限访问该文件
|
||||||
if(!checkAccess(allArgs["params"])){
|
if(!checkAccess(allArgs["params"])){
|
||||||
//无访问权限
|
//无访问权限
|
||||||
@ -1185,7 +1156,7 @@ void installWebApi() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
api_regist("/index/hook/on_server_started",[](API_ARGS1){
|
api_regist("/index/hook/on_server_started",[](API_ARGS_MAP){
|
||||||
//服务器重启报告
|
//服务器重启报告
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
99
server/WebApi.h
Normal file → Executable file
99
server/WebApi.h
Normal file → Executable file
@ -12,10 +12,21 @@
|
|||||||
#define ZLMEDIAKIT_WEBAPI_H
|
#define ZLMEDIAKIT_WEBAPI_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include "jsoncpp/json.h"
|
||||||
|
#include "Common/Parser.h"
|
||||||
|
#include "Network/Socket.h"
|
||||||
|
#include "Http/HttpSession.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace Json;
|
||||||
|
using namespace toolkit;
|
||||||
|
using namespace mediakit;
|
||||||
|
|
||||||
|
//配置文件路径
|
||||||
|
extern string g_ini_file;
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
////////////RTSP服务器配置///////////
|
////////////RTSP服务器配置///////////
|
||||||
namespace Rtsp {
|
namespace Rtsp {
|
||||||
extern const string kPort;
|
extern const string kPort;
|
||||||
@ -25,13 +36,93 @@ extern const string kPort;
|
|||||||
namespace Rtmp {
|
namespace Rtmp {
|
||||||
extern const string kPort;
|
extern const string kPort;
|
||||||
} //namespace RTMP
|
} //namespace RTMP
|
||||||
|
|
||||||
} // namespace mediakit
|
} // namespace mediakit
|
||||||
|
|
||||||
|
namespace API {
|
||||||
|
typedef enum {
|
||||||
|
NotFound = -500,//未找到
|
||||||
|
Exception = -400,//代码抛异常
|
||||||
|
InvalidArgs = -300,//参数不合法
|
||||||
|
SqlFailed = -200,//sql执行失败
|
||||||
|
AuthFailed = -100,//鉴权失败
|
||||||
|
OtherFailed = -1,//业务代码执行失败,
|
||||||
|
Success = 0//执行成功
|
||||||
|
} ApiErr;
|
||||||
|
}//namespace API
|
||||||
|
|
||||||
|
class ApiRetException: public std::runtime_error {
|
||||||
|
public:
|
||||||
|
ApiRetException(const char *str = "success" ,int code = API::Success):runtime_error(str){
|
||||||
|
_code = code;
|
||||||
|
}
|
||||||
|
~ApiRetException() = default;
|
||||||
|
int code(){ return _code; }
|
||||||
|
private:
|
||||||
|
int _code;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AuthException : public ApiRetException {
|
||||||
|
public:
|
||||||
|
AuthException(const char *str):ApiRetException(str,API::AuthFailed){}
|
||||||
|
~AuthException() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InvalidArgsException: public ApiRetException {
|
||||||
|
public:
|
||||||
|
InvalidArgsException(const char *str):ApiRetException(str,API::InvalidArgs){}
|
||||||
|
~InvalidArgsException() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SuccessException: public ApiRetException {
|
||||||
|
public:
|
||||||
|
SuccessException():ApiRetException("success",API::Success){}
|
||||||
|
~SuccessException() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
using ApiArgsType = map<string, variant, StrCaseCompare>;
|
||||||
|
|
||||||
|
#define API_ARGS_MAP SockInfo &sender, HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, ApiArgsType &allArgs, Json::Value &val
|
||||||
|
#define API_ARGS_MAP_ASYNC API_ARGS_MAP, const HttpSession::HttpResponseInvoker &invoker
|
||||||
|
#define API_ARGS_JSON SockInfo &sender, HttpSession::KeyValue &headerIn, HttpSession::KeyValue &headerOut, Json::Value &allArgs, Json::Value &val
|
||||||
|
#define API_ARGS_JSON_ASYNC API_ARGS_JSON, const HttpSession::HttpResponseInvoker &invoker
|
||||||
|
#define API_ARGS_VALUE sender, headerIn, headerOut, allArgs, val
|
||||||
|
|
||||||
|
//注册http请求参数是map<string, variant, StrCaseCompare>类型的http api
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_MAP)> &func);
|
||||||
|
//注册http请求参数是map<string, variant, StrCaseCompare>类型,但是可以异步回复的的http api
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_MAP_ASYNC)> &func);
|
||||||
|
|
||||||
|
//注册http请求参数是Json::Value类型的http api(可以支持多级嵌套的json参数对象)
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_JSON)> &func);
|
||||||
|
//注册http请求参数是Json::Value类型,但是可以异步回复的的http api
|
||||||
|
void api_regist(const string &api_path, const function<void(API_ARGS_JSON_ASYNC)> &func);
|
||||||
|
|
||||||
|
template<typename Args, typename First>
|
||||||
|
bool checkArgs(Args &&args, First &&first) {
|
||||||
|
return !args[first].empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Args, typename First, typename ...KeyTypes>
|
||||||
|
bool checkArgs(Args &&args, First &&first, KeyTypes &&...keys) {
|
||||||
|
return !args[first].empty() && checkArgs(std::forward<Args>(args), std::forward<KeyTypes>(keys)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查http参数是否为空的宏
|
||||||
|
#define CHECK_ARGS(...) \
|
||||||
|
if(!checkArgs(allArgs,##__VA_ARGS__)){ \
|
||||||
|
throw InvalidArgsException("缺少必要参数:" #__VA_ARGS__); \
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查http参数中是否附带secret密钥的宏,127.0.0.1的ip不检查密钥
|
||||||
|
#define CHECK_SECRET() \
|
||||||
|
if(sender.get_peer_ip() != "127.0.0.1"){ \
|
||||||
|
CHECK_ARGS("secret"); \
|
||||||
|
if(api_secret != allArgs["secret"]){ \
|
||||||
|
throw AuthException("secret错误"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
void installWebApi();
|
void installWebApi();
|
||||||
void unInstallWebApi();
|
void unInstallWebApi();
|
||||||
//配置文件路径
|
|
||||||
extern string g_ini_file;
|
|
||||||
|
|
||||||
#endif //ZLMEDIAKIT_WEBAPI_H
|
#endif //ZLMEDIAKIT_WEBAPI_H
|
||||||
|
26
server/WebHook.cpp
Normal file → Executable file
26
server/WebHook.cpp
Normal file → Executable file
@ -9,9 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "jsoncpp/json.h"
|
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
#include "Util/util.h"
|
|
||||||
#include "Util/onceToken.h"
|
#include "Util/onceToken.h"
|
||||||
#include "Util/NoticeCenter.h"
|
#include "Util/NoticeCenter.h"
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
@ -22,21 +20,9 @@
|
|||||||
#include "Http/HttpSession.h"
|
#include "Http/HttpSession.h"
|
||||||
#include "WebHook.h"
|
#include "WebHook.h"
|
||||||
|
|
||||||
using namespace Json;
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
using namespace mediakit;
|
using namespace mediakit;
|
||||||
|
|
||||||
|
|
||||||
//支持json或urlencoded方式传输参数
|
|
||||||
#define JSON_ARGS
|
|
||||||
|
|
||||||
#ifdef JSON_ARGS
|
|
||||||
typedef Value ArgsType;
|
|
||||||
#else
|
|
||||||
typedef HttpArgs ArgsType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace Hook {
|
namespace Hook {
|
||||||
#define HOOK_FIELD "hook."
|
#define HOOK_FIELD "hook."
|
||||||
|
|
||||||
@ -126,18 +112,18 @@ const char *getContentType(const HttpArgs &value){
|
|||||||
return "application/x-www-form-urlencoded";
|
return "application/x-www-form-urlencoded";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_http_hook(const string &url,const ArgsType &body,const function<void(const Value &,const string &)> &fun){
|
void do_http_hook(const string &url,const ArgsType &body,const function<void(const Value &,const string &)> &func){
|
||||||
GET_CONFIG(string, mediaServerId, General::kMediaServerId);
|
GET_CONFIG(string, mediaServerId, General::kMediaServerId);
|
||||||
const_cast<ArgsType &>(body)["mediaServerId"] = mediaServerId;
|
|
||||||
|
|
||||||
GET_CONFIG(float, hook_timeoutSec, Hook::kTimeoutSec);
|
GET_CONFIG(float, hook_timeoutSec, Hook::kTimeoutSec);
|
||||||
|
|
||||||
|
const_cast<ArgsType &>(body)["mediaServerId"] = mediaServerId;
|
||||||
HttpRequester::Ptr requester(new HttpRequester);
|
HttpRequester::Ptr requester(new HttpRequester);
|
||||||
requester->setMethod("POST");
|
requester->setMethod("POST");
|
||||||
auto bodyStr = to_string(body);
|
auto bodyStr = to_string(body);
|
||||||
requester->setBody(bodyStr);
|
requester->setBody(bodyStr);
|
||||||
requester->addHeader("Content-Type", getContentType(body));
|
requester->addHeader("Content-Type", getContentType(body));
|
||||||
std::shared_ptr<Ticker> pTicker(new Ticker);
|
std::shared_ptr<Ticker> pTicker(new Ticker);
|
||||||
requester->startRequester(url,[url,fun,bodyStr,requester,pTicker](const SockException &ex,
|
requester->startRequester(url, [url, func, bodyStr, requester, pTicker](const SockException &ex,
|
||||||
const string &status,
|
const string &status,
|
||||||
const HttpClient::HttpHeader &header,
|
const HttpClient::HttpHeader &header,
|
||||||
const string &strRecvBody) {
|
const string &strRecvBody) {
|
||||||
@ -145,8 +131,8 @@ static void do_http_hook(const string &url,const ArgsType &body,const function<v
|
|||||||
const_cast<HttpRequester::Ptr &>(requester).reset();
|
const_cast<HttpRequester::Ptr &>(requester).reset();
|
||||||
});
|
});
|
||||||
parse_http_response(ex,status,header,strRecvBody,[&](const Value &obj,const string &err){
|
parse_http_response(ex,status,header,strRecvBody,[&](const Value &obj,const string &err){
|
||||||
if(fun){
|
if (func) {
|
||||||
fun(obj,err);
|
func(obj, err);
|
||||||
}
|
}
|
||||||
if (!err.empty()) {
|
if (!err.empty()) {
|
||||||
WarnL << "hook " << url << " " << pTicker->elapsedTime() << "ms,failed" << err << ":" << bodyStr;
|
WarnL << "hook " << url << " " << pTicker->elapsedTime() << "ms,failed" << err << ":" << bodyStr;
|
||||||
|
21
server/WebHook.h
Normal file → Executable file
21
server/WebHook.h
Normal file → Executable file
@ -12,13 +12,32 @@
|
|||||||
#define ZLMEDIAKIT_WEBHOOK_H
|
#define ZLMEDIAKIT_WEBHOOK_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include "jsoncpp/json.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace Json;
|
||||||
|
|
||||||
|
//支持json或urlencoded方式传输参数
|
||||||
|
#define JSON_ARGS
|
||||||
|
|
||||||
|
#ifdef JSON_ARGS
|
||||||
|
typedef Value ArgsType;
|
||||||
|
#else
|
||||||
|
typedef HttpArgs ArgsType;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Hook {
|
namespace Hook {
|
||||||
|
//web hook回复最大超时时间
|
||||||
extern const string kTimeoutSec;
|
extern const string kTimeoutSec;
|
||||||
}//namespace Hook
|
}//namespace Hook
|
||||||
|
|
||||||
void installWebHook();
|
void installWebHook();
|
||||||
void unInstallWebHook();
|
void unInstallWebHook();
|
||||||
|
/**
|
||||||
|
* 触发http hook请求
|
||||||
|
* @param url 请求地址
|
||||||
|
* @param body 请求body
|
||||||
|
* @param func 回调
|
||||||
|
*/
|
||||||
|
void do_http_hook(const string &url, const ArgsType &body, const function<void(const Value &, const string &)> &func = nullptr);
|
||||||
#endif //ZLMEDIAKIT_WEBHOOK_H
|
#endif //ZLMEDIAKIT_WEBHOOK_H
|
||||||
|
Loading…
Reference in New Issue
Block a user