winlin

support http api json, to PUT/POST, to 0.9.103

@@ -184,6 +184,14 @@ string SrsConfDirective::arg2() @@ -184,6 +184,14 @@ string SrsConfDirective::arg2()
184 return ""; 184 return "";
185 } 185 }
186 186
  187 +void SrsConfDirective::set_arg0(string value)
  188 +{
  189 + if (args.size() > 0) {
  190 + args[0] = value;
  191 + }
  192 + args.push_back(value);
  193 +}
  194 +
187 SrsConfDirective* SrsConfDirective::at(int index) 195 SrsConfDirective* SrsConfDirective::at(int index)
188 { 196 {
189 return directives.at(index); 197 return directives.at(index);
@@ -529,38 +537,23 @@ int SrsConfig::reload() @@ -529,38 +537,23 @@ int SrsConfig::reload()
529 537
530 // merge config: srs_log_tank 538 // merge config: srs_log_tank
531 if (!srs_directive_equals(root->get("srs_log_tank"), old_root->get("srs_log_tank"))) { 539 if (!srs_directive_equals(root->get("srs_log_tank"), old_root->get("srs_log_tank"))) {
532 - for (it = subscribes.begin(); it != subscribes.end(); ++it) {  
533 - ISrsReloadHandler* subscribe = *it;  
534 - if ((ret = subscribe->on_reload_log_tank()) != ERROR_SUCCESS) {  
535 - srs_error("notify subscribes reload srs_log_tank failed. ret=%d", ret);  
536 - return ret;  
537 - } 540 + if ((ret = force_reload_log_tank()) != ERROR_SUCCESS) {
  541 + return ret;
538 } 542 }
539 - srs_trace("reload srs_log_tank success.");  
540 } 543 }
541 544
542 // merge config: srs_log_level 545 // merge config: srs_log_level
543 if (!srs_directive_equals(root->get("srs_log_level"), old_root->get("srs_log_level"))) { 546 if (!srs_directive_equals(root->get("srs_log_level"), old_root->get("srs_log_level"))) {
544 - for (it = subscribes.begin(); it != subscribes.end(); ++it) {  
545 - ISrsReloadHandler* subscribe = *it;  
546 - if ((ret = subscribe->on_reload_log_level()) != ERROR_SUCCESS) {  
547 - srs_error("notify subscribes reload srs_log_level failed. ret=%d", ret);  
548 - return ret;  
549 - } 547 + if ((ret = force_reload_log_level()) != ERROR_SUCCESS) {
  548 + return ret;
550 } 549 }
551 - srs_trace("reload srs_log_level success.");  
552 } 550 }
553 551
554 // merge config: srs_log_file 552 // merge config: srs_log_file
555 if (!srs_directive_equals(root->get("srs_log_file"), old_root->get("srs_log_file"))) { 553 if (!srs_directive_equals(root->get("srs_log_file"), old_root->get("srs_log_file"))) {
556 - for (it = subscribes.begin(); it != subscribes.end(); ++it) {  
557 - ISrsReloadHandler* subscribe = *it;  
558 - if ((ret = subscribe->on_reload_log_file()) != ERROR_SUCCESS) {  
559 - srs_error("notify subscribes reload srs_log_file failed. ret=%d", ret);  
560 - return ret;  
561 - } 554 + if ((ret = force_reload_log_file()) != ERROR_SUCCESS) {
  555 + return ret;
562 } 556 }
563 - srs_trace("reload srs_log_file success.");  
564 } 557 }
565 558
566 // merge config: pithy_print 559 // merge config: pithy_print
@@ -593,6 +586,117 @@ int SrsConfig::reload() @@ -593,6 +586,117 @@ int SrsConfig::reload()
593 return ret; 586 return ret;
594 } 587 }
595 588
  589 +SrsConfDirective* SrsConfig::get_or_create(SrsConfDirective* node, string name)
  590 +{
  591 + srs_assert(node);
  592 +
  593 + SrsConfDirective* conf = node->get(name);
  594 +
  595 + if (!conf) {
  596 + conf = new SrsConfDirective();
  597 + conf->name = name;
  598 + node->directives.push_back(conf);
  599 + }
  600 +
  601 + return conf;
  602 +}
  603 +
  604 +bool SrsConfig::set_log_file(string file)
  605 +{
  606 + if (file == get_log_file()) {
  607 + return false;
  608 + }
  609 +
  610 + SrsConfDirective* conf = get_or_create(root, "srs_log_file");
  611 + srs_assert(conf);
  612 + conf->set_arg0(file);
  613 +
  614 + return true;
  615 +}
  616 +
  617 +bool SrsConfig::set_log_tank(string tank)
  618 +{
  619 + if (get_log_tank_file() && tank != "console") {
  620 + return false;
  621 + }
  622 + if (!get_log_tank_file() && tank == "console") {
  623 + return false;
  624 + }
  625 +
  626 + SrsConfDirective* conf = get_or_create(root, "srs_log_tank");
  627 + srs_assert(conf);
  628 + conf->set_arg0(tank);
  629 +
  630 + return true;
  631 +}
  632 +
  633 +bool SrsConfig::set_log_level(string level)
  634 +{
  635 + if (level == get_log_level()) {
  636 + return false;
  637 + }
  638 +
  639 + SrsConfDirective* conf = get_or_create(root, "srs_log_level");
  640 + srs_assert(conf);
  641 + conf->set_arg0(level);
  642 +
  643 + return true;
  644 +}
  645 +
  646 +int SrsConfig::force_reload_log_file()
  647 +{
  648 + int ret = ERROR_SUCCESS;
  649 +
  650 + std::vector<ISrsReloadHandler*>::iterator it;
  651 +
  652 + for (it = subscribes.begin(); it != subscribes.end(); ++it) {
  653 + ISrsReloadHandler* subscribe = *it;
  654 + if ((ret = subscribe->on_reload_log_file()) != ERROR_SUCCESS) {
  655 + srs_error("notify subscribes reload srs_log_file failed. ret=%d", ret);
  656 + return ret;
  657 + }
  658 + }
  659 + srs_trace("reload srs_log_file success.");
  660 +
  661 + return ret;
  662 +}
  663 +
  664 +int SrsConfig::force_reload_log_tank()
  665 +{
  666 + int ret = ERROR_SUCCESS;
  667 +
  668 + std::vector<ISrsReloadHandler*>::iterator it;
  669 +
  670 + for (it = subscribes.begin(); it != subscribes.end(); ++it) {
  671 + ISrsReloadHandler* subscribe = *it;
  672 + if ((ret = subscribe->on_reload_log_tank()) != ERROR_SUCCESS) {
  673 + srs_error("notify subscribes reload srs_log_tank failed. ret=%d", ret);
  674 + return ret;
  675 + }
  676 + }
  677 + srs_trace("reload srs_log_tank success.");
  678 +
  679 + return ret;
  680 +}
  681 +
  682 +int SrsConfig::force_reload_log_level()
  683 +{
  684 + int ret = ERROR_SUCCESS;
  685 +
  686 + std::vector<ISrsReloadHandler*>::iterator it;
  687 +
  688 + for (it = subscribes.begin(); it != subscribes.end(); ++it) {
  689 + ISrsReloadHandler* subscribe = *it;
  690 + if ((ret = subscribe->on_reload_log_level()) != ERROR_SUCCESS) {
  691 + srs_error("notify subscribes reload srs_log_level failed. ret=%d", ret);
  692 + return ret;
  693 + }
  694 + }
  695 + srs_trace("reload srs_log_level success.");
  696 +
  697 + return ret;
  698 +}
  699 +
