正在显示
9 个修改的文件
包含
323 行增加
和
211 行删除
| @@ -427,7 +427,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | @@ -427,7 +427,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke | ||
| 427 | "srs_app_codec" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" | 427 | "srs_app_codec" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" |
| 428 | "srs_app_http" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" | 428 | "srs_app_http" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" |
| 429 | "srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" | 429 | "srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" |
| 430 | - "srs_app_http_conn" "srs_app_http_hooks") | 430 | + "srs_app_http_conn" "srs_app_http_hooks" "srs_app_json") |
| 431 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh | 431 | APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh |
| 432 | APP_OBJS="${MODULE_OBJS[@]}" | 432 | APP_OBJS="${MODULE_OBJS[@]}" |
| 433 | # | 433 | # |
| @@ -39,6 +39,22 @@ using namespace std; | @@ -39,6 +39,22 @@ using namespace std; | ||
| 39 | 39 | ||
| 40 | #define SRS_HTTP_HEADER_BUFFER 1024 | 40 | #define SRS_HTTP_HEADER_BUFFER 1024 |
| 41 | 41 | ||
| 42 | +bool srs_path_equals(const char* expect, const char* path, int nb_path) | ||
| 43 | +{ | ||
| 44 | + int size = strlen(expect); | ||
| 45 | + | ||
| 46 | + if (size != nb_path) { | ||
| 47 | + return false; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + return !memcmp(expect, path, size); | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +SrsHttpHandlerMatch::SrsHttpHandlerMatch() | ||
| 54 | +{ | ||
| 55 | + handler = NULL; | ||
| 56 | +} | ||
| 57 | + | ||
| 42 | SrsHttpHandler::SrsHttpHandler() | 58 | SrsHttpHandler::SrsHttpHandler() |
| 43 | { | 59 | { |
| 44 | } | 60 | } |
| @@ -59,21 +75,34 @@ int SrsHttpHandler::initialize() | @@ -59,21 +75,34 @@ int SrsHttpHandler::initialize() | ||
| 59 | return ret; | 75 | return ret; |
| 60 | } | 76 | } |
| 61 | 77 | ||
| 62 | -bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/, const char** /*pnext_path*/) | 78 | +bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/, const char** /*pchild*/) |
| 63 | { | 79 | { |
| 64 | return false; | 80 | return false; |
| 65 | } | 81 | } |
| 66 | 82 | ||
| 67 | -int SrsHttpHandler::process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/, const char* /*path*/, int /*length*/) | 83 | +int SrsHttpHandler::process_request(SrsSocket* skt, SrsHttpMessage* req) |
| 84 | +{ | ||
| 85 | + if (req->method() == HTTP_OPTIONS) { | ||
| 86 | + return res_options(skt); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + return do_process_request(skt, req); | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +int SrsHttpHandler::do_process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/) | ||
| 68 | { | 93 | { |
| 69 | int ret = ERROR_SUCCESS; | 94 | int ret = ERROR_SUCCESS; |
| 70 | return ret; | 95 | return ret; |
| 71 | } | 96 | } |
| 72 | 97 | ||
| 73 | -int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength) | 98 | +int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch) |
| 74 | { | 99 | { |
| 75 | int ret = ERROR_SUCCESS; | 100 | int ret = ERROR_SUCCESS; |
| 76 | 101 | ||
| 102 | + SrsHttpHandler* handler = NULL; | ||
| 103 | + const char* match_start = NULL; | ||
| 104 | + int match_length = 0; | ||
| 105 | + | ||
| 77 | for (;;) { | 106 | for (;;) { |
| 78 | // ensure cur is not NULL. | 107 | // ensure cur is not NULL. |
| 79 | // ensure p not NULL and has bytes to parse. | 108 | // ensure p not NULL and has bytes to parse. |
| @@ -86,23 +115,23 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph | @@ -86,23 +115,23 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph | ||
| 86 | } | 115 | } |
| 87 | 116 | ||
| 88 | // whether the handler can handler the node. | 117 | // whether the handler can handler the node. |
| 89 | - const char* pnext = p; | ||
| 90 | - if (!can_handle(path, p - path, &pnext)) { | 118 | + const char* pchild = p; |
| 119 | + if (!can_handle(path, p - path, &pchild)) { | ||
| 91 | break; | 120 | break; |
| 92 | } | 121 | } |
| 93 | 122 | ||
| 94 | // save current handler, it's ok for current handler atleast. | 123 | // save current handler, it's ok for current handler atleast. |
| 95 | - *phandler = this; | ||
| 96 | - *pstart = path; | ||
| 97 | - *plength = p - path; | 124 | + handler = this; |
| 125 | + match_start = path; | ||
| 126 | + match_length = p - path; | ||
| 98 | 127 | ||
| 99 | // find the best matched child handler. | 128 | // find the best matched child handler. |
| 100 | std::vector<SrsHttpHandler*>::iterator it; | 129 | std::vector<SrsHttpHandler*>::iterator it; |
| 101 | for (it = handlers.begin(); it != handlers.end(); ++it) { | 130 | for (it = handlers.begin(); it != handlers.end(); ++it) { |
| 102 | - SrsHttpHandler* handler = *it; | 131 | + SrsHttpHandler* h = *it; |
| 103 | 132 | ||
| 104 | // matched, donot search more. | 133 | // matched, donot search more. |
| 105 | - if (handler->best_match(pnext, length - (pnext - path), phandler, pstart, plength) == ERROR_SUCCESS) { | 134 | + if (h->best_match(pchild, length - (pchild - path), ppmatch) == ERROR_SUCCESS) { |
| 106 | break; | 135 | break; |
| 107 | } | 136 | } |
| 108 | } | 137 | } |
| @@ -111,11 +140,22 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph | @@ -111,11 +140,22 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph | ||
| 111 | break; | 140 | break; |
| 112 | } | 141 | } |
| 113 | 142 | ||
| 114 | - if (*phandler == NULL) { | 143 | + // if already matched by child, return. |
| 144 | + if (*ppmatch) { | ||
| 145 | + return ret; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + // not matched, error. | ||
| 149 | + if (handler == NULL) { | ||
| 115 | ret = ERROR_HTTP_HANDLER_MATCH_URL; | 150 | ret = ERROR_HTTP_HANDLER_MATCH_URL; |
| 116 | return ret; | 151 | return ret; |
| 117 | } | 152 | } |
| 118 | 153 | ||
| 154 | + // matched by this handler. | ||
| 155 | + *ppmatch = new SrsHttpHandlerMatch(); | ||
| 156 | + (*ppmatch)->handler = handler; | ||
| 157 | + (*ppmatch)->matched_url.append(match_start, match_length); | ||
| 158 | + | ||
| 119 | return ret; | 159 | return ret; |
| 120 | } | 160 | } |
| 121 | 161 | ||
| @@ -133,6 +173,13 @@ SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss) | @@ -133,6 +173,13 @@ SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss) | ||
| 133 | return this; | 173 | return this; |
| 134 | } | 174 | } |
| 135 | 175 | ||
| 176 | +SrsHttpHandler* SrsHttpHandler::res_content_type_json(std::stringstream& ss) | ||
| 177 | +{ | ||
| 178 | + ss << "Content-Type: application/json;charset=utf-8" << __CRLF | ||
| 179 | + << "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF; | ||
| 180 | + return this; | ||
| 181 | +} | ||
| 182 | + | ||
| 136 | SrsHttpHandler* SrsHttpHandler::res_content_length(std::stringstream& ss, int64_t length) | 183 | SrsHttpHandler* SrsHttpHandler::res_content_length(std::stringstream& ss, int64_t length) |
| 137 | { | 184 | { |
| 138 | ss << "Content-Length: "<< length << __CRLF; | 185 | ss << "Content-Length: "<< length << __CRLF; |
| @@ -189,6 +236,18 @@ int SrsHttpHandler::res_text(SrsSocket* skt, std::string body) | @@ -189,6 +236,18 @@ int SrsHttpHandler::res_text(SrsSocket* skt, std::string body) | ||
| 189 | return res_flush(skt, ss); | 236 | return res_flush(skt, ss); |
| 190 | } | 237 | } |
| 191 | 238 | ||
| 239 | +int SrsHttpHandler::res_json(SrsSocket* skt, std::string json) | ||
| 240 | +{ | ||
| 241 | + std::stringstream ss; | ||
| 242 | + | ||
| 243 | + res_status_line(ss)->res_content_type_json(ss) | ||
| 244 | + ->res_content_length(ss, (int)json.length())->res_enable_crossdomain(ss) | ||
| 245 | + ->res_header_eof(ss) | ||
| 246 | + ->res_body(ss, json); | ||
| 247 | + | ||
| 248 | + return res_flush(skt, ss); | ||
| 249 | +} | ||
| 250 | + | ||
| 192 | SrsHttpHandler* SrsHttpHandler::create_http_api() | 251 | SrsHttpHandler* SrsHttpHandler::create_http_api() |
| 193 | { | 252 | { |
| 194 | return new SrsApiRoot(); | 253 | return new SrsApiRoot(); |
| @@ -204,11 +263,15 @@ SrsHttpMessage::SrsHttpMessage() | @@ -204,11 +263,15 @@ SrsHttpMessage::SrsHttpMessage() | ||
| 204 | { | 263 | { |
| 205 | _body = new SrsBuffer(); | 264 | _body = new SrsBuffer(); |
| 206 | _state = SrsHttpParseStateInit; | 265 | _state = SrsHttpParseStateInit; |
| 266 | + _uri = new SrsHttpUri(); | ||
| 267 | + _match = NULL; | ||
| 207 | } | 268 | } |
| 208 | 269 | ||
| 209 | SrsHttpMessage::~SrsHttpMessage() | 270 | SrsHttpMessage::~SrsHttpMessage() |
| 210 | { | 271 | { |
| 211 | srs_freep(_body); | 272 | srs_freep(_body); |
| 273 | + srs_freep(_uri); | ||
| 274 | + srs_freep(_match); | ||
| 212 | } | 275 | } |
| 213 | 276 | ||
| 214 | void SrsHttpMessage::reset() | 277 | void SrsHttpMessage::reset() |
| @@ -218,6 +281,11 @@ void SrsHttpMessage::reset() | @@ -218,6 +281,11 @@ void SrsHttpMessage::reset() | ||
| 218 | _url = ""; | 281 | _url = ""; |
| 219 | } | 282 | } |
| 220 | 283 | ||
| 284 | +int SrsHttpMessage::parse_uri() | ||
| 285 | +{ | ||
| 286 | + return _uri->initialize(_url); | ||
| 287 | +} | ||
| 288 | + | ||
| 221 | bool SrsHttpMessage::is_complete() | 289 | bool SrsHttpMessage::is_complete() |
| 222 | { | 290 | { |
| 223 | return _state == SrsHttpParseStateComplete; | 291 | return _state == SrsHttpParseStateComplete; |
| @@ -230,7 +298,17 @@ u_int8_t SrsHttpMessage::method() | @@ -230,7 +298,17 @@ u_int8_t SrsHttpMessage::method() | ||
| 230 | 298 | ||
| 231 | string SrsHttpMessage::url() | 299 | string SrsHttpMessage::url() |
| 232 | { | 300 | { |
| 233 | - return _url; | 301 | + return _uri->get_url(); |
| 302 | +} | ||
| 303 | + | ||
| 304 | +string SrsHttpMessage::path() | ||
| 305 | +{ | ||
| 306 | + return _uri->get_path(); | ||
| 307 | +} | ||
| 308 | + | ||
| 309 | +string SrsHttpMessage::query() | ||
| 310 | +{ | ||
| 311 | + return _uri->get_query(); | ||
| 234 | } | 312 | } |
| 235 | 313 | ||
| 236 | string SrsHttpMessage::body() | 314 | string SrsHttpMessage::body() |
| @@ -254,6 +332,11 @@ int64_t SrsHttpMessage::content_length() | @@ -254,6 +332,11 @@ int64_t SrsHttpMessage::content_length() | ||
| 254 | return _header.content_length; | 332 | return _header.content_length; |
| 255 | } | 333 | } |
| 256 | 334 | ||
| 335 | +SrsHttpHandlerMatch* SrsHttpMessage::match() | ||
| 336 | +{ | ||
| 337 | + return _match; | ||
| 338 | +} | ||
| 339 | + | ||
| 257 | void SrsHttpMessage::set_url(std::string url) | 340 | void SrsHttpMessage::set_url(std::string url) |
| 258 | { | 341 | { |
| 259 | _url = url; | 342 | _url = url; |
| @@ -269,6 +352,12 @@ void SrsHttpMessage::set_header(http_parser* header) | @@ -269,6 +352,12 @@ void SrsHttpMessage::set_header(http_parser* header) | ||
| 269 | memcpy(&_header, header, sizeof(http_parser)); | 352 | memcpy(&_header, header, sizeof(http_parser)); |
| 270 | } | 353 | } |
| 271 | 354 | ||
| 355 | +void SrsHttpMessage::set_match(SrsHttpHandlerMatch* match) | ||
| 356 | +{ | ||
| 357 | + srs_freep(_match); | ||
| 358 | + _match = match; | ||
| 359 | +} | ||
| 360 | + | ||
| 272 | void SrsHttpMessage::append_body(const char* body, int length) | 361 | void SrsHttpMessage::append_body(const char* body, int length) |
| 273 | { | 362 | { |
| 274 | _body->append(body, length); | 363 | _body->append(body, length); |
| @@ -489,22 +578,25 @@ int SrsHttpUri::initialize(std::string _url) | @@ -489,22 +578,25 @@ int SrsHttpUri::initialize(std::string _url) | ||
| 489 | path = get_uri_field(url, &hp_u, UF_PATH); | 578 | path = get_uri_field(url, &hp_u, UF_PATH); |
| 490 | srs_info("parse url %s success", purl); | 579 | srs_info("parse url %s success", purl); |
| 491 | 580 | ||
| 581 | + query = get_uri_field(url, &hp_u, UF_QUERY); | ||
| 582 | + srs_trace("parse query %s success", purl); | ||
| 583 | + | ||
| 492 | return ret; | 584 | return ret; |
| 493 | } | 585 | } |
| 494 | 586 | ||
| 495 | const char* SrsHttpUri::get_url() | 587 | const char* SrsHttpUri::get_url() |
| 496 | { | 588 | { |
| 497 | - return url.c_str(); | 589 | + return url.data(); |
| 498 | } | 590 | } |
| 499 | 591 | ||
| 500 | const char* SrsHttpUri::get_schema() | 592 | const char* SrsHttpUri::get_schema() |
| 501 | { | 593 | { |
| 502 | - return schema.c_str(); | 594 | + return schema.data(); |
| 503 | } | 595 | } |
| 504 | 596 | ||
| 505 | const char* SrsHttpUri::get_host() | 597 | const char* SrsHttpUri::get_host() |
| 506 | { | 598 | { |
| 507 | - return host.c_str(); | 599 | + return host.data(); |
| 508 | } | 600 | } |
| 509 | 601 | ||
| 510 | int SrsHttpUri::get_port() | 602 | int SrsHttpUri::get_port() |
| @@ -514,7 +606,12 @@ int SrsHttpUri::get_port() | @@ -514,7 +606,12 @@ int SrsHttpUri::get_port() | ||
| 514 | 606 | ||
| 515 | const char* SrsHttpUri::get_path() | 607 | const char* SrsHttpUri::get_path() |
| 516 | { | 608 | { |
| 517 | - return path.c_str(); | 609 | + return path.data(); |
| 610 | +} | ||
| 611 | + | ||
| 612 | +const char* SrsHttpUri::get_query() | ||
| 613 | +{ | ||
| 614 | + return path.data(); | ||
| 518 | } | 615 | } |
| 519 | 616 | ||
| 520 | std::string SrsHttpUri::get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field) | 617 | std::string SrsHttpUri::get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field) |
| @@ -42,7 +42,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -42,7 +42,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 42 | class SrsBuffer; | 42 | class SrsBuffer; |
| 43 | class SrsRequest; | 43 | class SrsRequest; |
| 44 | class SrsSocket; | 44 | class SrsSocket; |
| 45 | +class SrsHttpUri; | ||
| 45 | class SrsHttpMessage; | 46 | class SrsHttpMessage; |
| 47 | +class SrsHttpHandler; | ||
| 46 | 48 | ||
| 47 | // http specification | 49 | // http specification |
| 48 | // CR = <US-ASCII CR, carriage return (13)> | 50 | // CR = <US-ASCII CR, carriage return (13)> |
| @@ -62,6 +64,12 @@ class SrsHttpMessage; | @@ -62,6 +64,12 @@ class SrsHttpMessage; | ||
| 62 | 64 | ||
| 63 | // linux path seprator | 65 | // linux path seprator |
| 64 | #define __PATH_SEP '/' | 66 | #define __PATH_SEP '/' |
| 67 | +// query string seprator | ||
| 68 | +#define __QUERY_SEP '?' | ||
| 69 | + | ||
| 70 | +// compare the path. | ||
| 71 | +// full compare, extractly match. | ||
| 72 | +extern bool srs_path_equals(const char* expect, const char* path, int nb_path); | ||
| 65 | 73 | ||
| 66 | // state of message | 74 | // state of message |
| 67 | enum SrsHttpParseState { | 75 | enum SrsHttpParseState { |
| @@ -71,6 +79,18 @@ enum SrsHttpParseState { | @@ -71,6 +79,18 @@ enum SrsHttpParseState { | ||
| 71 | }; | 79 | }; |
| 72 | 80 | ||
| 73 | /** | 81 | /** |
| 82 | +* the matched handler info. | ||
| 83 | +*/ | ||
| 84 | +class SrsHttpHandlerMatch | ||
| 85 | +{ | ||
| 86 | +public: | ||
| 87 | + SrsHttpHandler* handler; | ||
| 88 | + std::string matched_url; | ||
| 89 | +public: | ||
| 90 | + SrsHttpHandlerMatch(); | ||
| 91 | +}; | ||
| 92 | + | ||
| 93 | +/** | ||
| 74 | * resource handler for HTTP RESTful api. | 94 | * resource handler for HTTP RESTful api. |
| 75 | */ | 95 | */ |
| 76 | class SrsHttpHandler | 96 | class SrsHttpHandler |
| @@ -90,21 +110,29 @@ public: | @@ -90,21 +110,29 @@ public: | ||
| 90 | virtual int initialize(); | 110 | virtual int initialize(); |
| 91 | /** | 111 | /** |
| 92 | * whether current handler can handle the specified path. | 112 | * whether current handler can handle the specified path. |
| 93 | - * @pnext_path set the next path, if needed. | 113 | + * @pchild set the next child path, if needed. |
| 114 | + * for example, the root handler will reset pchild to path, | ||
| 115 | + * to reparse the path use child handlers. | ||
| 94 | */ | 116 | */ |
| 95 | - virtual bool can_handle(const char* path, int length, const char** pnext_path); | 117 | + virtual bool can_handle(const char* path, int length, const char** pchild); |
| 96 | /** | 118 | /** |
| 97 | * use the handler to process the request. | 119 | * use the handler to process the request. |
| 120 | + * @remark sub classes should override the do_process_request. | ||
| 98 | */ | 121 | */ |
| 99 | - virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length); | 122 | + virtual int process_request(SrsSocket* skt, SrsHttpMessage* req); |
| 100 | public: | 123 | public: |
| 101 | /** | 124 | /** |
| 102 | * find the best matched handler | 125 | * find the best matched handler |
| 103 | */ | 126 | */ |
| 104 | - virtual int best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength); | 127 | + virtual int best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch); |
| 128 | +// factory methods | ||
| 129 | +protected: | ||
| 130 | + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | ||
| 131 | +// response writer | ||
| 105 | public: | 132 | public: |
| 106 | virtual SrsHttpHandler* res_status_line(std::stringstream& ss); | 133 | virtual SrsHttpHandler* res_status_line(std::stringstream& ss); |
| 107 | virtual SrsHttpHandler* res_content_type(std::stringstream& ss); | 134 | virtual SrsHttpHandler* res_content_type(std::stringstream& ss); |
| 135 | + virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss); | ||
| 108 | virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length); | 136 | virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length); |
| 109 | virtual SrsHttpHandler* res_enable_crossdomain(std::stringstream& ss); | 137 | virtual SrsHttpHandler* res_enable_crossdomain(std::stringstream& ss); |
| 110 | virtual SrsHttpHandler* res_header_eof(std::stringstream& ss); | 138 | virtual SrsHttpHandler* res_header_eof(std::stringstream& ss); |
| @@ -113,6 +141,8 @@ public: | @@ -113,6 +141,8 @@ public: | ||
| 113 | public: | 141 | public: |
| 114 | virtual int res_options(SrsSocket* skt); | 142 | virtual int res_options(SrsSocket* skt); |
| 115 | virtual int res_text(SrsSocket* skt, std::string body); | 143 | virtual int res_text(SrsSocket* skt, std::string body); |
| 144 | + virtual int res_json(SrsSocket* skt, std::string json); | ||
| 145 | +// object creator | ||
| 116 | public: | 146 | public: |
| 117 | /** | 147 | /** |
| 118 | * create http api resource handler. | 148 | * create http api resource handler. |
| @@ -148,23 +178,34 @@ private: | @@ -148,23 +178,34 @@ private: | ||
| 148 | * @remark, user can use is_complete() to determine the state. | 178 | * @remark, user can use is_complete() to determine the state. |
| 149 | */ | 179 | */ |
| 150 | SrsHttpParseState _state; | 180 | SrsHttpParseState _state; |
| 151 | - | 181 | + /** |
| 182 | + * uri parser | ||
| 183 | + */ | ||
| 184 | + SrsHttpUri* _uri; | ||
| 185 | + /** | ||
| 186 | + * best matched handler. | ||
| 187 | + */ | ||
| 188 | + SrsHttpHandlerMatch* _match; | ||
| 152 | public: | 189 | public: |
| 153 | SrsHttpMessage(); | 190 | SrsHttpMessage(); |
| 154 | virtual ~SrsHttpMessage(); | 191 | virtual ~SrsHttpMessage(); |
| 155 | - | ||
| 156 | public: | 192 | public: |
| 157 | virtual void reset(); | 193 | virtual void reset(); |
| 194 | + virtual int parse_uri(); | ||
| 158 | public: | 195 | public: |
| 159 | virtual bool is_complete(); | 196 | virtual bool is_complete(); |
| 160 | virtual u_int8_t method(); | 197 | virtual u_int8_t method(); |
| 161 | virtual std::string url(); | 198 | virtual std::string url(); |
| 199 | + virtual std::string path(); | ||
| 200 | + virtual std::string query(); | ||
| 162 | virtual std::string body(); | 201 | virtual std::string body(); |
| 163 | virtual int64_t body_size(); | 202 | virtual int64_t body_size(); |
| 164 | virtual int64_t content_length(); | 203 | virtual int64_t content_length(); |
| 204 | + virtual SrsHttpHandlerMatch* match(); | ||
| 165 | virtual void set_url(std::string url); | 205 | virtual void set_url(std::string url); |
| 166 | virtual void set_state(SrsHttpParseState state); | 206 | virtual void set_state(SrsHttpParseState state); |
| 167 | virtual void set_header(http_parser* header); | 207 | virtual void set_header(http_parser* header); |
| 208 | + virtual void set_match(SrsHttpHandlerMatch* match); | ||
| 168 | virtual void append_body(const char* body, int length); | 209 | virtual void append_body(const char* body, int length); |
| 169 | }; | 210 | }; |
| 170 | 211 | ||
| @@ -220,6 +261,7 @@ private: | @@ -220,6 +261,7 @@ private: | ||
| 220 | std::string host; | 261 | std::string host; |
| 221 | int port; | 262 | int port; |
| 222 | std::string path; | 263 | std::string path; |
| 264 | + std::string query; | ||
| 223 | public: | 265 | public: |
| 224 | SrsHttpUri(); | 266 | SrsHttpUri(); |
| 225 | virtual ~SrsHttpUri(); | 267 | virtual ~SrsHttpUri(); |
| @@ -234,6 +276,7 @@ public: | @@ -234,6 +276,7 @@ public: | ||
| 234 | virtual const char* get_host(); | 276 | virtual const char* get_host(); |
| 235 | virtual int get_port(); | 277 | virtual int get_port(); |
| 236 | virtual const char* get_path(); | 278 | virtual const char* get_path(); |
| 279 | + virtual const char* get_query(); | ||
| 237 | private: | 280 | private: |
| 238 | /** | 281 | /** |
| 239 | * get the parsed url field. | 282 | * get the parsed url field. |
| @@ -33,6 +33,7 @@ using namespace std; | @@ -33,6 +33,7 @@ using namespace std; | ||
| 33 | #include <srs_app_http.hpp> | 33 | #include <srs_app_http.hpp> |
| 34 | #include <srs_app_socket.hpp> | 34 | #include <srs_app_socket.hpp> |
| 35 | #include <srs_core_autofree.hpp> | 35 | #include <srs_core_autofree.hpp> |
| 36 | +#include <srs_app_json.hpp> | ||
| 36 | 37 | ||
| 37 | SrsApiRoot::SrsApiRoot() | 38 | SrsApiRoot::SrsApiRoot() |
| 38 | { | 39 | { |
| @@ -43,24 +44,28 @@ SrsApiRoot::~SrsApiRoot() | @@ -43,24 +44,28 @@ SrsApiRoot::~SrsApiRoot() | ||
| 43 | { | 44 | { |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | -bool SrsApiRoot::can_handle(const char* path, int length, const char** pnext_path) | 47 | +bool SrsApiRoot::can_handle(const char* path, int length, const char** pchild) |
| 47 | { | 48 | { |
| 48 | - // reset the next path for child to parse. | ||
| 49 | - *pnext_path = path; | 49 | + // reset the child path to path, |
| 50 | + // for child to reparse the path. | ||
| 51 | + *pchild = path; | ||
| 50 | 52 | ||
| 51 | - return true; | 53 | + // only compare the first char. |
| 54 | + return srs_path_equals("/", path, 1); | ||
| 52 | } | 55 | } |
| 53 | 56 | ||
| 54 | -int SrsApiRoot::process_request(SrsSocket* skt, SrsHttpMessage* req, const char* /*path*/, int /*length*/) | 57 | +int SrsApiRoot::do_process_request(SrsSocket* skt, SrsHttpMessage* req) |
| 55 | { | 58 | { |
| 56 | - if (req->method() == HTTP_OPTIONS) { | ||
| 57 | - return res_options(skt); | ||
| 58 | - } else { | ||
| 59 | - std::string body = "hello, root"; | ||
| 60 | - return res_text(skt, body); | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - return ERROR_SUCCESS; | 59 | + std::stringstream ss; |
| 60 | + | ||
| 61 | + ss << JOBJECT_START | ||
| 62 | + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT | ||
| 63 | + << JFIELD_ORG("urls", JOBJECT_START) | ||
| 64 | + << JFIELD_STR("v1", "the api version 1.0") | ||
| 65 | + << JOBJECT_END | ||
| 66 | + << JOBJECT_END; | ||
| 67 | + | ||
| 68 | + return res_json(skt, ss.str()); | ||
| 64 | } | 69 | } |
| 65 | 70 | ||
| 66 | SrsApiApi::SrsApiApi() | 71 | SrsApiApi::SrsApiApi() |
| @@ -71,21 +76,15 @@ SrsApiApi::~SrsApiApi() | @@ -71,21 +76,15 @@ SrsApiApi::~SrsApiApi() | ||
| 71 | { | 76 | { |
| 72 | } | 77 | } |
| 73 | 78 | ||
| 74 | -bool SrsApiApi::can_handle(const char* path, int length, const char** /*pnext_path*/) | 79 | +bool SrsApiApi::can_handle(const char* path, int length, const char** /*pchild*/) |
| 75 | { | 80 | { |
| 76 | - return !memcmp("/api", path, length); | 81 | + return srs_path_equals("/api", path, length); |
| 77 | } | 82 | } |
| 78 | 83 | ||
| 79 | -int SrsApiApi::process_request(SrsSocket* skt, SrsHttpMessage* req, const char* /*path*/, int /*length*/) | 84 | +int SrsApiApi::do_process_request(SrsSocket* skt, SrsHttpMessage* req) |
| 80 | { | 85 | { |
| 81 | - if (req->method() == HTTP_OPTIONS) { | ||
| 82 | - return res_options(skt); | ||
| 83 | - } else { | ||
| 84 | - std::string body = "hello, api"; | ||
| 85 | - return res_text(skt, body); | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - return ERROR_SUCCESS; | 86 | + std::string body = "hello, api"; |
| 87 | + return res_text(skt, body); | ||
| 89 | } | 88 | } |
| 90 | 89 | ||
| 91 | SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler) | 90 | SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler) |
| @@ -147,25 +146,31 @@ int SrsHttpApi::do_cycle() | @@ -147,25 +146,31 @@ int SrsHttpApi::do_cycle() | ||
| 147 | int SrsHttpApi::process_request(SrsSocket* skt, SrsHttpMessage* req) | 146 | int SrsHttpApi::process_request(SrsSocket* skt, SrsHttpMessage* req) |
| 148 | { | 147 | { |
| 149 | int ret = ERROR_SUCCESS; | 148 | int ret = ERROR_SUCCESS; |
| 149 | + | ||
| 150 | + // parse uri to schema/server:port/path?query | ||
| 151 | + if ((ret = req->parse_uri()) != ERROR_SUCCESS) { | ||
| 152 | + return ret; | ||
| 153 | + } | ||
| 150 | 154 | ||
| 151 | // TODO: maybe need to parse the url. | 155 | // TODO: maybe need to parse the url. |
| 152 | - std::string uri = req->url(); | 156 | + std::string url = req->path(); |
| 153 | 157 | ||
| 154 | - int length = 0; | ||
| 155 | - const char* start = NULL; | ||
| 156 | - SrsHttpHandler* p = NULL; | ||
| 157 | - if ((ret = handler->best_match(uri.data(), uri.length(), &p, &start, &length)) != ERROR_SUCCESS) { | 158 | + SrsHttpHandlerMatch* p = NULL; |
| 159 | + if ((ret = handler->best_match(url.data(), url.length(), &p)) != ERROR_SUCCESS) { | ||
| 158 | srs_warn("failed to find the best match handler for url. ret=%d", ret); | 160 | srs_warn("failed to find the best match handler for url. ret=%d", ret); |
| 159 | return ret; | 161 | return ret; |
| 160 | } | 162 | } |
| 161 | 163 | ||
| 162 | // if success, p and pstart should be valid. | 164 | // if success, p and pstart should be valid. |
| 163 | srs_assert(p); | 165 | srs_assert(p); |
| 164 | - srs_assert(start); | ||
| 165 | - srs_assert(length <= (int)uri.length()); | 166 | + srs_assert(p->handler); |
| 167 | + srs_assert(p->matched_url.length() <= url.length()); | ||
| 168 | + srs_info("best match handler, matched_url=%s", p->matched_url.c_str()); | ||
| 169 | + | ||
| 170 | + req->set_match(p); | ||
| 166 | 171 | ||
| 167 | // use handler to process request. | 172 | // use handler to process request. |
| 168 | - if ((ret = p->process_request(skt, req, start, length)) != ERROR_SUCCESS) { | 173 | + if ((ret = p->handler->process_request(skt, req)) != ERROR_SUCCESS) { |
| 169 | srs_warn("handler failed to process http request. ret=%d", ret); | 174 | srs_warn("handler failed to process http request. ret=%d", ret); |
| 170 | return ret; | 175 | return ret; |
| 171 | } | 176 | } |
| @@ -48,8 +48,8 @@ public: | @@ -48,8 +48,8 @@ public: | ||
| 48 | SrsApiRoot(); | 48 | SrsApiRoot(); |
| 49 | virtual ~SrsApiRoot(); | 49 | virtual ~SrsApiRoot(); |
| 50 | public: | 50 | public: |
| 51 | - virtual bool can_handle(const char* path, int length, const char** pnext_path); | ||
| 52 | - virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length); | 51 | + virtual bool can_handle(const char* path, int length, const char** pchild); |
| 52 | + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | ||
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | class SrsApiApi : public SrsHttpHandler | 55 | class SrsApiApi : public SrsHttpHandler |
| @@ -58,8 +58,8 @@ public: | @@ -58,8 +58,8 @@ public: | ||
| 58 | SrsApiApi(); | 58 | SrsApiApi(); |
| 59 | virtual ~SrsApiApi(); | 59 | virtual ~SrsApiApi(); |
| 60 | public: | 60 | public: |
| 61 | - virtual bool can_handle(const char* path, int length, const char** pnext_path); | ||
| 62 | - virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length); | 61 | + virtual bool can_handle(const char* path, int length, const char** pchild); |
| 62 | + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); | ||
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | class SrsHttpApi : public SrsConnection | 65 | class SrsHttpApi : public SrsConnection |
| @@ -35,6 +35,7 @@ using namespace std; | @@ -35,6 +35,7 @@ using namespace std; | ||
| 35 | #include <srs_kernel_log.hpp> | 35 | #include <srs_kernel_log.hpp> |
| 36 | #include <srs_app_socket.hpp> | 36 | #include <srs_app_socket.hpp> |
| 37 | #include <srs_app_http.hpp> | 37 | #include <srs_app_http.hpp> |
| 38 | +#include <srs_app_json.hpp> | ||
| 38 | 39 | ||
| 39 | #define SRS_HTTP_RESPONSE_OK "0" | 40 | #define SRS_HTTP_RESPONSE_OK "0" |
| 40 | 41 | ||
| @@ -202,32 +203,14 @@ int SrsHttpHooks::on_connect(std::string url, int client_id, std::string ip, Srs | @@ -202,32 +203,14 @@ int SrsHttpHooks::on_connect(std::string url, int client_id, std::string ip, Srs | ||
| 202 | } | 203 | } |
| 203 | */ | 204 | */ |
| 204 | std::stringstream ss; | 205 | std::stringstream ss; |
| 205 | - ss << "{" | ||
| 206 | - // action | ||
| 207 | - << '"' << "action" << '"' << ':' | ||
| 208 | - << '"' << "on_connect" << '"' | ||
| 209 | - << ',' | ||
| 210 | - // client_id | ||
| 211 | - << '"' << "client_id" << '"' << ':' | ||
| 212 | - << std::dec << client_id | ||
| 213 | - << ',' | ||
| 214 | - // ip | ||
| 215 | - << '"' << "ip" << '"' << ':' | ||
| 216 | - << '"' << ip << '"' | ||
| 217 | - << ',' | ||
| 218 | - // vhost | ||
| 219 | - << '"' << "vhost" << '"' << ':' | ||
| 220 | - << '"' << req->vhost << '"' | ||
| 221 | - << ',' | ||
| 222 | - // app | ||
| 223 | - << '"' << "app" << '"' << ':' | ||
| 224 | - << '"' << req->app << '"' | ||
| 225 | - << ',' | ||
| 226 | - // pageUrl | ||
| 227 | - << '"' << "pageUrl" << '"' << ':' | ||
| 228 | - << '"' << req->pageUrl << '"' | ||
| 229 | - //<< ',' | ||
| 230 | - << "}"; | 206 | + ss << JOBJECT_START |
| 207 | + << JFIELD_STR("action", "on_connect") << JFIELD_CONT | ||
| 208 | + << JFIELD_ORG("client_id", client_id) << JFIELD_CONT | ||
| 209 | + << JFIELD_STR("ip", ip) << JFIELD_CONT | ||
| 210 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
| 211 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
| 212 | + << JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT | ||
| 213 | + << JOBJECT_END; | ||
| 231 | std::string data = ss.str(); | 214 | std::string data = ss.str(); |
| 232 | std::string res; | 215 | std::string res; |
| 233 | 216 | ||
| @@ -273,28 +256,14 @@ void SrsHttpHooks::on_close(std::string url, int client_id, std::string ip, SrsR | @@ -273,28 +256,14 @@ void SrsHttpHooks::on_close(std::string url, int client_id, std::string ip, SrsR | ||
| 273 | } | 256 | } |
| 274 | */ | 257 | */ |
| 275 | std::stringstream ss; | 258 | std::stringstream ss; |
| 276 | - ss << "{" | ||
| 277 | - // action | ||
| 278 | - << '"' << "action" << '"' << ':' | ||
| 279 | - << '"' << "on_close" << '"' | ||
| 280 | - << ',' | ||
| 281 | - // client_id | ||
| 282 | - << '"' << "client_id" << '"' << ':' | ||
| 283 | - << std::dec << client_id | ||
| 284 | - << ',' | ||
| 285 | - // ip | ||
| 286 | - << '"' << "ip" << '"' << ':' | ||
| 287 | - << '"' << ip << '"' | ||
| 288 | - << ',' | ||
| 289 | - // vhost | ||
| 290 | - << '"' << "vhost" << '"' << ':' | ||
| 291 | - << '"' << req->vhost << '"' | ||
| 292 | - << ',' | ||
| 293 | - // app | ||
| 294 | - << '"' << "app" << '"' << ':' | ||
| 295 | - << '"' << req->app << '"' | ||
| 296 | - //<< ',' | ||
| 297 | - << "}"; | 259 | + ss << JOBJECT_START |
| 260 | + << JFIELD_STR("action", "on_close") << JFIELD_CONT | ||
| 261 | + << JFIELD_ORG("client_id", client_id) << JFIELD_CONT | ||
| 262 | + << JFIELD_STR("ip", ip) << JFIELD_CONT | ||
| 263 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
| 264 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
| 265 | + << JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT | ||
| 266 | + << JOBJECT_END; | ||
| 298 | std::string data = ss.str(); | 267 | std::string data = ss.str(); |
| 299 | std::string res; | 268 | std::string res; |
| 300 | 269 | ||
| @@ -340,32 +309,15 @@ int SrsHttpHooks::on_publish(std::string url, int client_id, std::string ip, Srs | @@ -340,32 +309,15 @@ int SrsHttpHooks::on_publish(std::string url, int client_id, std::string ip, Srs | ||
| 340 | } | 309 | } |
| 341 | */ | 310 | */ |
| 342 | std::stringstream ss; | 311 | std::stringstream ss; |
| 343 | - ss << "{" | ||
| 344 | - // action | ||
| 345 | - << '"' << "action" << '"' << ':' | ||
| 346 | - << '"' << "on_publish" << '"' | ||
| 347 | - << ',' | ||
| 348 | - // client_id | ||
| 349 | - << '"' << "client_id" << '"' << ':' | ||
| 350 | - << std::dec << client_id | ||
| 351 | - << ',' | ||
| 352 | - // ip | ||
| 353 | - << '"' << "ip" << '"' << ':' | ||
| 354 | - << '"' << ip << '"' | ||
| 355 | - << ',' | ||
| 356 | - // vhost | ||
| 357 | - << '"' << "vhost" << '"' << ':' | ||
| 358 | - << '"' << req->vhost << '"' | ||
| 359 | - << ',' | ||
| 360 | - // app | ||
| 361 | - << '"' << "app" << '"' << ':' | ||
| 362 | - << '"' << req->app << '"' | ||
| 363 | - << ',' | ||
| 364 | - // stream | ||
| 365 | - << '"' << "stream" << '"' << ':' | ||
| 366 | - << '"' << req->stream << '"' | ||
| 367 | - //<< ',' | ||
| 368 | - << "}"; | 312 | + ss << JOBJECT_START |
| 313 | + << JFIELD_STR("action", "on_publish") << JFIELD_CONT | ||
| 314 | + << JFIELD_ORG("client_id", client_id) << JFIELD_CONT | ||
| 315 | + << JFIELD_STR("ip", ip) << JFIELD_CONT | ||
| 316 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
| 317 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
| 318 | + << JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT | ||
| 319 | + << JFIELD_STR("stream", req->stream) << JFIELD_CONT | ||
| 320 | + << JOBJECT_END; | ||
| 369 | std::string data = ss.str(); | 321 | std::string data = ss.str(); |
| 370 | std::string res; | 322 | std::string res; |
| 371 | 323 | ||
| @@ -411,32 +363,15 @@ void SrsHttpHooks::on_unpublish(std::string url, int client_id, std::string ip, | @@ -411,32 +363,15 @@ void SrsHttpHooks::on_unpublish(std::string url, int client_id, std::string ip, | ||
| 411 | } | 363 | } |
| 412 | */ | 364 | */ |
| 413 | std::stringstream ss; | 365 | std::stringstream ss; |
| 414 | - ss << "{" | ||
| 415 | - // action | ||
| 416 | - << '"' << "action" << '"' << ':' | ||
| 417 | - << '"' << "on_unpublish" << '"' | ||
| 418 | - << ',' | ||
| 419 | - // client_id | ||
| 420 | - << '"' << "client_id" << '"' << ':' | ||
| 421 | - << std::dec << client_id | ||
| 422 | - << ',' | ||
| 423 | - // ip | ||
| 424 | - << '"' << "ip" << '"' << ':' | ||
| 425 | - << '"' << ip << '"' | ||
| 426 | - << ',' | ||
| 427 | - // vhost | ||
| 428 | - << '"' << "vhost" << '"' << ':' | ||
| 429 | - << '"' << req->vhost << '"' | ||
| 430 | - << ',' | ||
| 431 | - // app | ||
| 432 | - << '"' << "app" << '"' << ':' | ||
| 433 | - << '"' << req->app << '"' | ||
| 434 | - << ',' | ||
| 435 | - // stream | ||
| 436 | - << '"' << "stream" << '"' << ':' | ||
| 437 | - << '"' << req->stream << '"' | ||
| 438 | - //<< ',' | ||
| 439 | - << "}"; | 366 | + ss << JOBJECT_START |
| 367 | + << JFIELD_STR("action", "on_unpublish") << JFIELD_CONT | ||
| 368 | + << JFIELD_ORG("client_id", client_id) << JFIELD_CONT | ||
| 369 | + << JFIELD_STR("ip", ip) << JFIELD_CONT | ||
| 370 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
| 371 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
| 372 | + << JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT | ||
| 373 | + << JFIELD_STR("stream", req->stream) << JFIELD_CONT | ||
| 374 | + << JOBJECT_END; | ||
| 440 | std::string data = ss.str(); | 375 | std::string data = ss.str(); |
| 441 | std::string res; | 376 | std::string res; |
| 442 | 377 | ||
| @@ -482,32 +417,15 @@ int SrsHttpHooks::on_play(std::string url, int client_id, std::string ip, SrsReq | @@ -482,32 +417,15 @@ int SrsHttpHooks::on_play(std::string url, int client_id, std::string ip, SrsReq | ||
| 482 | } | 417 | } |
| 483 | */ | 418 | */ |
| 484 | std::stringstream ss; | 419 | std::stringstream ss; |
| 485 | - ss << "{" | ||
| 486 | - // action | ||
| 487 | - << '"' << "action" << '"' << ':' | ||
| 488 | - << '"' << "on_play" << '"' | ||
| 489 | - << ',' | ||
| 490 | - // client_id | ||
| 491 | - << '"' << "client_id" << '"' << ':' | ||
| 492 | - << std::dec << client_id | ||
| 493 | - << ',' | ||
| 494 | - // ip | ||
| 495 | - << '"' << "ip" << '"' << ':' | ||
| 496 | - << '"' << ip << '"' | ||
| 497 | - << ',' | ||
| 498 | - // vhost | ||
| 499 | - << '"' << "vhost" << '"' << ':' | ||
| 500 | - << '"' << req->vhost << '"' | ||
| 501 | - << ',' | ||
| 502 | - // app | ||
| 503 | - << '"' << "app" << '"' << ':' | ||
| 504 | - << '"' << req->app << '"' | ||
| 505 | - << ',' | ||
| 506 | - // stream | ||
| 507 | - << '"' << "stream" << '"' << ':' | ||
| 508 | - << '"' << req->stream << '"' | ||
| 509 | - //<< ',' | ||
| 510 | - << "}"; | 420 | + ss << JOBJECT_START |
| 421 | + << JFIELD_STR("action", "on_play") << JFIELD_CONT | ||
| 422 | + << JFIELD_ORG("client_id", client_id) << JFIELD_CONT | ||
| 423 | + << JFIELD_STR("ip", ip) << JFIELD_CONT | ||
| 424 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
| 425 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
| 426 | + << JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT | ||
| 427 | + << JFIELD_STR("stream", req->stream) << JFIELD_CONT | ||
| 428 | + << JOBJECT_END; | ||
| 511 | std::string data = ss.str(); | 429 | std::string data = ss.str(); |
| 512 | std::string res; | 430 | std::string res; |
| 513 | 431 | ||
| @@ -553,32 +471,15 @@ void SrsHttpHooks::on_stop(std::string url, int client_id, std::string ip, SrsRe | @@ -553,32 +471,15 @@ void SrsHttpHooks::on_stop(std::string url, int client_id, std::string ip, SrsRe | ||
| 553 | } | 471 | } |
| 554 | */ | 472 | */ |
| 555 | std::stringstream ss; | 473 | std::stringstream ss; |
| 556 | - ss << "{" | ||
| 557 | - // action | ||
| 558 | - << '"' << "action" << '"' << ':' | ||
| 559 | - << '"' << "on_stop" << '"' | ||
| 560 | - << ',' | ||
| 561 | - // client_id | ||
| 562 | - << '"' << "client_id" << '"' << ':' | ||
| 563 | - << std::dec << client_id | ||
| 564 | - << ',' | ||
| 565 | - // ip | ||
| 566 | - << '"' << "ip" << '"' << ':' | ||
| 567 | - << '"' << ip << '"' | ||
| 568 | - << ',' | ||
| 569 | - // vhost | ||
| 570 | - << '"' << "vhost" << '"' << ':' | ||
| 571 | - << '"' << req->vhost << '"' | ||
| 572 | - << ',' | ||
| 573 | - // app | ||
| 574 | - << '"' << "app" << '"' << ':' | ||
| 575 | - << '"' << req->app << '"' | ||
| 576 | - << ',' | ||
| 577 | - // stream | ||
| 578 | - << '"' << "stream" << '"' << ':' | ||
| 579 | - << '"' << req->stream << '"' | ||
| 580 | - //<< ',' | ||
| 581 | - << "}"; | 474 | + ss << JOBJECT_START |
| 475 | + << JFIELD_STR("action", "on_stop") << JFIELD_CONT | ||
| 476 | + << JFIELD_ORG("client_id", client_id) << JFIELD_CONT | ||
| 477 | + << JFIELD_STR("ip", ip) << JFIELD_CONT | ||
| 478 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
| 479 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
| 480 | + << JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT | ||
| 481 | + << JFIELD_STR("stream", req->stream) << JFIELD_CONT | ||
| 482 | + << JOBJECT_END; | ||
| 582 | std::string data = ss.str(); | 483 | std::string data = ss.str(); |
| 583 | std::string res; | 484 | std::string res; |
| 584 | 485 |
trunk/src/app/srs_app_json.cpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#include <srs_app_json.hpp> |
trunk/src/app/srs_app_json.hpp
0 → 100644
| 1 | +/* | ||
| 2 | +The MIT License (MIT) | ||
| 3 | + | ||
| 4 | +Copyright (c) 2013-2014 winlin | ||
| 5 | + | ||
| 6 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 7 | +this software and associated documentation files (the "Software"), to deal in | ||
| 8 | +the Software without restriction, including without limitation the rights to | ||
| 9 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
| 10 | +the Software, and to permit persons to whom the Software is furnished to do so, | ||
| 11 | +subject to the following conditions: | ||
| 12 | + | ||
| 13 | +The above copyright notice and this permission notice shall be included in all | ||
| 14 | +copies or substantial portions of the Software. | ||
| 15 | + | ||
| 16 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
| 18 | +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
| 19 | +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
| 20 | +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
| 21 | +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 22 | +*/ | ||
| 23 | + | ||
| 24 | +#ifndef SRS_APP_JSON_HPP | ||
| 25 | +#define SRS_APP_JSON_HPP | ||
| 26 | + | ||
| 27 | +/* | ||
| 28 | +#include <srs_app_json.hpp> | ||
| 29 | +*/ | ||
| 30 | +#include <srs_core.hpp> | ||
| 31 | + | ||
| 32 | +// json encode macros | ||
| 33 | +#define JOBJECT_START "{" | ||
| 34 | +#define JFIELD_STR(k, v) "\"" << k << "\":\"" << v << "\"" | ||
| 35 | +#define JFIELD_ORG(k, v) "\"" << k << "\":" << std::dec << v | ||
| 36 | +#define JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret | ||
| 37 | +#define JFIELD_CONT "," | ||
| 38 | +#define JOBJECT_END "}" | ||
| 39 | + | ||
| 40 | +#endif |
| @@ -61,6 +61,8 @@ file | @@ -61,6 +61,8 @@ file | ||
| 61 | ..\app\srs_app_http_conn.cpp, | 61 | ..\app\srs_app_http_conn.cpp, |
| 62 | ..\app\srs_app_http_hooks.hpp, | 62 | ..\app\srs_app_http_hooks.hpp, |
| 63 | ..\app\srs_app_http_hooks.cpp, | 63 | ..\app\srs_app_http_hooks.cpp, |
| 64 | + ..\app\srs_app_json.hpp, | ||
| 65 | + ..\app\srs_app_json.cpp, | ||
| 64 | ..\app\srs_app_log.hpp, | 66 | ..\app\srs_app_log.hpp, |
| 65 | ..\app\srs_app_log.cpp, | 67 | ..\app\srs_app_log.cpp, |
| 66 | ..\app\srs_app_refer.hpp, | 68 | ..\app\srs_app_refer.hpp, |
-
请 注册 或 登录 后发表评论