diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 82452f63e6..a802576bc1 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -228,6 +228,14 @@ SrsConfDirective* SrsConfDirective::set_arg0(string a0) return this; } +void SrsConfDirective::remove(SrsConfDirective* v) +{ + std::vector::iterator it; + if ((it = ::find(directives.begin(), directives.end(), v)) != directives.end()) { + directives.erase(it); + } +} + bool SrsConfDirective::is_vhost() { return name == "vhost"; @@ -2472,6 +2480,40 @@ int SrsConfig::raw_create_vhost(string vhost, bool& applied) return ret; } +int SrsConfig::raw_update_vhost(string vhost, string name, bool& applied) +{ + int ret = ERROR_SUCCESS; + + applied = false; + + // the vhost must be disabled, so we donot need to reload. + SrsConfDirective* conf = root->get_or_create("vhost", vhost); + conf->set_arg0(name); + + applied = true; + + return ret; +} + +int SrsConfig::raw_delete_vhost(string vhost, bool& applied) +{ + int ret = ERROR_SUCCESS; + + applied = false; + + // the vhost must be disabled, so we donot need to reload. + SrsConfDirective* conf = root->get("vhost", vhost); + srs_assert(conf); + + // remove the directive. + root->remove(conf); + srs_freep(conf); + + applied = true; + + return ret; +} + int SrsConfig::do_reload_listen() { int ret = ERROR_SUCCESS; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index adddb186d2..ad3a9f9731 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -131,6 +131,10 @@ class SrsConfDirective 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); + /** + * remove the v from sub directives, user must free the v. + */ + virtual void remove(SrsConfDirective* v); // help utilities public: /** @@ -378,6 +382,14 @@ class SrsConfig * raw create the new vhost. */ virtual int raw_create_vhost(std::string vhost, bool& applied); + /** + * raw update the disabled vhost name. + */ + virtual int raw_update_vhost(std::string vhost, std::string name, bool& applied); + /** + * raw delete the disabled vhost. + */ + virtual int raw_delete_vhost(std::string vhost, bool& applied); private: virtual int do_reload_listen(); virtual int do_reload_pid(); diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 9decefbe0b..d23056e566 100755 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -985,21 +985,23 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) // @scope the scope to update for config. // @value the updated value for scope. // @param the extra param for scope. + // @data the extra data for scope. // possible updates: - // @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. - // ff_log_dir ./objs the dir for ffmpeg log. - // srs_log_tank file the tank to log, file or console. - // srs_log_level trace the level of log, verbose, info, trace, warn, error. - // srs_log_file ./objs/srs.log the log file when tank is file. - // 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. + // @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. + // ff_log_dir ./objs the dir for ffmpeg log. + // srs_log_tank file the tank to log, file or console. + // srs_log_level trace the level of log, verbose, info, trace, warn, error. + // srs_log_file ./objs/srs.log the log file when tank is file. + // 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 + // @scope @value @param @data description + // vhost ossrs.net create - create vhost ossrs.net + // vhost ossrs.net update new.ossrs.net the new name to update vhost if (rpc == "update") { if (!allow_update) { ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED; @@ -1009,7 +1011,6 @@ 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); @@ -1024,13 +1025,9 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) 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; + string extra = ""; if (scope == "listen") { vector eps = srs_string_split(value, ","); @@ -1156,6 +1153,15 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) return srs_api_response_code(w, r, ret); } } else if (scope == "vhost") { + std::string param = r->query_get("param"); + std::string data = r->query_get("data"); + if (param != "create" && param != "update" && param != "delete") { + 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); + } + extra += " " + param; + if (param == "create") { // when create, the vhost must not exists. if (param.empty() || _srs_config->get_vhost(value, false)) { @@ -1168,15 +1174,44 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) 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); } + } else if (param == "update") { + extra += " to " + data; + + // when update, the vhost must exists and disabled. + SrsConfDirective* vhost = _srs_config->get_vhost(value, false); + if (data.empty() || data == value || param.empty() || !vhost || _srs_config->get_vhost_enabled(vhost)) { + ret = ERROR_SYSTEM_CONFIG_RAW_PARAMS; + srs_error("raw api update check vhost=%s, param=%s, data=%s failed. ret=%d", value.c_str(), param.c_str(), data.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + + if ((ret = _srs_config->raw_update_vhost(value, data, applied)) != ERROR_SUCCESS) { + srs_error("raw api update vhost=%s, param=%s, data=%s failed. ret=%d", value.c_str(), param.c_str(), data.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + } else if (param == "delete") { + // when delete, the vhost must exists and disabled. + SrsConfDirective* vhost = _srs_config->get_vhost(value, false); + if (param.empty() || !vhost || _srs_config->get_vhost_enabled(vhost)) { + 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_delete_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. if (applied) { server->on_signal(SRS_SIGNAL_PERSISTENCE_CONFIG); - srs_trace("raw api update %s=%s ok.", scope.c_str(), value.c_str()); + srs_trace("raw api update %s=%s%s ok.", scope.c_str(), value.c_str(), extra.c_str()); } else { - srs_warn("raw api update not applied %s=%s.", scope.c_str(), value.c_str()); + srs_warn("raw api update not applied %s=%s%s.", scope.c_str(), value.c_str(), extra.c_str()); } return srs_api_response(w, r, obj->to_json());