Skip to content

Commit

Permalink
for #319, support rpc raw api to query the HTTP RAW API configs.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Aug 28, 2015
1 parent af0a76e commit 2dcf3bc
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 21 deletions.
16 changes: 12 additions & 4 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,18 @@ 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;
# the HTTP RAW API is more powerful api to change srs state and reload.
raw_api {
# whether enable the HTTP RAW API.
# default: off
enabled off;
# whether enable rpc reload.
# default: off
allow_reload off;
# whether enable rpc config_query.
# default: off
allow_config_query off;
}
}
# embeded http server in srs.
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
Expand Down
131 changes: 125 additions & 6 deletions trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1143,9 +1143,6 @@ 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 @@ -1199,6 +1196,24 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root)
}
srs_trace("reload enabled modified http_api success.");

if (!srs_directive_equals(old_http_api->get("crossdomain"), new_http_api->get("crossdomain"))) {
ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_http_api_crossdomain()) != ERROR_SUCCESS) {
srs_error("notify subscribes http_api crossdomain modified failed. ret=%d", ret);
return ret;
}
}
srs_trace("reload crossdomain modified http_api success.");

if (!srs_directive_equals(old_http_api->get("raw_api"), new_http_api->get("raw_api"))) {
ISrsReloadHandler* subscribe = *it;
if ((ret = subscribe->on_reload_http_api_raw_api()) != ERROR_SUCCESS) {
srs_error("notify subscribes http_api raw_api modified failed. ret=%d", ret);
return ret;
}
}
srs_trace("reload raw_api modified http_api success.");

return ret;
}

Expand Down Expand Up @@ -1645,7 +1660,7 @@ int SrsConfig::global_to_json(SrsAmf0Object* obj)
} else if (sdir->name == "crossdomain") {
sobj->set(sdir->name, sdir->dumps_arg0_to_boolean());
} else if (sdir->name == "raw_api") {
sobj->set(sdir->name, sdir->dumps_arg0_to_boolean());
sobj->set(sdir->name, SrsAmf0Any::boolean(get_raw_api()));
}
}
obj->set(dir->name, sobj);
Expand Down Expand Up @@ -1780,6 +1795,49 @@ int SrsConfig::vhost_to_json(SrsConfDirective* vhost, SrsAmf0Object* obj)
return ret;
}

int SrsConfig::raw_to_json(SrsAmf0Object* obj)
{
int ret = ERROR_SUCCESS;

SrsAmf0Object* sobj = SrsAmf0Any::object();
obj->set("http_api", sobj);

for (int i = 0; i < (int)root->directives.size(); i++) {
SrsConfDirective* dir = root->directives.at(i);

if (dir->name != "http_api") {
continue;
}

for (int j = 0; j < (int)dir->directives.size(); j++) {
SrsConfDirective* sdir = dir->directives.at(j);
if (sdir->name == "enabled") {
sobj->set(sdir->name, sdir->dumps_arg0_to_boolean());
} else if (sdir->name == "listen") {
sobj->set(sdir->name, sdir->dumps_arg0_to_str());
} else if (sdir->name == "crossdomain") {
sobj->set(sdir->name, sdir->dumps_arg0_to_boolean());
} else if (sdir->name == "raw_api") {
SrsAmf0Object* ssobj = SrsAmf0Any::object();
sobj->set(sdir->name, ssobj);

for (int k = 0; k < (int)sdir->directives.size(); k++) {
SrsConfDirective* ssdir = sdir->directives.at(k);
if (ssdir->name == "enabled") {
ssobj->set(ssdir->name, ssdir->dumps_arg0_to_boolean());
} else if (ssdir->name == "allow_reload") {
ssobj->set(ssdir->name, ssdir->dumps_arg0_to_boolean());
} else if (ssdir->name == "allow_config_query") {
ssobj->set(ssdir->name, ssdir->dumps_arg0_to_boolean());
}
}
}
}
}

return ret;
}

string SrsConfig::config()
{
return config_file;
Expand Down Expand Up @@ -1946,12 +2004,24 @@ int SrsConfig::check_config()
if (true) {
SrsConfDirective* conf = get_http_api();
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
string n = conf->at(i)->name;
SrsConfDirective* obj = conf->at(i);
string n = obj->name;
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;
}

if (n == "raw_api") {
for (int j = 0; j < (int)obj->directives.size(); j++) {
string m = obj->at(j)->name;
if (m != "enabled" && m != "allow_reload" && m != "allow_config_query") {
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported http_api.raw_api directive %s, ret=%d", m.c_str(), ret);
return ret;
}
}
}
}
}
if (true) {
Expand Down Expand Up @@ -4529,7 +4599,29 @@ bool SrsConfig::get_http_api_crossdomain()
return SRS_CONF_PERFER_TRUE(conf->arg0());
}

bool SrsConfig::get_http_api_raw_api()
bool SrsConfig::get_raw_api()
{
static bool DEFAULT = false;

SrsConfDirective* conf = get_http_api();
if (!conf) {
return DEFAULT;
}

conf = conf->get("raw_api");
if (!conf) {
return DEFAULT;
}

conf = conf->get("enabled");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}

return SRS_CONF_PERFER_FALSE(conf->arg0());
}

bool SrsConfig::get_raw_api_allow_reload()
{
static bool DEFAULT = false;

Expand All @@ -4539,6 +4631,33 @@ bool SrsConfig::get_http_api_raw_api()
}

conf = conf->get("raw_api");
if (!conf) {
return DEFAULT;
}

conf = conf->get("allow_reload");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}

