winlin

support http api json, to PUT/POST. 0.9.105

@@ -229,6 +229,11 @@ Supported operating systems and hardware: @@ -229,6 +229,11 @@ Supported operating systems and hardware:
229 * 2013-10-17, Created.<br/> 229 * 2013-10-17, Created.<br/>
230 230
231 ## History 231 ## History
  232 +* v1.0, 2014-05-18, support http api json, to PUT/POST. 0.9.105
  233 +* v1.0, 2014-05-17, fix #72, also need stream_id for send_and_free_message. 0.9.101
  234 +* v1.0, 2014-05-17, rename struct to class. 0.9.100
  235 +* v1.0, 2014-05-14, fix #67 pithy print, stage must has a age. 0.9.98
  236 +* v1.0, 2014-05-13, fix mem leak for delete[] SharedPtrMessage array. 0.9.95
232 * v1.0, 2014-05-12, refine the kbps calc module. 0.9.93 237 * v1.0, 2014-05-12, refine the kbps calc module. 0.9.93
233 * v1.0, 2014-05-08, edge support FMS origin server. 0.9.92 238 * v1.0, 2014-05-08, edge support FMS origin server. 0.9.92
234 * v1.0, 2014-04-28, [1.0 mainline2(0.9.79)](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0.mainline2) released. 35255 lines. 239 * v1.0, 2014-04-28, [1.0 mainline2(0.9.79)](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0.mainline2) released. 35255 lines.
@@ -217,7 +217,7 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch @@ -217,7 +217,7 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch
217 SrsHttpHandler* SrsHttpHandler::res_status_line(stringstream& ss) 217 SrsHttpHandler* SrsHttpHandler::res_status_line(stringstream& ss)
218 { 218 {
219 ss << "HTTP/1.1 200 OK " << __CRLF 219 ss << "HTTP/1.1 200 OK " << __CRLF
220 - << "Server: SRS/"RTMP_SIG_SRS_VERSION"" << __CRLF; 220 + << "Server: "RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION"" << __CRLF;
221 return this; 221 return this;
222 } 222 }
223 223
@@ -597,11 +597,28 @@ bool SrsHttpMessage::is_http_delete() @@ -597,11 +597,28 @@ bool SrsHttpMessage::is_http_delete()
597 return _header.method == HTTP_DELETE; 597 return _header.method == HTTP_DELETE;
598 } 598 }
599 599
  600 +string SrsHttpMessage::uri()
  601 +{
  602 + std::string uri = _uri->get_schema();
  603 + if (uri.empty()) {
  604 + uri += "http://";
  605 + }
  606 +
  607 + uri += host();
  608 + uri += path();
  609 + return uri;
  610 +}
  611 +
600 string SrsHttpMessage::url() 612 string SrsHttpMessage::url()
601 { 613 {
602 return _uri->get_url(); 614 return _uri->get_url();
603 } 615 }
604 616
  617 +string SrsHttpMessage::host()
  618 +{
  619 + return get_request_header("Host");
  620 +}
  621 +
605 string SrsHttpMessage::path() 622 string SrsHttpMessage::path()
606 { 623 {
607 return _uri->get_path(); 624 return _uri->get_path();
@@ -683,6 +700,46 @@ void SrsHttpMessage::append_body(const char* body, int length) @@ -683,6 +700,46 @@ void SrsHttpMessage::append_body(const char* body, int length)
683 _body->append(body, length); 700 _body->append(body, length);
684 } 701 }
685 702
  703 +int SrsHttpMessage::request_header_count()
  704 +{
  705 + return (int)headers.size();
  706 +}
  707 +
  708 +string SrsHttpMessage::request_header_key_at(int index)
  709 +{
  710 + srs_assert(index < request_header_count());
  711 + SrsHttpHeaderField item = headers[index];
  712 + return item.first;
  713 +}
  714 +
  715 +string SrsHttpMessage::request_header_value_at(int index)
  716 +{
  717 + srs_assert(index < request_header_count());
  718 + SrsHttpHeaderField item = headers[index];
  719 + return item.second;
  720 +}
  721 +
  722 +void SrsHttpMessage::set_request_header(string key, string value)
  723 +{
  724 + headers.push_back(std::make_pair(key, value));
  725 +}
  726 +
  727 +string SrsHttpMessage::get_request_header(string name)
  728 +{
  729 + std::vector<SrsHttpHeaderField>::iterator it;
  730 +
  731 + for (it = headers.begin(); it != headers.end(); ++it) {
  732 + SrsHttpHeaderField& elem = *it;
  733 + std::string key = elem.first;
  734 + std::string value = elem.second;
  735 + if (key == name) {
  736 + return value;
  737 + }
  738 + }
  739 +
  740 + return "";
  741 +}
  742 +
