diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 4ef39c62e9..e01e0996ef 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -200,20 +200,32 @@ SrsConfDirective* SrsConfDirective::get_or_create(string n) SrsConfDirective* SrsConfDirective::get_or_create(string n, string a0) { - SrsConfDirective* conf = get_or_create(n); + SrsConfDirective* conf = get(n, a0); - if (conf->arg0() == a0) { - return conf; + if (!conf) { + conf = new SrsConfDirective(); + conf->name = n; + conf->set_arg0(a0); + directives.push_back(conf); + } + + return conf; +} + +SrsConfDirective* SrsConfDirective::set_arg0(string a0) +{ + if (arg0() == a0) { + return this; } // update a0. - if (!conf->args.empty()) { - conf->args.erase(conf->args.begin()); + if (!args.empty()) { + args.erase(args.begin()); } - conf->args.insert(conf->args.begin(), a0); + args.insert(args.begin(), a0); - return conf; + return this; } bool SrsConfDirective::is_vhost() @@ -693,17 +705,9 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) // DISABLED => ENABLED if (!get_vhost_enabled(old_vhost) && get_vhost_enabled(new_vhost)) { - srs_trace("vhost %s added, reload it.", vhost.c_str()); - for (it = subscribes.begin(); it != subscribes.end(); ++it) { - ISrsReloadHandler* subscribe = *it; - if ((ret = subscribe->on_reload_vhost_added(vhost)) != ERROR_SUCCESS) { - srs_error("notify subscribes added " - "vhost %s failed. ret=%d", vhost.c_str(), ret); - return ret; - } + if ((ret = do_reload_vhost_added(vhost)) != ERROR_SUCCESS) { + return ret; } - - srs_trace("reload new vhost %s success.", vhost.c_str()); continue; } @@ -2448,6 +2452,25 @@ int SrsConfig::raw_set_pithy_print_ms(string pithy_print_ms, bool& applied) return ret; } +int SrsConfig::raw_create_vhost(string vhost, bool& applied) +{ + int ret = ERROR_SUCCESS; + + applied = false; + + + SrsConfDirective* conf = root->get_or_create("vhost", vhost); + conf->get_or_create("enabled")->set_arg0("on"); + + if ((ret = do_reload_vhost_added(vhost)) != ERROR_SUCCESS) { + return ret; + } + + applied = true; + + return ret; +} + int SrsConfig::do_reload_listen() { int ret = ERROR_SUCCESS; @@ -2584,6 +2607,26 @@ int SrsConfig::do_reload_pithy_print_ms() return ret; } +int SrsConfig::do_reload_vhost_added(string vhost) +{ + int ret = ERROR_SUCCESS; + + srs_trace("vhost %s added, reload it.", vhost.c_str()); + + vector::iterator it; + for (it = subscribes.begin(); it != subscribes.end(); ++it) { + ISrsReloadHandler* subscribe = *it; + if ((ret = subscribe->on_reload_vhost_added(vhost)) != ERROR_SUCCESS) { + srs_error("notify subscribes added vhost %s failed. ret=%d", vhost.c_str(), ret); + return ret; + } + } + + srs_trace("reload new vhost %s success.", vhost.c_str()); + + return ret; +} + string SrsConfig::config() { return config_file; @@ -3491,7 +3534,7 @@ int SrsConfig::get_stream_caster_rtp_port_max(SrsConfDirective* conf) return ::atoi(conf->arg0().c_str()); } -SrsConfDirective* SrsConfig::get_vhost(string vhost) +SrsConfDirective* SrsConfig::get_vhost(string vhost, bool try_default_vhost) { srs_assert(root); @@ -3507,7 +3550,7 @@ SrsConfDirective* SrsConfig::get_vhost(string vhost) } } - if (vhost != SRS_CONSTS_RTMP_DEFAULT_VHOST) { + if (try_default_vhost && vhost != SRS_CONSTS_RTMP_DEFAULT_VHOST) { return get_vhost(SRS_CONSTS_RTMP_DEFAULT_VHOST); } @@ -6268,7 +6311,7 @@ int srs_config_transform_vhost(SrsConfDirective* root) // SRS3+: // vhost { forward { enabled; destination; } } if (n == "forward" && conf->directives.empty()) { - conf->get_or_create("enabled", "on"); + conf->get_or_create("enabled")->set_arg0("on"); SrsConfDirective* destination = conf->get_or_create("destination"); destination->args = conf->args; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 5f9056f24c..3fcbde6401 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -130,6 +130,7 @@ class SrsConfDirective public: virtual SrsConfDirective* get_or_create(std::string n); virtual SrsConfDirective* get_or_create(std::string n, std::string a0); + virtual SrsConfDirective* set_arg0(std::string a0); // help utilities public: /** @@ -373,6 +374,10 @@ class SrsConfig * raw set the global pithy print interval in ms. */ virtual int raw_set_pithy_print_ms(std::string pithy_print_ms, bool& applied); + /** + * raw create the new vhost. + */ + virtual int raw_create_vhost(std::string vhost, bool& applied); private: virtual int do_reload_listen(); virtual int do_reload_pid(); @@ -382,6 +387,7 @@ class SrsConfig virtual int do_reload_max_connections(); virtual int do_reload_utc_time(); virtual int do_reload_pithy_print_ms(); + virtual int do_reload_vhost_added(std::string vhost); public: /** * get the config file path. @@ -503,13 +509,14 @@ class SrsConfig // vhost specified section public: /** - * get the vhost directive by vhost name. - * @param vhost, the name of vhost to get. - */ - virtual SrsConfDirective* get_vhost(std::string vhost); + * get the vhost directive by vhost name. + * @param vhost, the name of vhost to get. + * @param try_default_vhost whether try default when get specified vhost failed. + */ + virtual SrsConfDirective* get_vhost(std::string vhost, bool try_default_vhost = true); /** - * get all vhosts in config file. - */ + * get all vhosts in config file. + */ virtual void get_vhosts(std::vector& vhosts); /** * whether vhost is enabled diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index cc5444e7fa..2078059acc 100755 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -982,10 +982,11 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) } // for rpc=update, to update the configs of server. - // @param scope the scope to update for config. - // @param value the updated value for scope. + // @scope the scope to update for config. + // @value the updated value for scope. + // @param the extra param for scope. // possible updates: - // @param scope @param value value-description + // @scope @value value-description // listen 1935,1936 the port list. // pid ./objs/srs.pid the pid file of srs. // chunk_size 60000 the global RTMP chunk_size. @@ -996,6 +997,9 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) // max_connections 1000 the max connections of srs. // utc_time false whether enable utc time. // pithy_print_ms 10000 the pithy print interval in ms. + // vhost specified updates: + // @scope @value @param description + // vhost ossrs.net create create vhost ossrs.net if (rpc == "update") { if (!allow_update) { ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED; @@ -1005,6 +1009,7 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) std::string scope = r->query_get("scope"); std::string value = r->query_get("value"); + std::string param = r->query_get("param"); if (scope.empty()) { ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; srs_error("raw api query invalid empty scope. ret=%d", ret); @@ -1013,12 +1018,17 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) if (scope != "listen" && scope != "pid" && scope != "chunk_size" && scope != "ff_log_dir" && scope != "srs_log_tank" && scope != "srs_log_level" && scope != "srs_log_file" && scope != "max_connections" && scope != "utc_time" - && scope != "pithy_print_ms" + && scope != "pithy_print_ms" && scope != "vhost" ) { ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; srs_error("raw api query invalid scope=%s. ret=%d", scope.c_str(), ret); return srs_api_response_code(w, r, ret); } + if (scope == "vhost" && param != "create") { + ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; + srs_error("raw api query invalid scope=%s, param=%s. ret=%d", scope.c_str(), param.c_str(), ret); + return srs_api_response_code(w, r, ret); + } bool applied = false; if (scope == "listen") { @@ -1145,6 +1155,20 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) srs_error("raw api update pithy_print_ms=%s/%d failed. ret=%d", value.c_str(), ppmv, ret); return srs_api_response_code(w, r, ret); } + } else if (scope == "vhost") { + if (param == "create") { + // when create, the vhost must not exists. + if (param.empty() || _srs_config->get_vhost(value, false)) { + ret = ERROR_SYSTEM_CONFIG_RAW_PARAMS; + srs_error("raw api update check vhost=%s, param=%s failed. ret=%d", value.c_str(), param.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + + if ((ret = _srs_config->raw_create_vhost(value, applied)) != ERROR_SUCCESS) { + srs_error("raw api update vhost=%s, param=%s failed. ret=%d", value.c_str(), param.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + } } // whether the config applied.