diff --git a/trunk/conf/compatible.conf b/trunk/conf/compatible.conf index 91632df12..42767ea87 100644 --- a/trunk/conf/compatible.conf +++ b/trunk/conf/compatible.conf @@ -12,6 +12,7 @@ http_api { enabled on; allow_reload on; allow_query on; + allow_update on; } } # for SRS1. diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 1882b754e..93fa3b616 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -137,6 +137,9 @@ http_api { # whether enable rpc query. # default: off allow_query off; + # whether enable rpc update. + # default: off + allow_update off; } } # embeded http server in srs. diff --git a/trunk/conf/full.one.vhost.conf b/trunk/conf/full.one.vhost.conf index 5e0a21c13..fcbd8914d 100644 --- a/trunk/conf/full.one.vhost.conf +++ b/trunk/conf/full.one.vhost.conf @@ -28,6 +28,7 @@ http_api { enabled on; allow_reload on; allow_query on; + allow_update on; } } http_server { diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 7b87884f4..b258c5423 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -67,6 +67,9 @@ using namespace _srs_internal; // '\r' #define SRS_CR (char)SRS_CONSTS_CR +// dumps the engine to amf0 object. +int srs_config_dumps_engine(SrsConfDirective* dir, SrsAmf0Object* engine); + bool is_common_space(char ch) { return (ch == ' ' || ch == '\t' || ch == SRS_CR || ch == SRS_LF); @@ -1520,6 +1523,8 @@ int SrsConfig::global_to_json(SrsAmf0Object* obj) ssobj->set(ssdir->name, ssdir->dumps_arg0_to_boolean()); } else if (ssdir->name == "allow_query") { ssobj->set(ssdir->name, ssdir->dumps_arg0_to_boolean()); + } else if (ssdir->name == "allow_update") { + ssobj->set(ssdir->name, ssdir->dumps_arg0_to_boolean()); } } } @@ -2100,7 +2105,7 @@ int SrsConfig::vhost_to_json(SrsConfDirective* vhost, SrsAmf0Object* obj) SrsAmf0Object* engine = SrsAmf0Any::object(); ingest->set("engine", engine); - if ((ret = dumps_engine(sdir, engine)) != ERROR_SUCCESS) { + if ((ret = srs_config_dumps_engine(sdir, engine)) != ERROR_SUCCESS) { return ret; } } @@ -2138,7 +2143,7 @@ int SrsConfig::vhost_to_json(SrsConfDirective* vhost, SrsAmf0Object* obj) SrsAmf0Object* engine = SrsAmf0Any::object(); engines->append(engine); - if ((ret = dumps_engine(sdir, engine)) != ERROR_SUCCESS) { + if ((ret = srs_config_dumps_engine(sdir, engine)) != ERROR_SUCCESS) { return ret; } } @@ -2165,108 +2170,7 @@ int SrsConfig::raw_to_json(SrsAmf0Object* obj) ssobj->set("enabled", SrsAmf0Any::boolean(get_raw_api())); ssobj->set("allow_reload", SrsAmf0Any::boolean(get_raw_api_allow_reload())); ssobj->set("allow_query", SrsAmf0Any::boolean(get_raw_api_allow_query())); - - return ret; -} - -int SrsConfig::dumps_engine(SrsConfDirective* dir, SrsAmf0Object* engine) -{ - int ret = ERROR_SUCCESS; - - SrsConfDirective* conf = NULL; - - engine->set("id", dir->dumps_arg0_to_str()); - engine->set("enabled", SrsAmf0Any::boolean(get_engine_enabled(dir))); - - if ((conf = dir->get("iformat")) != NULL) { - engine->set("iformat", conf->dumps_arg0_to_str()); - } - - if ((conf = dir->get("vfilter")) != NULL) { - SrsAmf0Object* vfilter = SrsAmf0Any::object(); - engine->set("vfilter", vfilter); - - for (int i = 0; i < (int)conf->directives.size(); i++) { - SrsConfDirective* sdir = conf->directives.at(i); - vfilter->set(sdir->name, sdir->dumps_arg0_to_str()); - } - } - - if ((conf = dir->get("vcodec")) != NULL) { - engine->set("vcodec", conf->dumps_arg0_to_str()); - } - - if ((conf = dir->get("vbitrate")) != NULL) { - engine->set("vbitrate", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("vfps")) != NULL) { - engine->set("vfps", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("vwidth")) != NULL) { - engine->set("vwidth", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("vheight")) != NULL) { - engine->set("vheight", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("vthreads")) != NULL) { - engine->set("vthreads", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("vprofile")) != NULL) { - engine->set("vprofile", conf->dumps_arg0_to_str()); - } - - if ((conf = dir->get("vpreset")) != NULL) { - engine->set("vpreset", conf->dumps_arg0_to_str()); - } - - if ((conf = dir->get("vparams")) != NULL) { - SrsAmf0Object* vparams = SrsAmf0Any::object(); - engine->set("vparams", vparams); - - for (int i = 0; i < (int)conf->directives.size(); i++) { - SrsConfDirective* sdir = conf->directives.at(i); - vparams->set(sdir->name, sdir->dumps_arg0_to_str()); - } - } - - if ((conf = dir->get("acodec")) != NULL) { - engine->set("acodec", conf->dumps_arg0_to_str()); - } - - if ((conf = dir->get("abitrate")) != NULL) { - engine->set("abitrate", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("asample_rate")) != NULL) { - engine->set("asample_rate", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("achannels")) != NULL) { - engine->set("achannels", conf->dumps_arg0_to_number()); - } - - if ((conf = dir->get("aparams")) != NULL) { - SrsAmf0Object* aparams = SrsAmf0Any::object(); - engine->set("aparams", aparams); - - for (int i = 0; i < (int)conf->directives.size(); i++) { - SrsConfDirective* sdir = conf->directives.at(i); - aparams->set(sdir->name, sdir->dumps_arg0_to_str()); - } - } - - if ((conf = dir->get("oformat")) != NULL) { - engine->set("oformat", conf->dumps_arg0_to_str()); - } - - if ((conf = dir->get("output")) != NULL) { - engine->set("output", conf->dumps_arg0_to_str()); - } + ssobj->set("allow_update", SrsAmf0Any::boolean(get_raw_api_allow_update())); return ret; } @@ -2448,7 +2352,7 @@ int SrsConfig::check_config() 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_query") { + if (m != "enabled" && m != "allow_reload" && m != "allow_query" && m != "allow_update") { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported http_api.raw_api directive %s, ret=%d", m.c_str(), ret); return ret; @@ -5296,6 +5200,28 @@ bool SrsConfig::get_raw_api_allow_query() return SRS_CONF_PERFER_FALSE(conf->arg0()); } +bool SrsConfig::get_raw_api_allow_update() +{ + static bool DEFAULT = false; + + SrsConfDirective* conf = root->get("http_api"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("raw_api"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("allow_update"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return SRS_CONF_PERFER_FALSE(conf->arg0()); +} + bool SrsConfig::get_http_stream_enabled() { SrsConfDirective* conf = root->get("http_server"); @@ -5961,3 +5887,106 @@ int srs_config_transform_vhost(SrsConfDirective* root) return ret; } + +int srs_config_dumps_engine(SrsConfDirective* dir, SrsAmf0Object* engine) +{ + int ret = ERROR_SUCCESS; + + SrsConfDirective* conf = NULL; + + engine->set("id", dir->dumps_arg0_to_str()); + engine->set("enabled", SrsAmf0Any::boolean(_srs_config->get_engine_enabled(dir))); + + if ((conf = dir->get("iformat")) != NULL) { + engine->set("iformat", conf->dumps_arg0_to_str()); + } + + if ((conf = dir->get("vfilter")) != NULL) { + SrsAmf0Object* vfilter = SrsAmf0Any::object(); + engine->set("vfilter", vfilter); + + for (int i = 0; i < (int)conf->directives.size(); i++) { + SrsConfDirective* sdir = conf->directives.at(i); + vfilter->set(sdir->name, sdir->dumps_arg0_to_str()); + } + } + + if ((conf = dir->get("vcodec")) != NULL) { + engine->set("vcodec", conf->dumps_arg0_to_str()); + } + + if ((conf = dir->get("vbitrate")) != NULL) { + engine->set("vbitrate", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("vfps")) != NULL) { + engine->set("vfps", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("vwidth")) != NULL) { + engine->set("vwidth", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("vheight")) != NULL) { + engine->set("vheight", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("vthreads")) != NULL) { + engine->set("vthreads", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("vprofile")) != NULL) { + engine->set("vprofile", conf->dumps_arg0_to_str()); + } + + if ((conf = dir->get("vpreset")) != NULL) { + engine->set("vpreset", conf->dumps_arg0_to_str()); + } + + if ((conf = dir->get("vparams")) != NULL) { + SrsAmf0Object* vparams = SrsAmf0Any::object(); + engine->set("vparams", vparams); + + for (int i = 0; i < (int)conf->directives.size(); i++) { + SrsConfDirective* sdir = conf->directives.at(i); + vparams->set(sdir->name, sdir->dumps_arg0_to_str()); + } + } + + if ((conf = dir->get("acodec")) != NULL) { + engine->set("acodec", conf->dumps_arg0_to_str()); + } + + if ((conf = dir->get("abitrate")) != NULL) { + engine->set("abitrate", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("asample_rate")) != NULL) { + engine->set("asample_rate", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("achannels")) != NULL) { + engine->set("achannels", conf->dumps_arg0_to_number()); + } + + if ((conf = dir->get("aparams")) != NULL) { + SrsAmf0Object* aparams = SrsAmf0Any::object(); + engine->set("aparams", aparams); + + for (int i = 0; i < (int)conf->directives.size(); i++) { + SrsConfDirective* sdir = conf->directives.at(i); + aparams->set(sdir->name, sdir->dumps_arg0_to_str()); + } + } + + if ((conf = dir->get("oformat")) != NULL) { + engine->set("oformat", conf->dumps_arg0_to_str()); + } + + if ((conf = dir->get("output")) != NULL) { + engine->set("output", conf->dumps_arg0_to_str()); + } + + return ret; +} + diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 421076fcb..acc94037f 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -329,11 +329,6 @@ public: * dumps the http_api sections to json for raw api info. */ virtual int raw_to_json(SrsAmf0Object* obj); -private: - /** - * dumps the engine section to amf0 object. - */ - virtual int dumps_engine(SrsConfDirective* dir, SrsAmf0Object* engine); public: /** * get the config file path. @@ -1086,6 +1081,10 @@ public: * whether allow rpc query. */ virtual bool get_raw_api_allow_query(); + /** + * whether allow rpc update. + */ + virtual bool get_raw_api_allow_update(); // http stream section private: /** diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 7c1ba7d16..ca4d0f491 100755 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -853,6 +853,7 @@ SrsGoApiRaw::SrsGoApiRaw(SrsServer* svr) raw_api = _srs_config->get_raw_api(); allow_reload = _srs_config->get_raw_api_allow_reload(); allow_query = _srs_config->get_raw_api_allow_query(); + allow_update = _srs_config->get_raw_api_allow_update(); _srs_config->subscribe(this); } @@ -891,8 +892,10 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) return srs_api_response_code(w, r, ret); } + ////////////////////////////////////////////////////////////////////////// // the rpc is required. - if (rpc.empty() || (rpc != "reload" && rpc != "query" && rpc != "raw")) { + // the allowd rpc method check. + if (rpc.empty() || (rpc != "reload" && rpc != "query" && rpc != "raw" && rpc != "update")) { 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); @@ -968,6 +971,49 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) return srs_api_response(w, r, obj->to_json()); } + // for rpc=update, to update the configs of server. + // @param scope the scope to update for config. + // @param value the updated value for scope. + // possible updates: + // @param scope @param value value-description + // global.listen 1935,1936 the port list. + if (rpc == "update") { + if (!allow_update) { + ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED; + srs_error("raw api allow_update 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 value = r->query_get("value"); + if (scope.empty() || (scope != "global.listen")) { + ret = ERROR_SYSTEM_CONFIG_RAW_PARAMS; + srs_error("raw api query invalid scope=%s. ret=%d", scope.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + + if (scope == "global.listen") { + vector eps = srs_string_split(value, ","); + + bool invalid = eps.empty(); + for (int i = 0; i < (int)eps.size(); i++) { + string ep = eps.at(i); + int port = ::atoi(ep.c_str()); + if (port <= 2 || port >= 65535) { + invalid = true; + break; + } + } + if (invalid) { + ret = ERROR_SYSTEM_CONFIG_RAW_PARAMS; + srs_error("raw api update global.listen invalid eps=%s. ret=%d", value.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + } + + return srs_api_response(w, r, obj->to_json()); + } + return ret; } @@ -976,6 +1022,7 @@ 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_query = _srs_config->get_raw_api_allow_query(); + allow_update = _srs_config->get_raw_api_allow_update(); return ERROR_SUCCESS; } diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index 4bcd6cde1..1cb060cb1 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -187,6 +187,7 @@ private: bool raw_api; bool allow_reload; bool allow_query; + bool allow_update; public: SrsGoApiRaw(SrsServer* svr); virtual ~SrsGoApiRaw();