686 SrsHttpParser::SrsHttpParser() 743 SrsHttpParser::SrsHttpParser()
687 { 744 {
688 msg = NULL; 745 msg = NULL;
@@ -723,6 +780,9 @@ int SrsHttpParser::parse_message(SrsSocket* skt, SrsHttpMessage** ppmsg) @@ -723,6 +780,9 @@ int SrsHttpParser::parse_message(SrsSocket* skt, SrsHttpMessage** ppmsg)
723 srs_assert(msg == NULL); 780 srs_assert(msg == NULL);
724 msg = new SrsHttpMessage(); 781 msg = new SrsHttpMessage();
725 782
  783 + // reset request data.
  784 + filed_name = "";
  785 +
726 // reset response header. 786 // reset response header.
727 msg->reset(); 787 msg->reset();
728 788
@@ -827,14 +887,34 @@ int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length) @@ -827,14 +887,34 @@ int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
827 return 0; 887 return 0;
828 } 888 }
829 889
830 -int SrsHttpParser::on_header_field(http_parser* /*parser*/, const char* at, size_t length) 890 +int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length)
831 { 891 {
  892 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  893 +
  894 + if (length > 0) {
  895 + srs_assert(obj);
  896 + obj->filed_name.append(at, (int)length);
  897 + }
  898 +
832 srs_info("Header field: %.*s", (int)length, at); 899 srs_info("Header field: %.*s", (int)length, at);
833 return 0; 900 return 0;
834 } 901 }
835 902
836 -int SrsHttpParser::on_header_value(http_parser* /*parser*/, const char* at, size_t length) 903 +int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length)
837 { 904 {
  905 + SrsHttpParser* obj = (SrsHttpParser*)parser->data;
  906 +
  907 + if (length > 0) {
  908 + srs_assert(obj);
  909 + srs_assert(obj->msg);
  910 +
  911 + std::string field_value;
  912 + field_value.append(at, (int)length);
  913 +
  914 + obj->msg->set_request_header(obj->filed_name, field_value);
  915 + obj->filed_name = "";
  916 + }
  917 +
838 srs_info("Header value: %.*s", (int)length, at); 918 srs_info("Header value: %.*s", (int)length, at);
839 return 0; 919 return 0;
840 } 920 }
@@ -323,6 +323,9 @@ private: @@ -323,6 +323,9 @@ private:
323 * use a buffer to read and send ts file. 323 * use a buffer to read and send ts file.
324 */ 324 */
325 char* _http_ts_send_buffer; 325 char* _http_ts_send_buffer;
  326 + // http headers
  327 + typedef std::pair<std::string, std::string> SrsHttpHeaderField;
  328 + std::vector<SrsHttpHeaderField> headers;
326 public: 329 public:
327 SrsHttpMessage(); 330 SrsHttpMessage();
328 virtual ~SrsHttpMessage(); 331 virtual ~SrsHttpMessage();
@@ -337,7 +340,9 @@ public: @@ -337,7 +340,9 @@ public:
337 virtual bool is_http_put(); 340 virtual bool is_http_put();
338 virtual bool is_http_post(); 341 virtual bool is_http_post();
339 virtual bool is_http_delete(); 342 virtual bool is_http_delete();
  343 + virtual std::string uri();
