diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index e05a28676..fb0659673 100755 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -112,6 +112,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) << SRS_JFIELD_STR("requests", "the request itself, for http debug") << SRS_JFIELD_CONT << SRS_JFIELD_STR("vhosts", "dumps vhost to json") << SRS_JFIELD_CONT << SRS_JFIELD_STR("streams", "dumps streams to json") << SRS_JFIELD_CONT + << SRS_JFIELD_STR("clients", "dumps clients to json") << SRS_JFIELD_CONT << SRS_JFIELD_ORG("test", SRS_JOBJECT_START) << SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT << SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT @@ -468,18 +469,13 @@ SrsGoApiStreams::~SrsGoApiStreams() int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) { int ret = ERROR_SUCCESS; + SrsStatistic* stat = SrsStatistic::instance(); std::stringstream ss; // path: {pattern}{stream_id} // e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100 - int sid = -1; - if (true) { - string stream_id = r->path().substr((int)entry->pattern.length()); - if (!stream_id.empty()) { - sid = ::atoi(stream_id.c_str()); - } - } + int sid = r->parse_rest_id(entry->pattern); SrsStatisticStream* stream = NULL; if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) { @@ -537,6 +533,44 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) return ret; } +SrsGoApiClients::SrsGoApiClients() +{ +} + +SrsGoApiClients::~SrsGoApiClients() +{ +} + +int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) +{ + int ret = ERROR_SUCCESS; + + SrsStatistic* stat = SrsStatistic::instance(); + std::stringstream ss; + + // path: {pattern}{client_id} + // e.g. /api/v1/clients/100 pattern= /api/v1/clients/, client_id=100 + int cid = r->parse_rest_id(entry->pattern); + + SrsStatisticClient* client = NULL; + // TODO: FIXME: implements it. + /*if (cid >= 0 && (client = stat->find_client(cid)) == NULL) { + ret = ERROR_RTMP_STREAM_NOT_FOUND; + srs_error("stream client_id=%d not found. ret=%d", cid, ret); + + ss << SRS_JOBJECT_START << SRS_JFIELD_ERROR(ret) << SRS_JOBJECT_END; + + return srs_http_response_json(w, ss.str()); + + }*/ + + if (r->is_http_get()) { + + } + + return ret; +} + SrsGoApiError::SrsGoApiError() { } diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index cdc5d0af0..8bb3124f2 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -159,6 +159,15 @@ public: virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; +class SrsGoApiClients : public ISrsHttpHandler +{ +public: + SrsGoApiClients(); + virtual ~SrsGoApiClients(); +public: + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); +}; + class SrsGoApiError : public ISrsHttpHandler { public: diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index d4637cc01..b74830eeb 100755 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -654,6 +654,7 @@ string SrsHttpMessage::uri() uri += host(); uri += path(); + return uri; } @@ -677,6 +678,21 @@ string SrsHttpMessage::ext() return _ext; } +int SrsHttpMessage::parse_rest_id(string pattern) +{ + string p = _uri->get_path(); + if (p.length() <= pattern.length()) { + return -1; + } + + string id = p.substr((int)pattern.length()); + if (!id.empty()) { + return ::atoi(id.c_str()); + } + + return -1; +} + int SrsHttpMessage::body_read_all(string& body) { int ret = ERROR_SUCCESS; diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index 7bc06cd01..731a00b6f 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -246,6 +246,10 @@ public: virtual std::string host(); virtual std::string path(); virtual std::string ext(); + /** + * get the RESTful matched id. + */ + virtual int parse_rest_id(std::string pattern); public: /** * read body to string. diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index ace385252..afc82e965 100755 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -773,10 +773,10 @@ int SrsServer::http_handle() if ((ret = http_api_mux->handle("/", new SrsHttpNotFoundHandler())) != ERROR_SUCCESS) { return ret; } - if ((ret = http_api_mux->handle("/api", new SrsGoApiApi())) != ERROR_SUCCESS) { + if ((ret = http_api_mux->handle("/api/", new SrsGoApiApi())) != ERROR_SUCCESS) { return ret; } - if ((ret = http_api_mux->handle("/api/v1", new SrsGoApiV1())) != ERROR_SUCCESS) { + if ((ret = http_api_mux->handle("/api/v1/", new SrsGoApiV1())) != ERROR_SUCCESS) { return ret; } if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) { @@ -800,12 +800,15 @@ int SrsServer::http_handle() if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) { return ret; } - if ((ret = http_api_mux->handle("/api/v1/vhosts", new SrsGoApiVhosts())) != ERROR_SUCCESS) { + if ((ret = http_api_mux->handle("/api/v1/vhosts/", new SrsGoApiVhosts())) != ERROR_SUCCESS) { return ret; } if ((ret = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != ERROR_SUCCESS) { return ret; } + if ((ret = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != ERROR_SUCCESS) { + return ret; + } // test the request info. if ((ret = http_api_mux->handle("/api/v1/test/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) { diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index 172dfbf45..f8dcafb89 100755 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -143,6 +143,14 @@ int srs_http_response_json(ISrsHttpResponseWriter* w, string data) return w->write((char*)data.data(), (int)data.length()); } +int srs_http_response_code(ISrsHttpResponseWriter* w, int code) +{ + std::stringstream ss; + // TODO: FIXME: implements it. + //ss << SRS_JOBJECT_START << SRS_JFIELD_ERROR(code) << SRS_JOBJECT_END; + return srs_http_response_json(w, ss.str()); +} + SrsHttpHeader::SrsHttpHeader() { } diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index bf12477ac..2b683a6af 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -78,6 +78,7 @@ class ISrsHttpResponseWriter; // helper function: response in json format. extern int srs_http_response_json(ISrsHttpResponseWriter* w, std::string data); +extern int srs_http_response_code(ISrsHttpResponseWriter* w, int code); // get the status text of code. extern std::string srs_generate_http_status_text(int status); @@ -488,6 +489,14 @@ public: virtual std::string host() = 0; virtual std::string path() = 0; virtual std::string ext() = 0; + /** + * get the RESTful id, + * for example, pattern is /api/v1/streams, path is /api/v1/streams/100, + * then the rest id is 100. + * @param pattern the handler pattern which will serve the request. + * @return the REST id; -1 if not matched. + */ + virtual int parse_rest_id(std::string pattern) = 0; public: /** * read body to string.