596 int SrsConfig::reload_http_api(SrsConfDirective* old_root) 700 int SrsConfig::reload_http_api(SrsConfDirective* old_root)
597 { 701 {
598 int ret = ERROR_SUCCESS; 702 int ret = ERROR_SUCCESS;
@@ -1171,13 +1275,13 @@ int SrsConfig::parse_file(const char* filename) @@ -1171,13 +1275,13 @@ int SrsConfig::parse_file(const char* filename)
1171 // TODO: check pid. 1275 // TODO: check pid.
1172 1276
1173 // check log 1277 // check log
1174 - std::string log_filename = this->get_srs_log_file();  
1175 - if (get_srs_log_tank_file() && log_filename.empty()) { 1278 + std::string log_filename = this->get_log_file();
  1279 + if (get_log_tank_file() && log_filename.empty()) {
1176 ret = ERROR_SYSTEM_CONFIG_INVALID; 1280 ret = ERROR_SYSTEM_CONFIG_INVALID;
1177 srs_error("must specifies the file to write log to. ret=%d", ret); 1281 srs_error("must specifies the file to write log to. ret=%d", ret);
1178 return ret; 1282 return ret;
1179 } 1283 }
1180 - if (get_srs_log_tank_file()) { 1284 + if (get_log_tank_file()) {
1181 srs_trace("write log to file %s", log_filename.c_str()); 1285 srs_trace("write log to file %s", log_filename.c_str());
1182 srs_trace("you can: tailf %s", log_filename.c_str()); 1286 srs_trace("you can: tailf %s", log_filename.c_str());
1183 srs_trace("@see: %s", SRS_WIKI_URL_LOG); 1287 srs_trace("@see: %s", SRS_WIKI_URL_LOG);
@@ -2293,7 +2397,7 @@ string SrsConfig::get_ingest_input_url(SrsConfDirective* ingest) @@ -2293,7 +2397,7 @@ string SrsConfig::get_ingest_input_url(SrsConfDirective* ingest)
2293 return conf->arg0(); 2397 return conf->arg0();
2294 } 2398 }
2295 2399
2296 -string SrsConfig::get_srs_log_file() 2400 +string SrsConfig::get_log_file()
2297 { 2401 {
2298 srs_assert(root); 2402 srs_assert(root);
2299 2403
@@ -2317,7 +2421,7 @@ string SrsConfig::get_ffmpeg_log_dir() @@ -2317,7 +2421,7 @@ string SrsConfig::get_ffmpeg_log_dir()
2317 return conf->arg0(); 2421 return conf->arg0();
2318 } 2422 }
2319 2423
2320 -string SrsConfig::get_srs_log_level() 2424 +string SrsConfig::get_log_level()
2321 { 2425 {
2322 srs_assert(root); 2426 srs_assert(root);
2323 2427
@@ -2329,7 +2433,7 @@ string SrsConfig::get_srs_log_level() @@ -2329,7 +2433,7 @@ string SrsConfig::get_srs_log_level()
2329 return conf->arg0(); 2433 return conf->arg0();
2330 } 2434 }
2331 2435
2332 -bool SrsConfig::get_srs_log_tank_file() 2436 +bool SrsConfig::get_log_tank_file()
2333 { 2437 {
2334 srs_assert(root); 2438 srs_assert(root);
2335 2439
@@ -96,6 +96,7 @@ public: @@ -96,6 +96,7 @@ public:
96 std::string arg0(); 96 std::string arg0();
97 std::string arg1(); 97 std::string arg1();
98 std::string arg2(); 98 std::string arg2();
  99 + void set_arg0(std::string value);
99 SrsConfDirective* at(int index); 100 SrsConfDirective* at(int index);
100 SrsConfDirective* get(std::string _name); 101 SrsConfDirective* get(std::string _name);
101 SrsConfDirective* get(std::string _name, std::string _arg0); 102 SrsConfDirective* get(std::string _name, std::string _arg0);
@@ -136,6 +137,20 @@ public: @@ -136,6 +137,20 @@ public:
136 virtual void unsubscribe(ISrsReloadHandler* handler); 137 virtual void unsubscribe(ISrsReloadHandler* handler);
137 virtual int reload(); 138 virtual int reload();
138 private: 139 private:
  140 + virtual SrsConfDirective* get_or_create(SrsConfDirective* node, std::string name);
  141 +public:
  142 + /**
  143 + * dynamic set the config, for instance, for http api to set,
  144 + * @return ture if config changed and need to reload.
  145 + */
  146 + virtual bool set_log_file(std::string file);
  147 + virtual bool set_log_tank(std::string tank);
  148 + virtual bool set_log_level(std::string level);
  149 +public:
  150 + virtual int force_reload_log_file();
  151 + virtual int force_reload_log_tank();
  152 + virtual int force_reload_log_level();
  153 +private:
139 virtual int reload_http_api(SrsConfDirective* old_root); 154 virtual int reload_http_api(SrsConfDirective* old_root);
140 virtual int reload_http_stream(SrsConfDirective* old_root); 155 virtual int reload_http_stream(SrsConfDirective* old_root);
141 virtual int reload_vhost(SrsConfDirective* old_root); 156 virtual int reload_vhost(SrsConfDirective* old_root);
@@ -231,9 +246,9 @@ public: @@ -231,9 +246,9 @@ public:
231 virtual std::string get_ingest_input_url(SrsConfDirective* ingest); 246 virtual std::string get_ingest_input_url(SrsConfDirective* ingest);
232 // log section 247 // log section
233 public: 248 public:
234 - virtual bool get_srs_log_tank_file();  
235 - virtual std::string get_srs_log_level();  
236 - virtual std::string get_srs_log_file(); 249 + virtual bool get_log_tank_file();
  250 + virtual std::string get_log_level();
  251 + virtual std::string get_log_file();
237 virtual std::string get_ffmpeg_log_dir(); 252 virtual std::string get_ffmpeg_log_dir();
238 // hls section 253 // hls section
239 private: 254 private:
@@ -134,6 +134,17 @@ int SrsHttpHandler::do_process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req @@ -134,6 +134,17 @@ int SrsHttpHandler::do_process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req
134 return ret; 134 return ret;
135 } 135 }
136 136
  137 +int SrsHttpHandler::response_error(SrsSocket* skt, SrsHttpMessage* req, int code, string desc)
  138 +{
  139 + std::stringstream ss;
  140 + ss << JOBJECT_START
  141 + << JFIELD_ERROR(code) << JFIELD_CONT
  142 + << JFIELD_STR("desc", desc)
  143 + << JOBJECT_END;
  144 +
  145 + return res_json(skt, req, ss.str());
  146 +}
  147 +
137 int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch) 148 int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch)
138 { 149 {
139 int ret = ERROR_SUCCESS; 150 int ret = ERROR_SUCCESS;
@@ -566,6 +577,26 @@ u_int8_t SrsHttpMessage::method() @@ -566,6 +577,26 @@ u_int8_t SrsHttpMessage::method()
566 return (u_int8_t)_header.method; 577 return (u_int8_t)_header.method;
567 } 578 }
568 579
  580 +bool SrsHttpMessage::is_http_get()
  581 +{
  582 + return _header.method == HTTP_GET;
  583 +}
  584 +
  585 +bool SrsHttpMessage::is_http_put()
  586 +{
  587 + return _header.method == HTTP_PUT;
  588 +}
  589 +
  590 +bool SrsHttpMessage::is_http_post()
  591 +{
  592 + return _header.method == HTTP_POST;
  593 +}
  594 +
  595 +bool SrsHttpMessage::is_http_delete()
  596 +{
  597 + return _header.method == HTTP_DELETE;
  598 +}
  599 +