340 virtual std::string url(); 344 virtual std::string url();
  345 + virtual std::string host();
341 virtual std::string path(); 346 virtual std::string path();
342 virtual std::string query(); 347 virtual std::string query();
343 virtual std::string body(); 348 virtual std::string body();
@@ -352,6 +357,12 @@ public: @@ -352,6 +357,12 @@ public:
352 virtual void set_match(SrsHttpHandlerMatch* match); 357 virtual void set_match(SrsHttpHandlerMatch* match);
353 virtual void set_requires_crossdomain(bool requires_crossdomain); 358 virtual void set_requires_crossdomain(bool requires_crossdomain);
354 virtual void append_body(const char* body, int length); 359 virtual void append_body(const char* body, int length);
  360 +public:
  361 + virtual int request_header_count();
  362 + virtual std::string request_header_key_at(int index);
  363 + virtual std::string request_header_value_at(int index);
  364 + virtual void set_request_header(std::string key, std::string value);
  365 + virtual std::string get_request_header(std::string name);
355 }; 366 };
356 367
357 /** 368 /**
@@ -364,6 +375,7 @@ private: @@ -364,6 +375,7 @@ private:
364 http_parser_settings settings; 375 http_parser_settings settings;
365 http_parser parser; 376 http_parser parser;
366 SrsHttpMessage* msg; 377 SrsHttpMessage* msg;
  378 + std::string filed_name;
367 public: 379 public:
368 SrsHttpParser(); 380 SrsHttpParser();
369 virtual ~SrsHttpParser(); 381 virtual ~SrsHttpParser();
@@ -124,6 +124,7 @@ SrsApiV1::SrsApiV1() @@ -124,6 +124,7 @@ SrsApiV1::SrsApiV1()
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 handlers.push_back(new SrsApiConfigs());
  127 + handlers.push_back(new SrsApiRequests());
127 } 128 }
128 129
129 SrsApiV1::~SrsApiV1() 130 SrsApiV1::~SrsApiV1()
@@ -149,7 +150,72 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -149,7 +150,72 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
149 << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT 150 << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT
150 << JFIELD_STR("meminfos", "the meminfo of system") << JFIELD_CONT 151 << JFIELD_STR("meminfos", "the meminfo of system") << JFIELD_CONT
151 << JFIELD_STR("configs", "to query or modify the config of srs") << JFIELD_CONT 152 << JFIELD_STR("configs", "to query or modify the config of srs") << JFIELD_CONT
152 - << JFIELD_STR("authors", "the primary authors and contributors") 153 + << JFIELD_STR("authors", "the primary authors and contributors") << JFIELD_CONT
  154 + << JFIELD_STR("requests", "the request itself, for http debug")
  155 + << JOBJECT_END
  156 + << JOBJECT_END;
  157 +
  158 + return res_json(skt, req, ss.str());
  159 +}
  160 +
  161 +SrsApiRequests::SrsApiRequests()
  162 +{
  163 +}
  164 +
  165 +SrsApiRequests::~SrsApiRequests()
  166 +{
  167 +}
  168 +
  169 +bool SrsApiRequests::can_handle(const char* path, int length, const char** /*pchild*/)
  170 +{
  171 + return srs_path_equals("/requests", path, length);
  172 +}
  173 +
  174 +int SrsApiRequests::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
  175 +{
  176 + std::stringstream ss;
  177 +
  178 + ss << JOBJECT_START
  179 + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
  180 + << JFIELD_ORG("data", JOBJECT_START)
  181 + << JFIELD_STR("uri", req->uri()) << JFIELD_CONT
  182 + << JFIELD_STR("path", req->path()) << JFIELD_CONT;
  183 +
  184 + // method
  185 + if (req->is_http_get()) {
  186 + ss << JFIELD_STR("METHOD", "GET");
  187 + } else if (req->is_http_post()) {
  188 + ss << JFIELD_STR("METHOD", "POST");
  189 + } else if (req->is_http_put()) {
  190 + ss << JFIELD_STR("METHOD", "PUT");
  191 + } else if (req->is_http_delete()) {
  192 + ss << JFIELD_STR("METHOD", "DELETE");
  193 + } else {
  194 + ss << JFIELD_ORG("METHOD", req->method());
  195 + }
  196 + ss << JFIELD_CONT;
  197 +
  198 + // request headers
  199 + ss << JFIELD_NAME("headers") << JOBJECT_START;
  200 + for (int i = 0; i < req->request_header_count(); i++) {
  201 + std::string key = req->request_header_key_at(i);
  202 + std::string value = req->request_header_value_at(i);
  203 + if ( i < req->request_header_count() - 1) {
  204 + ss << JFIELD_STR(key, value) << JFIELD_CONT;
  205 + } else {
  206 + ss << JFIELD_STR(key, value);
  207 + }
  208 + }
  209 + ss << JOBJECT_END << JFIELD_CONT;
  210 +
  211 + // server informations
  212 + ss << JFIELD_NAME("server") << JOBJECT_START
  213 + << JFIELD_STR("sigature", RTMP_SIG_SRS_KEY) << JFIELD_CONT
  214 + << JFIELD_STR("name", RTMP_SIG_SRS_NAME) << JFIELD_CONT
  215 + << JFIELD_STR("version", RTMP_SIG_SRS_VERSION) << JFIELD_CONT
  216 + << JFIELD_STR("link", RTMP_SIG_SRS_URL) << JFIELD_CONT
  217 + << JFIELD_ORG("time", srs_get_system_time_ms())
  218 + << JOBJECT_END
153 << JOBJECT_END 219 << JOBJECT_END
154 << JOBJECT_END; 220 << JOBJECT_END;
155 221
@@ -177,7 +243,12 @@ int SrsApiConfigs::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -177,7 +243,12 @@ int SrsApiConfigs::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
177 ss << JOBJECT_START 243 ss << JOBJECT_START
178 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT 244 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
179 << JFIELD_ORG("urls", JOBJECT_START) 245 << JFIELD_ORG("urls", JOBJECT_START)
180 - << JFIELD_STR("logs", "the log level, tank and path") 246 + << JFIELD_NAME("logs") << JOBJECT_START
  247 + << JFIELD_STR("uri", req->uri()+"/logs") << JFIELD_CONT
  248 + << JFIELD_STR("desc", "system log settings") << JFIELD_CONT
  249 + << JFIELD_STR("GET", "query logs tank/level/file") << JFIELD_CONT
  250 + << JFIELD_STR("PUT", "update logs tank/level/file")
  251 + << JOBJECT_END
181 << JOBJECT_END 252 << JOBJECT_END
182 << JOBJECT_END; 253 << JOBJECT_END;
183 254
@@ -76,6 +76,17 @@ protected: @@ -76,6 +76,17 @@ 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 SrsApiRequests : public SrsHttpHandler
  80 +{
  81 +public:
  82 + SrsApiRequests();
  83 + virtual ~SrsApiRequests();
  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 +
79 class SrsApiConfigs : public SrsHttpHandler 90 class SrsApiConfigs : public SrsHttpHandler
80 { 91 {
81 public: 92 public:
@@ -31,12 +31,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,12 +31,12 @@ 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 "104" 34 +#define VERSION_REVISION "105"
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"
38 #define RTMP_SIG_SRS_ROLE "origin/edge server" 38 #define RTMP_SIG_SRS_ROLE "origin/edge server"
39 -#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(simple rtmp server)" 39 +#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)"
40 #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" 40 #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"
41 #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT 41 #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
42 #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" 42 #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"