return SRS_CONF_PERFER_FALSE(conf->arg0());
}

bool SrsConfig::get_raw_api_allow_config_query()
{
static bool DEFAULT = false;

SrsConfDirective* conf = get_http_api();
if (!conf) {
return DEFAULT;
}

conf = conf->get("raw_api");
if (!conf) {
return DEFAULT;
}

conf = conf->get("allow_config_query");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
Expand Down
14 changes: 13 additions & 1 deletion trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ class SrsConfig
* dumps the vhost section to json.
*/
virtual int vhost_to_json(SrsConfDirective* vhost, SrsAmf0Object* obj);
/**
* dumps the http_api sections to json for raw api info.
*/
virtual int raw_to_json(SrsAmf0Object* obj);
/**
* get the config file path.
*/
Expand Down Expand Up @@ -1061,7 +1065,15 @@ class SrsConfig
/**
* whether enable the HTTP RAW API.
*/
virtual bool get_http_api_raw_api();
virtual bool get_raw_api();
/**
* whether allow rpc reload.
*/
virtual bool get_raw_api_allow_reload();
/**
* whether allow rpc config_query.
*/
virtual bool get_raw_api_allow_config_query();
// http stream section
private:
/**
Expand Down
68 changes: 60 additions & 8 deletions trunk/src/app/srs_app_http_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,45 +842,80 @@ int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
SrsGoApiRaw::SrsGoApiRaw(SrsServer* svr)
{
server = svr;

raw_api = _srs_config->get_raw_api();
allow_reload = _srs_config->get_raw_api_allow_reload();
allow_config_query = _srs_config->get_raw_api_allow_config_query();

_srs_config->subscribe(this);
}

SrsGoApiRaw::~SrsGoApiRaw()
{
_srs_config->unsubscribe(this);
}

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()) {
if (!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")) {
if (rpc.empty() || (rpc != "reload" && rpc != "config_query" && rpc != "raw")) {
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") {
if (!allow_reload) {
ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED;
srs_error("raw api reload disabled rpc=%s. ret=%d", rpc.c_str(), ret);
return srs_api_response_code(w, r, ret);
}

srs_trace("raw api trigger reload. ret=%d", ret);
server->on_signal(SRS_SIGNAL_RELOAD);
return srs_api_response_code(w, r, ret);
}

// the object to return for request.
SrsAmf0Object* obj = SrsAmf0Any::object();
SrsAutoFree(SrsAmf0Object, obj);
obj->set("code", SrsAmf0Any::number(ERROR_SUCCESS));

// for rpc=raw, to query the raw api config for http api.
if (rpc == "raw") {
// query global scope.
if ((ret = _srs_config->raw_to_json(obj)) != ERROR_SUCCESS) {
srs_error("raw api rpc raw failed. ret=%d", ret);
return srs_api_response_code(w, r, ret);
}

return srs_api_response(w, r, obj->to_json());
}

// for rpc=config_query, to get the configs of server.
// @param scope the scope to query for config, it can be:
// global, the configs belongs to the root, donot includes any sub directives.
// vhost, the configs for specified vhost by @param vhost.
// @param vhost the vhost name for @param scope is vhost to query config.
// for the default vhost, must be __defaultVhost__
if (rpc == "config_query") {
if (!allow_config_query) {
ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED;
srs_error("raw api allow_config_query disabled rpc=%s. ret=%d", rpc.c_str(), ret);
return srs_api_response_code(w, r, ret);
}

std::string scope = r->query_get("scope");
std::string vhost = r->query_get("vhost");
if (scope.empty() || (scope != "global" && scope != "vhost")) {
Expand All @@ -889,12 +924,6 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
return srs_api_response_code(w, r, ret);
}

// config query.
SrsAmf0Object* obj = SrsAmf0Any::object();
SrsAutoFree(SrsAmf0Object, obj);

obj->set("code", SrsAmf0Any::number(ERROR_SUCCESS));

if (scope == "vhost") {
// query vhost scope.
if (vhost.empty()) {
Expand Down Expand Up @@ -934,6 +963,15 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
return ret;
}

int SrsGoApiRaw::on_reload_http_api_raw_api()
{
raw_api = _srs_config->get_raw_api();
allow_reload = _srs_config->get_raw_api_allow_reload();
allow_config_query = _srs_config->get_raw_api_allow_config_query();

return ERROR_SUCCESS;
}

SrsGoApiError::SrsGoApiError()
{
}
Expand All @@ -954,11 +992,15 @@ SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m
mux = m;
parser = new SrsHttpParser();
crossdomain_required = false;

_srs_config->subscribe(this);
}

SrsHttpApi::~SrsHttpApi()
{
srs_freep(parser);

_srs_config->unsubscribe(this);
}

void SrsHttpApi::resample()
Expand Down Expand Up @@ -1002,6 +1044,9 @@ int SrsHttpApi::do_cycle()
// @see https://github.com/simple-rtmp-server/srs/issues/398
skt.set_recv_timeout(SRS_HTTP_RECV_TIMEOUT_US);

// initialize the crossdomain
crossdomain_enabled = _srs_config->get_http_api_crossdomain();

// process http messages.
while(!disposed) {
ISrsHttpMessage* req = NULL;
Expand Down Expand Up @@ -1083,5 +1128,12 @@ int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
return ret;
}

int SrsHttpApi::on_reload_http_api_crossdomain()
{
crossdomain_enabled = _srs_config->get_http_api_crossdomain();

return ERROR_SUCCESS;
}

#endif

Loading

0 comments on commit 2dcf3bc

Please sign in to comment.