2019-08-08 19:01:45 +08:00
|
|
|
|
/*
|
2020-04-04 20:30:09 +08:00
|
|
|
|
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
2019-06-11 09:25:54 +08:00
|
|
|
|
*
|
2021-01-17 18:31:50 +08:00
|
|
|
|
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
|
2019-06-11 09:25:54 +08:00
|
|
|
|
*
|
2020-04-04 20:30:09 +08:00
|
|
|
|
* Use of this source code is governed by MIT license that can be found in the
|
|
|
|
|
* LICENSE file in the root of the source tree. All contributing project authors
|
|
|
|
|
* may be found in the AUTHORS file in the root of the source tree.
|
2019-06-11 09:25:54 +08:00
|
|
|
|
*/
|
2019-06-06 18:28:33 +08:00
|
|
|
|
|
|
|
|
|
#ifndef ZLMEDIAKIT_WEBAPI_H
|
|
|
|
|
#define ZLMEDIAKIT_WEBAPI_H
|
|
|
|
|
|
2019-06-19 10:32:54 +08:00
|
|
|
|
#include <string>
|
2020-12-27 22:14:59 +08:00
|
|
|
|
#include <functional>
|
2022-10-16 21:10:18 +08:00
|
|
|
|
#include "json/json.h"
|
2020-12-27 22:14:59 +08:00
|
|
|
|
#include "Common/Parser.h"
|
|
|
|
|
#include "Network/Socket.h"
|
|
|
|
|
#include "Http/HttpSession.h"
|
2022-03-12 13:19:21 +08:00
|
|
|
|
#include "Common/MultiMediaSourceMuxer.h"
|
2020-12-27 22:14:59 +08:00
|
|
|
|
|
|
|
|
|
//配置文件路径
|
2022-02-02 20:34:50 +08:00
|
|
|
|
extern std::string g_ini_file;
|
2019-06-19 10:32:54 +08:00
|
|
|
|
|
2020-12-27 22:14:59 +08:00
|
|
|
|
namespace mediakit {
|
2019-06-06 18:28:33 +08:00
|
|
|
|
////////////RTSP服务器配置///////////
|
|
|
|
|
namespace Rtsp {
|
2022-02-02 20:34:50 +08:00
|
|
|
|
extern const std::string kPort;
|
2019-06-06 18:28:33 +08:00
|
|
|
|
} //namespace Rtsp
|
|
|
|
|
|
|
|
|
|
////////////RTMP服务器配置///////////
|
|
|
|
|
namespace Rtmp {
|
2022-02-02 20:34:50 +08:00
|
|
|
|
extern const std::string kPort;
|
2019-06-06 18:28:33 +08:00
|
|
|
|
} //namespace RTMP
|
|
|
|
|
} // namespace mediakit
|
|
|
|
|
|
2020-12-27 22:14:59 +08:00
|
|
|
|
namespace API {
|
|
|
|
|
typedef enum {
|
|
|
|
|
NotFound = -500,//未找到
|
|
|
|
|
Exception = -400,//代码抛异常
|
|
|
|
|
InvalidArgs = -300,//参数不合法
|
|
|
|
|
SqlFailed = -200,//sql执行失败
|
|
|
|
|
AuthFailed = -100,//鉴权失败
|
|
|
|
|
OtherFailed = -1,//业务代码执行失败,
|
|
|
|
|
Success = 0//执行成功
|
|
|
|
|
} ApiErr;
|
2023-07-22 17:30:20 +08:00
|
|
|
|
|
|
|
|
|
extern const std::string kSecret;
|
2020-12-27 22:14:59 +08:00
|
|
|
|
}//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;
|
|
|
|
|
};
|
|
|
|
|
|
2022-02-02 20:34:50 +08:00
|
|
|
|
using ApiArgsType = std::map<std::string, std::string, mediakit::StrCaseCompare>;
|
2020-12-27 22:14:59 +08:00
|
|
|
|
|
2021-08-12 16:07:31 +08:00
|
|
|
|
template<typename Args, typename First>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::string getValue(Args &args, const First &first) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return args[first];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename First>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::string getValue(Json::Value &args, const First &first) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return args[first].asString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename First>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::string getValue(std::string &args, const First &first) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename First>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::string getValue(const mediakit::Parser &parser, const First &first) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
auto ret = parser.getUrlArgs()[first];
|
|
|
|
|
if (!ret.empty()) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
return parser.getHeader()[first];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename First>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::string getValue(mediakit::Parser &parser, const First &first) {
|
|
|
|
|
return getValue((const mediakit::Parser &) parser, first);
|
2021-08-12 16:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Args, typename First>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::string getValue(const mediakit::Parser &parser, Args &args, const First &first) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
auto ret = getValue(args, first);
|
|
|
|
|
if (!ret.empty()) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
return getValue(parser, first);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Args>
|
|
|
|
|
class HttpAllArgs {
|
|
|
|
|
public:
|
2022-02-02 20:34:50 +08:00
|
|
|
|
HttpAllArgs(const mediakit::Parser &parser, Args &args) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
_get_args = [&args]() {
|
|
|
|
|
return (void *) &args;
|
|
|
|
|
};
|
2022-02-02 20:34:50 +08:00
|
|
|
|
_get_parser = [&parser]() -> const mediakit::Parser & {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return parser;
|
|
|
|
|
};
|
2022-02-02 20:34:50 +08:00
|
|
|
|
_get_value = [](HttpAllArgs &that, const std::string &key) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return getValue(that.getParser(), that.getArgs(), key);
|
|
|
|
|
};
|
|
|
|
|
_clone = [&](HttpAllArgs &that) {
|
|
|
|
|
that._get_args = [args]() {
|
|
|
|
|
return (void *) &args;
|
|
|
|
|
};
|
2022-02-02 20:34:50 +08:00
|
|
|
|
that._get_parser = [parser]() -> const mediakit::Parser & {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return parser;
|
|
|
|
|
};
|
2022-02-02 20:34:50 +08:00
|
|
|
|
that._get_value = [](HttpAllArgs &that, const std::string &key) {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return getValue(that.getParser(), that.getArgs(), key);
|
|
|
|
|
};
|
|
|
|
|
that._cache_able = true;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HttpAllArgs(const HttpAllArgs &that) {
|
|
|
|
|
if (that._cache_able) {
|
|
|
|
|
_get_args = that._get_args;
|
|
|
|
|
_get_parser = that._get_parser;
|
|
|
|
|
_get_value = that._get_value;
|
2021-08-18 20:37:10 +08:00
|
|
|
|
_cache_able = true;
|
2021-08-12 16:07:31 +08:00
|
|
|
|
} else {
|
|
|
|
|
that._clone(*this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~HttpAllArgs() = default;
|
|
|
|
|
|
|
|
|
|
template<typename Key>
|
2022-02-02 20:34:50 +08:00
|
|
|
|
toolkit::variant operator[](const Key &key) const {
|
|
|
|
|
return (toolkit::variant)_get_value(*(HttpAllArgs*)this, key);
|
2021-08-12 16:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-02 20:34:50 +08:00
|
|
|
|
const mediakit::Parser &getParser() const {
|
2021-08-12 16:07:31 +08:00
|
|
|
|
return _get_parser();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Args &getArgs() {
|
|
|
|
|
return *((Args *) _get_args());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Args &getArgs() const {
|
|
|
|
|
return *((Args *) _get_args());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool _cache_able = false;
|
2022-02-02 20:34:50 +08:00
|
|
|
|
std::function<void *() > _get_args;
|
|
|
|
|
std::function<const mediakit::Parser &() > _get_parser;
|
|
|
|
|
std::function<std::string(HttpAllArgs &that, const std::string &key)> _get_value;
|
|
|
|
|
std::function<void(HttpAllArgs &that) > _clone;
|
2021-08-12 16:07:31 +08:00
|
|
|
|
};
|
|
|
|
|
|
2022-02-02 20:34:50 +08:00
|
|
|
|
#define API_ARGS_MAP toolkit::SockInfo &sender, mediakit::HttpSession::KeyValue &headerOut, const HttpAllArgs<ApiArgsType> &allArgs, Json::Value &val
|
|
|
|
|
#define API_ARGS_MAP_ASYNC API_ARGS_MAP, const mediakit::HttpSession::HttpResponseInvoker &invoker
|
|
|
|
|
#define API_ARGS_JSON toolkit::SockInfo &sender, mediakit::HttpSession::KeyValue &headerOut, const HttpAllArgs<Json::Value> &allArgs, Json::Value &val
|
|
|
|
|
#define API_ARGS_JSON_ASYNC API_ARGS_JSON, const mediakit::HttpSession::HttpResponseInvoker &invoker
|
|
|
|
|
#define API_ARGS_STRING toolkit::SockInfo &sender, mediakit::HttpSession::KeyValue &headerOut, const HttpAllArgs<std::string> &allArgs, Json::Value &val
|
|
|
|
|
#define API_ARGS_STRING_ASYNC API_ARGS_STRING, const mediakit::HttpSession::HttpResponseInvoker &invoker
|
2021-08-12 16:07:31 +08:00
|
|
|
|
#define API_ARGS_VALUE sender, headerOut, allArgs, val
|
2020-12-27 22:14:59 +08:00
|
|
|
|
|
|
|
|
|
//注册http请求参数是map<string, variant, StrCaseCompare>类型的http api
|
2022-02-02 20:34:50 +08:00
|
|
|
|
void api_regist(const std::string &api_path, const std::function<void(API_ARGS_MAP)> &func);
|
2020-12-27 22:14:59 +08:00
|
|
|
|
//注册http请求参数是map<string, variant, StrCaseCompare>类型,但是可以异步回复的的http api
|
2022-02-02 20:34:50 +08:00
|
|
|
|
void api_regist(const std::string &api_path, const std::function<void(API_ARGS_MAP_ASYNC)> &func);
|
2020-12-27 22:14:59 +08:00
|
|
|
|
|
|
|
|
|
//注册http请求参数是Json::Value类型的http api(可以支持多级嵌套的json参数对象)
|
2022-02-02 20:34:50 +08:00
|
|
|
|
void api_regist(const std::string &api_path, const std::function<void(API_ARGS_JSON)> &func);
|
2020-12-27 22:14:59 +08:00
|
|
|
|
//注册http请求参数是Json::Value类型,但是可以异步回复的的http api
|
2022-02-02 20:34:50 +08:00
|
|
|
|
void api_regist(const std::string &api_path, const std::function<void(API_ARGS_JSON_ASYNC)> &func);
|
2020-12-27 22:14:59 +08:00
|
|
|
|
|
2021-03-31 17:15:26 +08:00
|
|
|
|
//注册http请求参数是http原始请求信息的http api
|
2022-02-02 20:34:50 +08:00
|
|
|
|
void api_regist(const std::string &api_path, const std::function<void(API_ARGS_STRING)> &func);
|
2021-03-31 17:15:26 +08:00
|
|
|
|
//注册http请求参数是http原始请求信息的异步回复的http api
|
2022-02-02 20:34:50 +08:00
|
|
|
|
void api_regist(const std::string &api_path, const std::function<void(API_ARGS_STRING_ASYNC)> &func);
|
2021-03-31 17:15:26 +08:00
|
|
|
|
|
2020-12-27 22:14:59 +08:00
|
|
|
|
template<typename Args, typename First>
|
2021-08-12 16:07:31 +08:00
|
|
|
|
bool checkArgs(Args &args, const First &first) {
|
2020-12-27 22:14:59 +08:00
|
|
|
|
return !args[first].empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Args, typename First, typename ...KeyTypes>
|
2021-08-12 16:07:31 +08:00
|
|
|
|
bool checkArgs(Args &args, const First &first, const KeyTypes &...keys) {
|
|
|
|
|
return checkArgs(args, first) && checkArgs(args, keys...);
|
2021-03-31 17:15:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-12 16:07:31 +08:00
|
|
|
|
//检查http url中或body中或http header参数是否为空的宏
|
2020-12-27 22:14:59 +08:00
|
|
|
|
#define CHECK_ARGS(...) \
|
|
|
|
|
if(!checkArgs(allArgs,##__VA_ARGS__)){ \
|
|
|
|
|
throw InvalidArgsException("缺少必要参数:" #__VA_ARGS__); \
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-26 17:18:33 +08:00
|
|
|
|
// 检查http参数中是否附带secret密钥的宏,127.0.0.1的ip不检查密钥
|
|
|
|
|
// 同时检测是否在ip白名单内
|
2020-12-27 22:14:59 +08:00
|
|
|
|
#define CHECK_SECRET() \
|
2023-07-26 17:18:33 +08:00
|
|
|
|
do { \
|
|
|
|
|
auto ip = sender.get_peer_ip(); \
|
|
|
|
|
if (!HttpFileManager::isIPAllowed(ip)) { \
|
|
|
|
|
throw AuthException("Your ip is not allowed to access the service."); \
|
2020-12-27 22:14:59 +08:00
|
|
|
|
} \
|
2023-07-27 15:42:53 +08:00
|
|
|
|
CHECK_ARGS("secret"); \
|
|
|
|
|
if (api_secret != allArgs["secret"]) { \
|
|
|
|
|
throw AuthException("secret错误"); \
|
2023-07-26 17:18:33 +08:00
|
|
|
|
} \
|
|
|
|
|
} while(false);
|
2019-06-06 18:28:33 +08:00
|
|
|
|
|
2019-06-24 14:58:56 +08:00
|
|
|
|
void installWebApi();
|
|
|
|
|
void unInstallWebApi();
|
2022-06-22 10:31:53 +08:00
|
|
|
|
|
2023-05-08 15:27:43 +08:00
|
|
|
|
#if defined(ENABLE_RTPPROXY)
|
2023-11-09 11:26:13 +08:00
|
|
|
|
uint16_t openRtpServer(uint16_t local_port, const std::string &stream_id, int tcp_mode, const std::string &local_ip, bool re_use_port, uint32_t ssrc, bool only_audio, bool multiplex=false);
|
2022-09-09 10:56:28 +08:00
|
|
|
|
void connectRtpServer(const std::string &stream_id, const std::string &dst_url, uint16_t dst_port, const std::function<void(const toolkit::SockException &ex)> &cb);
|
2022-06-22 10:31:53 +08:00
|
|
|
|
bool closeRtpServer(const std::string &stream_id);
|
2023-05-08 15:27:43 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2022-02-02 20:34:50 +08:00
|
|
|
|
Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
|
|
|
|
|
void getStatisticJson(const std::function<void(Json::Value &val)> &cb);
|
|
|
|
|
void addStreamProxy(const std::string &vhost, const std::string &app, const std::string &stream, const std::string &url, int retry_count,
|
2023-12-01 14:33:07 +08:00
|
|
|
|
const mediakit::ProtocolOption &option, int rtp_type, float timeout_sec, const toolkit::mINI &args,
|
2022-02-02 20:34:50 +08:00
|
|
|
|
const std::function<void(const toolkit::SockException &ex, const std::string &key)> &cb);
|
2019-06-06 18:28:33 +08:00
|
|
|
|
#endif //ZLMEDIAKIT_WEBAPI_H
|