You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
8.6KB

  1. /*
  2. * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef ZLMEDIAKIT_WEBAPI_H
  11. #define ZLMEDIAKIT_WEBAPI_H
  12. #include <string>
  13. #include <functional>
  14. #include "json/json.h"
  15. #include "Common/Parser.h"
  16. #include "Network/Socket.h"
  17. #include "Http/HttpSession.h"
  18. #include "Common/MultiMediaSourceMuxer.h"
  19. //配置文件路径
  20. extern std::string g_ini_file;
  21. namespace mediakit {
  22. ////////////RTSP服务器配置///////////
  23. namespace Rtsp {
  24. extern const std::string kPort;
  25. } //namespace Rtsp
  26. ////////////RTMP服务器配置///////////
  27. namespace Rtmp {
  28. extern const std::string kPort;
  29. } //namespace RTMP
  30. } // namespace mediakit
  31. namespace API {
  32. typedef enum {
  33. NotFound = -500,//未找到
  34. Exception = -400,//代码抛异常
  35. InvalidArgs = -300,//参数不合法
  36. SqlFailed = -200,//sql执行失败
  37. AuthFailed = -100,//鉴权失败
  38. OtherFailed = -1,//业务代码执行失败,
  39. Success = 0//执行成功
  40. } ApiErr;
  41. }//namespace API
  42. class ApiRetException: public std::runtime_error {
  43. public:
  44. ApiRetException(const char *str = "success" ,int code = API::Success):runtime_error(str){
  45. _code = code;
  46. }
  47. ~ApiRetException() = default;
  48. int code(){ return _code; }
  49. private:
  50. int _code;
  51. };
  52. class AuthException : public ApiRetException {
  53. public:
  54. AuthException(const char *str):ApiRetException(str,API::AuthFailed){}
  55. ~AuthException() = default;
  56. };
  57. class InvalidArgsException: public ApiRetException {
  58. public:
  59. InvalidArgsException(const char *str):ApiRetException(str,API::InvalidArgs){}
  60. ~InvalidArgsException() = default;
  61. };
  62. class SuccessException: public ApiRetException {
  63. public:
  64. SuccessException():ApiRetException("success",API::Success){}
  65. ~SuccessException() = default;
  66. };
  67. using ApiArgsType = std::map<std::string, std::string, mediakit::StrCaseCompare>;
  68. template<typename Args, typename First>
  69. std::string getValue(Args &args, const First &first) {
  70. return args[first];
  71. }
  72. template<typename First>
  73. std::string getValue(Json::Value &args, const First &first) {
  74. return args[first].asString();
  75. }
  76. template<typename First>
  77. std::string getValue(std::string &args, const First &first) {
  78. return "";
  79. }
  80. template<typename First>
  81. std::string getValue(const mediakit::Parser &parser, const First &first) {
  82. auto ret = parser.getUrlArgs()[first];
  83. if (!ret.empty()) {
  84. return ret;
  85. }
  86. return parser.getHeader()[first];
  87. }
  88. template<typename First>
  89. std::string getValue(mediakit::Parser &parser, const First &first) {
  90. return getValue((const mediakit::Parser &) parser, first);
  91. }
  92. template<typename Args, typename First>
  93. std::string getValue(const mediakit::Parser &parser, Args &args, const First &first) {
  94. auto ret = getValue(args, first);
  95. if (!ret.empty()) {
  96. return ret;
  97. }
  98. return getValue(parser, first);
  99. }
  100. template<typename Args>
  101. class HttpAllArgs {
  102. public:
  103. HttpAllArgs(const mediakit::Parser &parser, Args &args) {
  104. _get_args = [&args]() {
  105. return (void *) &args;
  106. };
  107. _get_parser = [&parser]() -> const mediakit::Parser & {
  108. return parser;
  109. };
  110. _get_value = [](HttpAllArgs &that, const std::string &key) {
  111. return getValue(that.getParser(), that.getArgs(), key);
  112. };
  113. _clone = [&](HttpAllArgs &that) {
  114. that._get_args = [args]() {
  115. return (void *) &args;
  116. };
  117. that._get_parser = [parser]() -> const mediakit::Parser & {
  118. return parser;
  119. };
  120. that._get_value = [](HttpAllArgs &that, const std::string &key) {
  121. return getValue(that.getParser(), that.getArgs(), key);
  122. };
  123. that._cache_able = true;
  124. };
  125. }
  126. HttpAllArgs(const HttpAllArgs &that) {
  127. if (that._cache_able) {
  128. _get_args = that._get_args;
  129. _get_parser = that._get_parser;
  130. _get_value = that._get_value;
  131. _cache_able = true;
  132. } else {
  133. that._clone(*this);
  134. }
  135. }
  136. ~HttpAllArgs() = default;
  137. template<typename Key>
  138. toolkit::variant operator[](const Key &key) const {
  139. return (toolkit::variant)_get_value(*(HttpAllArgs*)this, key);
  140. }
  141. const mediakit::Parser &getParser() const {
  142. return _get_parser();
  143. }
  144. Args &getArgs() {
  145. return *((Args *) _get_args());
  146. }
  147. const Args &getArgs() const {
  148. return *((Args *) _get_args());
  149. }
  150. private:
  151. bool _cache_able = false;
  152. std::function<void *() > _get_args;
  153. std::function<const mediakit::Parser &() > _get_parser;
  154. std::function<std::string(HttpAllArgs &that, const std::string &key)> _get_value;
  155. std::function<void(HttpAllArgs &that) > _clone;
  156. };
  157. #define API_ARGS_MAP toolkit::SockInfo &sender, mediakit::HttpSession::KeyValue &headerOut, const HttpAllArgs<ApiArgsType> &allArgs, Json::Value &val
  158. #define API_ARGS_MAP_ASYNC API_ARGS_MAP, const mediakit::HttpSession::HttpResponseInvoker &invoker
  159. #define API_ARGS_JSON toolkit::SockInfo &sender, mediakit::HttpSession::KeyValue &headerOut, const HttpAllArgs<Json::Value> &allArgs, Json::Value &val
  160. #define API_ARGS_JSON_ASYNC API_ARGS_JSON, const mediakit::HttpSession::HttpResponseInvoker &invoker
  161. #define API_ARGS_STRING toolkit::SockInfo &sender, mediakit::HttpSession::KeyValue &headerOut, const HttpAllArgs<std::string> &allArgs, Json::Value &val
  162. #define API_ARGS_STRING_ASYNC API_ARGS_STRING, const mediakit::HttpSession::HttpResponseInvoker &invoker
  163. #define API_ARGS_VALUE sender, headerOut, allArgs, val
  164. //注册http请求参数是map<string, variant, StrCaseCompare>类型的http api
  165. void api_regist(const std::string &api_path, const std::function<void(API_ARGS_MAP)> &func);
  166. //注册http请求参数是map<string, variant, StrCaseCompare>类型,但是可以异步回复的的http api
  167. void api_regist(const std::string &api_path, const std::function<void(API_ARGS_MAP_ASYNC)> &func);
  168. //注册http请求参数是Json::Value类型的http api(可以支持多级嵌套的json参数对象)
  169. void api_regist(const std::string &api_path, const std::function<void(API_ARGS_JSON)> &func);
  170. //注册http请求参数是Json::Value类型,但是可以异步回复的的http api
  171. void api_regist(const std::string &api_path, const std::function<void(API_ARGS_JSON_ASYNC)> &func);
  172. //注册http请求参数是http原始请求信息的http api
  173. void api_regist(const std::string &api_path, const std::function<void(API_ARGS_STRING)> &func);
  174. //注册http请求参数是http原始请求信息的异步回复的http api
  175. void api_regist(const std::string &api_path, const std::function<void(API_ARGS_STRING_ASYNC)> &func);
  176. template<typename Args, typename First>
  177. bool checkArgs(Args &args, const First &first) {
  178. return !args[first].empty();
  179. }
  180. template<typename Args, typename First, typename ...KeyTypes>
  181. bool checkArgs(Args &args, const First &first, const KeyTypes &...keys) {
  182. return checkArgs(args, first) && checkArgs(args, keys...);
  183. }
  184. //检查http url中或body中或http header参数是否为空的宏
  185. #define CHECK_ARGS(...) \
  186. if(!checkArgs(allArgs,##__VA_ARGS__)){ \
  187. throw InvalidArgsException("缺少必要参数:" #__VA_ARGS__); \
  188. }
  189. //检查http参数中是否附带secret密钥的宏,127.0.0.1的ip不检查密钥
  190. #define CHECK_SECRET() \
  191. if(sender.get_peer_ip() != "127.0.0.1"){ \
  192. CHECK_ARGS("secret"); \
  193. if(api_secret != allArgs["secret"]){ \
  194. throw AuthException("secret错误"); \
  195. } \
  196. }
  197. void installWebApi();
  198. void unInstallWebApi();
  199. 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);
  200. 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);
  201. bool closeRtpServer(const std::string &stream_id);
  202. Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
  203. void getStatisticJson(const std::function<void(Json::Value &val)> &cb);
  204. void addStreamProxy(const std::string &vhost, const std::string &app, const std::string &stream, const std::string &url, int retry_count,
  205. const mediakit::ProtocolOption &option, int rtp_type, float timeout_sec,
  206. const std::function<void(const toolkit::SockException &ex, const std::string &key)> &cb);
  207. #endif //ZLMEDIAKIT_WEBAPI_H