569 string SrsHttpMessage::url() 600 string SrsHttpMessage::url()
570 { 601 {
571 return _uri->get_url(); 602 return _uri->get_url();
@@ -592,6 +623,15 @@ string SrsHttpMessage::body() @@ -592,6 +623,15 @@ string SrsHttpMessage::body()
592 return b; 623 return b;
593 } 624 }
594 625
  626 +char* SrsHttpMessage::body_raw()
  627 +{
  628 + if (_body && !_body->empty()) {
  629 + return _body->bytes();
  630 + }
  631 +
  632 + return NULL;
  633 +}
  634 +
595 int64_t SrsHttpMessage::body_size() 635 int64_t SrsHttpMessage::body_size()
596 { 636 {
597 return (int64_t)_body->size(); 637 return (int64_t)_body->size();
@@ -228,9 +228,15 @@ protected: @@ -228,9 +228,15 @@ protected:
228 */ 228 */
229 virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase); 229 virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase);
230 /** 230 /**
231 - * do the actual process of request. 231 + * do the actual process of request., format as, for example:
  232 + * {"code":0, "data":{}}
232 */ 233 */
233 virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); 234 virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
  235 + /**
  236 + * response error, format as, for example:
  237 + * {"code":100, "desc":"description"}
  238 + */
  239 + virtual int response_error(SrsSocket* skt, SrsHttpMessage* req, int code, std::string desc);
