mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #319, support HTTP RAW API reload.
This commit is contained in:
parent
f74dc62046
commit
d921d59e57
9 changed files with 117 additions and 23 deletions
|
@ -121,6 +121,10 @@ http_api {
|
||||||
# whether enable crossdomain request.
|
# whether enable crossdomain request.
|
||||||
# default: on
|
# default: on
|
||||||
crossdomain on;
|
crossdomain on;
|
||||||
|
# whether enable the HTTP RAW API,
|
||||||
|
# which is more powerful api to change srs state and reload.
|
||||||
|
# default: off
|
||||||
|
raw_api off;
|
||||||
}
|
}
|
||||||
# embeded http server in srs.
|
# embeded http server in srs.
|
||||||
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
|
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
|
||||||
|
|
|
@ -1116,6 +1116,9 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// always support reload without additional code:
|
||||||
|
// crossdomain, raw_api
|
||||||
|
|
||||||
// merge config.
|
// merge config.
|
||||||
std::vector<ISrsReloadHandler*>::iterator it;
|
std::vector<ISrsReloadHandler*>::iterator it;
|
||||||
|
|
||||||
|
@ -1711,7 +1714,7 @@ int SrsConfig::check_config()
|
||||||
SrsConfDirective* conf = get_http_api();
|
SrsConfDirective* conf = get_http_api();
|
||||||
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
|
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
|
||||||
string n = conf->at(i)->name;
|
string n = conf->at(i)->name;
|
||||||
if (n != "enabled" && n != "listen" && n != "crossdomain") {
|
if (n != "enabled" && n != "listen" && n != "crossdomain" && n != "raw_api") {
|
||||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
srs_error("unsupported http_api directive %s, ret=%d", n.c_str(), ret);
|
srs_error("unsupported http_api directive %s, ret=%d", n.c_str(), ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -4293,6 +4296,23 @@ bool SrsConfig::get_http_api_crossdomain()
|
||||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsConfig::get_http_api_raw_api()
|
||||||
|
{
|
||||||
|
static bool DEFAULT = false;
|
||||||
|
|
||||||
|
SrsConfDirective* conf = get_http_api();
|
||||||
|
if (!conf) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("raw_api");
|
||||||
|
if (!conf || conf->arg0().empty()) {
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||||
|
}
|
||||||
|
|
||||||
bool SrsConfig::get_http_stream_enabled()
|
bool SrsConfig::get_http_stream_enabled()
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = get_http_stream();
|
SrsConfDirective* conf = get_http_stream();
|
||||||
|
|
|
@ -1036,6 +1036,10 @@ public:
|
||||||
* whether enable crossdomain for http api.
|
* whether enable crossdomain for http api.
|
||||||
*/
|
*/
|
||||||
virtual bool get_http_api_crossdomain();
|
virtual bool get_http_api_crossdomain();
|
||||||
|
/**
|
||||||
|
* whether enable the HTTP RAW API.
|
||||||
|
*/
|
||||||
|
virtual bool get_http_api_raw_api();
|
||||||
// http stream section
|
// http stream section
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,6 +42,8 @@ using namespace std;
|
||||||
#include <srs_app_config.hpp>
|
#include <srs_app_config.hpp>
|
||||||
#include <srs_app_source.hpp>
|
#include <srs_app_source.hpp>
|
||||||
#include <srs_app_http_conn.hpp>
|
#include <srs_app_http_conn.hpp>
|
||||||
|
#include <srs_kernel_consts.hpp>
|
||||||
|
#include <srs_app_server.hpp>
|
||||||
|
|
||||||
int srs_api_response_jsonp(ISrsHttpResponseWriter* w, string callback, string data)
|
int srs_api_response_jsonp(ISrsHttpResponseWriter* w, string callback, string data)
|
||||||
{
|
{
|
||||||
|
@ -205,6 +207,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||||
<< SRS_JFIELD_STR("vhosts", "manage all vhosts or specified vhost") << SRS_JFIELD_CONT
|
<< SRS_JFIELD_STR("vhosts", "manage all vhosts or specified vhost") << SRS_JFIELD_CONT
|
||||||
<< SRS_JFIELD_STR("streams", "manage all streams or specified stream") << SRS_JFIELD_CONT
|
<< SRS_JFIELD_STR("streams", "manage all streams or specified stream") << SRS_JFIELD_CONT
|
||||||
<< SRS_JFIELD_STR("clients", "manage all clients or specified client, default query top 10 clients") << SRS_JFIELD_CONT
|
<< SRS_JFIELD_STR("clients", "manage all clients or specified client, default query top 10 clients") << SRS_JFIELD_CONT
|
||||||
|
<< SRS_JFIELD_STR("raw", "raw api for srs, support CUID srs for instance the config") << SRS_JFIELD_CONT
|
||||||
<< SRS_JFIELD_ORG("tests", SRS_JOBJECT_START)
|
<< SRS_JFIELD_ORG("tests", SRS_JOBJECT_START)
|
||||||
<< SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT
|
<< SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT
|
||||||
<< SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT
|
<< SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT
|
||||||
|
@ -834,6 +837,44 @@ int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsGoApiRaw::SrsGoApiRaw(SrsServer* svr)
|
||||||
|
{
|
||||||
|
server = svr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsGoApiRaw::~SrsGoApiRaw()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// whether enabled the HTTP RAW API.
|
||||||
|
if (!_srs_config->get_http_api_raw_api()) {
|
||||||
|
ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED;
|
||||||
|
srs_warn("raw api disabled. ret=%d", ret);
|
||||||
|
return srs_api_response_code(w, r, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the rpc is required.
|
||||||
|
std::string rpc = r->query_get("rpc");
|
||||||
|
if (rpc.empty() || (rpc != "reload" && rpc != "config_query")) {
|
||||||
|
ret = ERROR_SYSTEM_CONFIG_RAW;
|
||||||
|
srs_error("raw api invalid rpc=%s. ret=%d", rpc.c_str(), ret);
|
||||||
|
return srs_api_response_code(w, r, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for rpc=reload, trigger the server to reload the config.
|
||||||
|
if (rpc == "reload") {
|
||||||
|
srs_trace("raw api trigger reload. ret=%d", ret);
|
||||||
|
server->on_signal(SRS_SIGNAL_RELOAD);
|
||||||
|
return srs_api_response_code(w, r, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
SrsGoApiError::SrsGoApiError()
|
SrsGoApiError::SrsGoApiError()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ class SrsStSocket;
|
||||||
class ISrsHttpMessage;
|
class ISrsHttpMessage;
|
||||||
class SrsHttpParser;
|
class SrsHttpParser;
|
||||||
class SrsHttpHandler;
|
class SrsHttpHandler;
|
||||||
|
class SrsServer;
|
||||||
|
|
||||||
#include <srs_app_st.hpp>
|
#include <srs_app_st.hpp>
|
||||||
#include <srs_app_conn.hpp>
|
#include <srs_app_conn.hpp>
|
||||||
|
@ -177,6 +178,17 @@ public:
|
||||||
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SrsGoApiRaw : public ISrsHttpHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SrsServer* server;
|
||||||
|
public:
|
||||||
|
SrsGoApiRaw(SrsServer* svr);
|
||||||
|
virtual ~SrsGoApiRaw();
|
||||||
|
public:
|
||||||
|
virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||||
|
};
|
||||||
|
|
||||||
class SrsGoApiError : public ISrsHttpHandler
|
class SrsGoApiError : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -48,15 +48,7 @@ using namespace std;
|
||||||
#include <srs_app_statistic.hpp>
|
#include <srs_app_statistic.hpp>
|
||||||
#include <srs_app_caster_flv.hpp>
|
#include <srs_app_caster_flv.hpp>
|
||||||
#include <srs_core_mem_watch.hpp>
|
#include <srs_core_mem_watch.hpp>
|
||||||
|
#include <srs_kernel_consts.hpp>
|
||||||
// signal defines.
|
|
||||||
// reload the config file and apply new config.
|
|
||||||
#define SRS_SIGNAL_RELOAD SIGHUP
|
|
||||||
// terminate the srs with dispose to detect memory leak for gmp.
|
|
||||||
#define SRS_SIGNAL_DISPOSE SIGUSR2
|
|
||||||
// persistence the config in memory to config file.
|
|
||||||
// @see https://github.com/simple-rtmp-server/srs/issues/319#issuecomment-134993922
|
|
||||||
#define SRS_SIGNAL_PERSISTENCE_CONFIG SIGUSR1
|
|
||||||
|
|
||||||
// system interval in ms,
|
// system interval in ms,
|
||||||
// all resolution times should be times togother,
|
// all resolution times should be times togother,
|
||||||
|
@ -430,7 +422,7 @@ int SrsSignalManager::start()
|
||||||
sa.sa_handler = SrsSignalManager::sig_catcher;
|
sa.sa_handler = SrsSignalManager::sig_catcher;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sa.sa_flags = 0;
|
sa.sa_flags = 0;
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
sigaction(SRS_SIGNAL_GRACEFULLY_QUIT, &sa, NULL);
|
||||||
|
|
||||||
sa.sa_handler = SrsSignalManager::sig_catcher;
|
sa.sa_handler = SrsSignalManager::sig_catcher;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
|
@ -824,6 +816,9 @@ int SrsServer::http_handle()
|
||||||
if ((ret = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != ERROR_SUCCESS) {
|
if ((ret = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/raw", new SrsGoApiRaw(this))) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// test the request info.
|
// test the request info.
|
||||||
if ((ret = http_api_mux->handle("/api/v1/tests/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {
|
if ((ret = http_api_mux->handle("/api/v1/tests/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {
|
||||||
|
@ -927,7 +922,7 @@ void SrsServer::on_signal(int signo)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signo == SIGINT || signo == SIGUSR2) {
|
if (signo == SIGINT || signo == SRS_SIGNAL_DISPOSE) {
|
||||||
#ifdef SRS_AUTO_GPERF_MC
|
#ifdef SRS_AUTO_GPERF_MC
|
||||||
srs_trace("gmc is on, main cycle will terminate normally.");
|
srs_trace("gmc is on, main cycle will terminate normally.");
|
||||||
signal_gmc_stop = true;
|
signal_gmc_stop = true;
|
||||||
|
@ -941,7 +936,7 @@ void SrsServer::on_signal(int signo)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signo == SIGTERM && !signal_gracefully_quit) {
|
if (signo == SRS_SIGNAL_GRACEFULLY_QUIT && !signal_gracefully_quit) {
|
||||||
srs_trace("user terminate program, gracefully quit.");
|
srs_trace("user terminate program, gracefully quit.");
|
||||||
signal_gracefully_quit = true;
|
signal_gracefully_quit = true;
|
||||||
return;
|
return;
|
||||||
|
@ -982,7 +977,7 @@ int SrsServer::do_cycle()
|
||||||
for (int i = 0; i < temp_max; i++) {
|
for (int i = 0; i < temp_max; i++) {
|
||||||
st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
|
st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
|
||||||
|
|
||||||
// gracefully quit for SIGINT or SIGTERM.
|
// gracefully quit for SIGINT or SIGTERM(SRS_SIGNAL_GRACEFULLY_QUIT).
|
||||||
if (signal_gracefully_quit) {
|
if (signal_gracefully_quit) {
|
||||||
srs_trace("cleanup for gracefully terminate.");
|
srs_trace("cleanup for gracefully terminate.");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -319,15 +319,19 @@ public:
|
||||||
// server utilities.
|
// server utilities.
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* callback for signal manager got a signal.
|
* callback for signal manager got a signal.
|
||||||
* the signal manager convert signal to io message,
|
* the signal manager convert signal to io message,
|
||||||
* whatever, we will got the signo like the orignal signal(int signo) handler.
|
* whatever, we will got the signo like the orignal signal(int signo) handler.
|
||||||
* @remark, direclty exit for SIGTERM.
|
* @param signo the signal number from user, where:
|
||||||
* @remark, do reload for SIGNAL_RELOAD.
|
* SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit.
|
||||||
* @remark, for SIGINT and SIGUSR2:
|
* SRS_SIGNAL_DISPOSE, the SIGUSR2, dispose for gmc.
|
||||||
* no gmc, directly exit.
|
* SRS_SIGNAL_PERSISTENCE_CONFIG, the SIGUSR1, persistence config to file.
|
||||||
* for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc.
|
* SRS_SIGNAL_RELOAD, the SIGHUP, reload the config.
|
||||||
*/
|
* @remark, for SIGINT and SRS_SIGNAL_DISPOSE:
|
||||||
|
* no gmc, directly exit.
|
||||||
|
* for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc.
|
||||||
|
* @remark, maybe the HTTP RAW API will trigger the on_signal() also.
|
||||||
|
*/
|
||||||
virtual void on_signal(int signo);
|
virtual void on_signal(int signo);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -134,6 +134,17 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define SRS_CONSTS_NULL_FILE "/dev/null"
|
#define SRS_CONSTS_NULL_FILE "/dev/null"
|
||||||
#define SRS_CONSTS_LOCALHOST "127.0.0.1"
|
#define SRS_CONSTS_LOCALHOST "127.0.0.1"
|
||||||
|
|
||||||
|
// signal defines.
|
||||||
|
// reload the config file and apply new config.
|
||||||
|
#define SRS_SIGNAL_RELOAD SIGHUP
|
||||||
|
// terminate the srs with dispose to detect memory leak for gmc.
|
||||||
|
#define SRS_SIGNAL_DISPOSE SIGUSR2
|
||||||
|
// persistence the config in memory to config file.
|
||||||
|
// @see https://github.com/simple-rtmp-server/srs/issues/319#issuecomment-134993922
|
||||||
|
#define SRS_SIGNAL_PERSISTENCE_CONFIG SIGUSR1
|
||||||
|
// srs should gracefully quit, do dispose then exit.
|
||||||
|
#define SRS_SIGNAL_GRACEFULLY_QUIT SIGTERM
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -98,6 +98,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define ERROR_SYSTEM_CREATE_DIR 1057
|
#define ERROR_SYSTEM_CREATE_DIR 1057
|
||||||
#define ERROR_SYSTEM_KILL 1058
|
#define ERROR_SYSTEM_KILL 1058
|
||||||
#define ERROR_SYSTEM_CONFIG_PERSISTENCE 1059
|
#define ERROR_SYSTEM_CONFIG_PERSISTENCE 1059
|
||||||
|
#define ERROR_SYSTEM_CONFIG_RAW 1060
|
||||||
|
#define ERROR_SYSTEM_CONFIG_RAW_DISABLED 1061
|
||||||
|
#define ERROR_SYSTEM_CONFIG_RAW_PARAMS 1062
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// RTMP protocol error.
|
// RTMP protocol error.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue