正在显示
6 个修改的文件
包含
187 行增加
和
8 行删除
| @@ -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" |
-
请 注册 或 登录 后发表评论