234 // response writer 240 // response writer
235 public: 241 public:
236 virtual SrsHttpHandler* res_status_line(std::stringstream& ss); 242 virtual SrsHttpHandler* res_status_line(std::stringstream& ss);
@@ -327,10 +333,15 @@ public: @@ -327,10 +333,15 @@ public:
327 public: 333 public:
328 virtual bool is_complete(); 334 virtual bool is_complete();
329 virtual u_int8_t method(); 335 virtual u_int8_t method();
  336 + virtual bool is_http_get();
  337 + virtual bool is_http_put();
  338 + virtual bool is_http_post();
  339 + virtual bool is_http_delete();
330 virtual std::string url(); 340 virtual std::string url();
331 virtual std::string path(); 341 virtual std::string path();
332 virtual std::string query(); 342 virtual std::string query();
333 virtual std::string body(); 343 virtual std::string body();
  344 + virtual char* body_raw();
334 virtual int64_t body_size(); 345 virtual int64_t body_size();
335 virtual int64_t content_length(); 346 virtual int64_t content_length();
336 virtual SrsHttpHandlerMatch* match(); 347 virtual SrsHttpHandlerMatch* match();
@@ -123,6 +123,7 @@ SrsApiV1::SrsApiV1() @@ -123,6 +123,7 @@ SrsApiV1::SrsApiV1()
123 handlers.push_back(new SrsApiSystemProcStats()); 123 handlers.push_back(new SrsApiSystemProcStats());
124 handlers.push_back(new SrsApiMemInfos()); 124 handlers.push_back(new SrsApiMemInfos());
125 handlers.push_back(new SrsApiAuthors()); 125 handlers.push_back(new SrsApiAuthors());
  126 + handlers.push_back(new SrsApiConfigs());
126 } 127 }
127 128
128 SrsApiV1::~SrsApiV1() 129 SrsApiV1::~SrsApiV1()
@@ -147,6 +148,7 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -147,6 +148,7 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
147 << JFIELD_STR("self_proc_stats", "the self process stats") << JFIELD_CONT 148 << JFIELD_STR("self_proc_stats", "the self process stats") << JFIELD_CONT
148 << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT 149 << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT
149 << JFIELD_STR("meminfos", "the meminfo of system") << JFIELD_CONT 150 << JFIELD_STR("meminfos", "the meminfo of system") << JFIELD_CONT
  151 + << JFIELD_STR("configs", "to query or modify the config of srs") << JFIELD_CONT
150 << JFIELD_STR("authors", "the primary authors and contributors") 152 << JFIELD_STR("authors", "the primary authors and contributors")
151 << JOBJECT_END 153 << JOBJECT_END
152 << JOBJECT_END; 154 << JOBJECT_END;
@@ -154,6 +156,107 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -154,6 +156,107 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
154 return res_json(skt, req, ss.str()); 156 return res_json(skt, req, ss.str());
155 } 157 }
156 158
  159 +SrsApiConfigs::SrsApiConfigs()
  160 +{
  161 + handlers.push_back(new SrsApiConfigsLogs());
  162 +}
  163 +
  164 +SrsApiConfigs::~SrsApiConfigs()
  165 +{
  166 +}
  167 +
  168 +bool SrsApiConfigs::can_handle(const char* path, int length, const char** /*pchild*/)
  169 +{
  170 + return srs_path_equals("/configs", path, length);
  171 +}
  172 +
  173 +int SrsApiConfigs::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
  174 +{
  175 + std::stringstream ss;
  176 +
  177 + ss << JOBJECT_START
  178 + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
  179 + << JFIELD_ORG("urls", JOBJECT_START)
  180 + << JFIELD_STR("logs", "the log level, tank and path")
  181 + << JOBJECT_END
  182 + << JOBJECT_END;
  183 +
  184 + return res_json(skt, req, ss.str());
  185 +}
  186 +
  187 +SrsApiConfigsLogs::SrsApiConfigsLogs()
  188 +{
  189 +}
  190 +
  191 +SrsApiConfigsLogs::~SrsApiConfigsLogs()
  192 +{
  193 +}
  194 +
  195 +bool SrsApiConfigsLogs::can_handle(const char* path, int length, const char** /*pchild*/)
  196 +{
  197 + return srs_path_equals("/logs", path, length);
  198 +}
  199 +
  200 +bool SrsApiConfigsLogs::is_handler_valid(SrsHttpMessage* req, int& status_code, string& reason_phrase)
  201 +{
  202 + if (!req->is_http_get() && !req->is_http_put()) {
  203 + status_code = HTTP_MethodNotAllowed;
  204 + reason_phrase = HTTP_MethodNotAllowed_str;
  205 +
  206 + return false;
  207 + }
  208 +
  209 + return SrsHttpHandler::is_handler_valid(req, status_code, reason_phrase);
  210 +}
  211 +
  212 +int SrsApiConfigsLogs::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
  213 +{
  214 + int ret = ERROR_SUCCESS;
  215 +
  216 + if (req->is_http_put()) {
  217 + srs_trace("http api PUT logs, req is: %s", req->body().c_str());
  218 +
  219 + SrsJsonAny* json = SrsJsonAny::loads(req->body_raw());
  220 + SrsAutoFree(SrsJsonAny, json);
  221 +
  222 + if (json->is_object()) {
  223 + SrsJsonObject* o = json->to_object();
  224 + SrsJsonAny* prop = NULL;
  225 + if ((prop = o->ensure_property_string("file")) != NULL && _srs_config->set_log_file(prop->to_str())) {
  226 + if ((ret = _srs_config->force_reload_log_file()) != ERROR_SUCCESS) {
  227 + return response_error(skt, req, ret, "reload log file failed");
  228 + }
  229 + srs_warn("http api reload log file to %s", prop->to_str().c_str());
  230 + }
  231 + if ((prop = o->ensure_property_string("tank")) != NULL && _srs_config->set_log_tank(prop->to_str())) {
  232 + if ((ret = _srs_config->force_reload_log_tank()) != ERROR_SUCCESS) {
  233 + return response_error(skt, req, ret, "reload log tank failed");
  234 + }
  235 + srs_warn("http api reload log tank to %s", prop->to_str().c_str());
  236 + }
  237 + if ((prop = o->ensure_property_string("level")) != NULL && _srs_config->set_log_level(prop->to_str())) {
  238 + if ((ret = _srs_config->force_reload_log_level()) != ERROR_SUCCESS) {
  239 + return response_error(skt, req, ret, "reload log level failed");
  240 + }
  241 + srs_warn("http api reload log level to %s", prop->to_str().c_str());
  242 + }
  243 + }
  244 + }
  245 +
  246 + std::stringstream ss;
  247 + ss << JOBJECT_START
  248 + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
  249 + << JFIELD_ORG("data", JOBJECT_START)
  250 + << JFIELD_STR("tank", (_srs_config->get_log_tank_file()? "file":"console")) << JFIELD_CONT
  251 + << JFIELD_STR("level", _srs_config->get_log_level()) << JFIELD_CONT
  252 + << JFIELD_STR("cwd", _srs_config->cwd()) << JFIELD_CONT
  253 + << JFIELD_STR("file", _srs_config->get_log_file())
  254 + << JOBJECT_END
  255 + << JOBJECT_END;
  256 +
  257 + return res_json(skt, req, ss.str());
  258 +}
  259 +
157 SrsApiVersion::SrsApiVersion() 260 SrsApiVersion::SrsApiVersion()
158 { 261 {
159 } 262 }
@@ -76,6 +76,29 @@ protected: @@ -76,6 +76,29 @@ protected:
76 virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); 76 virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
77 }; 77 };
78 78
  79 +class SrsApiConfigs : public SrsHttpHandler
  80 +{
  81 +public:
  82 + SrsApiConfigs();
  83 + virtual ~SrsApiConfigs();
  84 +public:
  85 + virtual bool can_handle(const char* path, int length, const char** pchild);
  86 +protected:
  87 + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
  88 +};
  89 +
  90 +class SrsApiConfigsLogs : public SrsHttpHandler
  91 +{
  92 +public:
  93 + SrsApiConfigsLogs();
  94 + virtual ~SrsApiConfigsLogs();
  95 +public:
  96 + virtual bool can_handle(const char* path, int length, const char** pchild);
  97 +protected:
  98 + virtual bool is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase);
  99 + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
  100 +};
  101 +
79 class SrsApiVersion : public SrsHttpHandler 102 class SrsApiVersion : public SrsHttpHandler
80 { 103 {
81 public: 104 public:
@@ -343,7 +343,10 @@ SrsJsonAny* srs_json_parse_tree_nx_json(const nx_json* node) @@ -343,7 +343,10 @@ SrsJsonAny* srs_json_parse_tree_nx_json(const nx_json* node)
343 343
344 SrsJsonAny* SrsJsonAny::loads(char* str) 344 SrsJsonAny* SrsJsonAny::loads(char* str)
345 { 345 {
346 - srs_assert(str); 346 + if (!str) {
  347 + return NULL;
  348 + }
  349 +
347 if (strlen(str) == 0) { 350 if (strlen(str) == 0) {
348 return NULL; 351 return NULL;
349 } 352 }
@@ -430,6 +433,21 @@ SrsJsonAny* SrsJsonObject::get_property(string name) @@ -430,6 +433,21 @@ SrsJsonAny* SrsJsonObject::get_property(string name)
430 return NULL; 433 return NULL;
431 } 434 }
432 435
  436 +SrsJsonAny* SrsJsonObject::ensure_property_string(string name)
  437 +{
  438 + SrsJsonAny* prop = get_property(name);
  439 +
  440 + if (!prop) {
  441 + return NULL;
  442 + }
  443 +
  444 + if (!prop->is_string()) {
  445 + return NULL;
  446 + }
  447 +
  448 + return prop;
  449 +}
  450 +
433 SrsJsonArray::SrsJsonArray() 451 SrsJsonArray::SrsJsonArray()
434 { 452 {
435 marker = SRS_JSON_Array; 453 marker = SRS_JSON_Array;
@@ -147,6 +147,7 @@ public: @@ -147,6 +147,7 @@ public:
147 public: 147 public:
148 virtual void set(std::string key, SrsJsonAny* value); 148 virtual void set(std::string key, SrsJsonAny* value);
149 virtual SrsJsonAny* get_property(std::string name); 149 virtual SrsJsonAny* get_property(std::string name);
  150 + virtual SrsJsonAny* ensure_property_string(std::string name);
150 }; 151 };
151 152
152 class SrsJsonArray : public SrsJsonAny 153 class SrsJsonArray : public SrsJsonAny
@@ -88,8 +88,8 @@ int SrsFastLog::initialize() @@ -88,8 +88,8 @@ int SrsFastLog::initialize()
88 88
89 _srs_config->subscribe(this); 89 _srs_config->subscribe(this);
90 90
91 - log_to_file_tank = _srs_config->get_srs_log_tank_file();  
92 - _level = srs_get_log_level(_srs_config->get_srs_log_level()); 91 + log_to_file_tank = _srs_config->get_log_tank_file();
  92 + _level = srs_get_log_level(_srs_config->get_log_level());
93 93
94 return ret; 94 return ret;
95 } 95 }
@@ -202,7 +202,7 @@ int SrsFastLog::on_reload_log_tank() @@ -202,7 +202,7 @@ int SrsFastLog::on_reload_log_tank()
202 int ret = ERROR_SUCCESS; 202 int ret = ERROR_SUCCESS;
203 203
204 bool tank = log_to_file_tank; 204 bool tank = log_to_file_tank;
205 - log_to_file_tank = _srs_config->get_srs_log_tank_file(); 205 + log_to_file_tank = _srs_config->get_log_tank_file();
206 206
207 if (tank) { 207 if (tank) {
208 return ret; 208 return ret;
@@ -224,7 +224,7 @@ int SrsFastLog::on_reload_log_level() @@ -224,7 +224,7 @@ int SrsFastLog::on_reload_log_level()
224 { 224 {
225 int ret = ERROR_SUCCESS; 225 int ret = ERROR_SUCCESS;
226 226
227 - _level = srs_get_log_level(_srs_config->get_srs_log_level()); 227 + _level = srs_get_log_level(_srs_config->get_log_level());
228 228
229 return ret; 229 return ret;
230 } 230 }
@@ -340,7 +340,7 @@ void SrsFastLog::write_log(int& fd, char *str_log, int size, int level) @@ -340,7 +340,7 @@ void SrsFastLog::write_log(int& fd, char *str_log, int size, int level)
340 340
341 void SrsFastLog::open_log_file() 341 void SrsFastLog::open_log_file()
342 { 342 {
343 - std::string filename = _srs_config->get_srs_log_file(); 343 + std::string filename = _srs_config->get_log_file();
344 344
345 if (filename.empty()) { 345 if (filename.empty()) {
346 return; 346 return;
@@ -31,15 +31,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,15 +31,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 31
32 int srs_get_log_level(std::string level) 32 int srs_get_log_level(std::string level)
33 { 33 {
34 - if ("verbose" == _srs_config->get_srs_log_level()) { 34 + if ("verbose" == _srs_config->get_log_level()) {
35 return SrsLogLevel::Verbose; 35 return SrsLogLevel::Verbose;
36 - } else if ("info" == _srs_config->get_srs_log_level()) { 36 + } else if ("info" == _srs_config->get_log_level()) {
37 return SrsLogLevel::Info; 37 return SrsLogLevel::Info;
38 - } else if ("trace" == _srs_config->get_srs_log_level()) { 38 + } else if ("trace" == _srs_config->get_log_level()) {
39 return SrsLogLevel::Trace; 39 return SrsLogLevel::Trace;
40 - } else if ("warn" == _srs_config->get_srs_log_level()) { 40 + } else if ("warn" == _srs_config->get_log_level()) {
41 return SrsLogLevel::Warn; 41 return SrsLogLevel::Warn;
42 - } else if ("error" == _srs_config->get_srs_log_level()) { 42 + } else if ("error" == _srs_config->get_log_level()) {
43 return SrsLogLevel::Error; 43 return SrsLogLevel::Error;
44 } else { 44 } else {
45 return SrsLogLevel::Trace; 45 return SrsLogLevel::Trace;
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "102" 34 +#define VERSION_REVISION "103"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "srs" 37 #define RTMP_SIG_SRS_KEY "srs"