Skip to content

Commit

Permalink
for #319, support HTTP RAW API reload.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Aug 27, 2015
1 parent f74dc62 commit d921d59
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 23 deletions.
4 changes: 4 additions & 0 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ http_api {
# whether enable crossdomain request.
# default: 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.
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
Expand Down
22 changes: 21 additions & 1 deletion trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,9 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root)
{
int ret = ERROR_SUCCESS;

// always support reload without additional code:
// crossdomain, raw_api

// merge config.
std::vector<ISrsReloadHandler*>::iterator it;

Expand Down Expand Up @@ -1711,7 +1714,7 @@ int SrsConfig::check_config()
SrsConfDirective* conf = get_http_api();
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
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;
srs_error("unsupported http_api directive %s, ret=%d", n.c_str(), ret);
return ret;
Expand Down Expand Up @@ -4293,6 +4296,23 @@ bool SrsConfig::get_http_api_crossdomain()
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()
{
SrsConfDirective* conf = get_http_stream();
Expand Down
4 changes: 4 additions & 0 deletions trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,10 @@ class SrsConfig
* whether enable crossdomain for http api.
*/
virtual bool get_http_api_crossdomain();
/**
* whether enable the HTTP RAW API.
*/
virtual bool get_http_api_raw_api();
// http stream section
private:
/**
Expand Down
41 changes: 41 additions & 0 deletions trunk/src/app/srs_app_http_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ using namespace std;
#include <srs_app_config.hpp>
#include <srs_app_source.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)
{
Expand Down Expand Up @@ -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("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("raw", "raw api for srs, support CUID srs for instance the config") << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("tests", SRS_JOBJECT_START)
<< SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT
<< SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT
Expand Down Expand Up @@ -834,6 +837,44 @@ int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
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()
{
}
Expand Down
12 changes: 12 additions & 0 deletions trunk/src/app/srs_app_http_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class SrsStSocket;
class ISrsHttpMessage;
class SrsHttpParser;
class SrsHttpHandler;
class SrsServer;

#include <srs_app_st.hpp>
#include <srs_app_conn.hpp>
Expand Down Expand Up @@ -177,6 +178,17 @@ class SrsGoApiClients : public ISrsHttpHandler
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
{
public:
Expand Down
21 changes: 8 additions & 13 deletions trunk/src/app/srs_app_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,7 @@ using namespace std;
#include <srs_app_statistic.hpp>
#include <srs_app_caster_flv.hpp>
#include <srs_core_mem_watch.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
#include <srs_kernel_consts.hpp>

// system interval in ms,
// all resolution times should be times togother,
Expand Down Expand Up @@ -430,7 +422,7 @@ int SrsSignalManager::start()
sa.sa_handler = SrsSignalManager::sig_catcher;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
sigaction(SRS_SIGNAL_GRACEFULLY_QUIT, &sa, NULL);

sa.sa_handler = SrsSignalManager::sig_catcher;
sigemptyset(&sa.sa_mask);
Expand Down Expand Up @@ -824,6 +816,9 @@ int SrsServer::http_handle()
if ((ret = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != ERROR_SUCCESS) {
return ret;
}
if ((ret = http_api_mux->handle("/api/v1/raw", new SrsGoApiRaw(this))) != ERROR_SUCCESS) {
return ret;
}

// test the request info.
if ((ret = http_api_mux->handle("/api/v1/tests/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {
Expand Down Expand Up @@ -927,7 +922,7 @@ void SrsServer::on_signal(int signo)
return;
}

if (signo == SIGINT || signo == SIGUSR2) {
if (signo == SIGINT || signo == SRS_SIGNAL_DISPOSE) {
#ifdef SRS_AUTO_GPERF_MC
srs_trace("gmc is on, main cycle will terminate normally.");
signal_gmc_stop = true;
Expand All @@ -941,7 +936,7 @@ void SrsServer::on_signal(int signo)
return;
}

if (signo == SIGTERM && !signal_gracefully_quit) {
if (signo == SRS_SIGNAL_GRACEFULLY_QUIT && !signal_gracefully_quit) {
srs_trace("user terminate program, gracefully quit.");
signal_gracefully_quit = true;
return;
Expand Down Expand Up @@ -982,7 +977,7 @@ int SrsServer::do_cycle()
for (int i = 0; i < temp_max; i++) {
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) {
srs_trace("cleanup for gracefully terminate.");
return ret;
Expand Down
22 changes: 13 additions & 9 deletions trunk/src/app/srs_app_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,19 @@ class SrsServer : virtual public ISrsReloadHandler
// server utilities.
public:
/**
* callback for signal manager got a signal.
* the signal manager convert signal to io message,
* whatever, we will got the signo like the orignal signal(int signo) handler.
* @remark, direclty exit for SIGTERM.
* @remark, do reload for SIGNAL_RELOAD.
* @remark, for SIGINT and SIGUSR2:
* no gmc, directly exit.
* for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc.
*/
* callback for signal manager got a signal.
* the signal manager convert signal to io message,
* whatever, we will got the signo like the orignal signal(int signo) handler.
* @param signo the signal number from user, where:
* SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit.
* SRS_SIGNAL_DISPOSE, the SIGUSR2, dispose for gmc.
* SRS_SIGNAL_PERSISTENCE_CONFIG, the SIGUSR1, persistence config to file.
* 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);
private:
/**
Expand Down
11 changes: 11 additions & 0 deletions trunk/src/kernel/srs_kernel_consts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_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

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
Expand Down
3 changes: 3 additions & 0 deletions trunk/src/kernel/srs_kernel_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_KILL 1058
#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.
Expand Down

0 comments on commit d921d59

Please sign in to comment.