1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

HTTP API support JSONP by specifies the query string callback=xxx.

This commit is contained in:
winlin 2015-08-22 18:18:18 +08:00
parent aeebddb269
commit 6e5143449e
6 changed files with 148 additions and 74 deletions

View file

@ -342,6 +342,7 @@ Remark:
## History ## History
* v2.0, 2015-08-22, HTTP API support JSONP by specifies the query string callback=xxx.
* v2.0, 2015-08-20, fix [#380](https://github.com/simple-rtmp-server/srs/issues/380), srs-librtmp send sequence header when sps or pps changed. * v2.0, 2015-08-20, fix [#380](https://github.com/simple-rtmp-server/srs/issues/380), srs-librtmp send sequence header when sps or pps changed.
* v2.0, 2015-08-18, close [#454](https://github.com/simple-rtmp-server/srs/issues/454), support obs restart publish. 2.0.184 * v2.0, 2015-08-18, close [#454](https://github.com/simple-rtmp-server/srs/issues/454), support obs restart publish. 2.0.184
* v2.0, 2015-08-14, use reduce_sequence_header for stream control. * v2.0, 2015-08-14, use reduce_sequence_header for stream control.

View file

@ -43,6 +43,95 @@ using namespace std;
#include <srs_app_source.hpp> #include <srs_app_source.hpp>
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>
int srs_api_response_jsonp(ISrsHttpResponseWriter* w, string callback, string data)
{
int ret = ERROR_SUCCESS;
SrsHttpHeader* h = w->header();
h->set_content_length(data.length() + callback.length() + 2);
h->set_content_type("text/javascript");
if (!callback.empty() && (ret = w->write((char*)callback.data(), (int)callback.length())) != ERROR_SUCCESS) {
return ret;
}
static char* c0 = (char*)"(";
if ((ret = w->write(c0, 1)) != ERROR_SUCCESS) {
return ret;
}
if ((ret = w->write((char*)data.data(), (int)data.length())) != ERROR_SUCCESS) {
return ret;
}
static char* c1 = (char*)")";
if ((ret = w->write(c1, 1)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int srs_api_response_jsonp_code(ISrsHttpResponseWriter* w, string callback, int code)
{
std::stringstream ss;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(code)
<< SRS_JOBJECT_END;
return srs_api_response_jsonp(w, callback, ss.str());
}
int srs_api_response_json(ISrsHttpResponseWriter* w, string data)
{
SrsHttpHeader* h = w->header();
h->set_content_length(data.length());
h->set_content_type("application/json");
return w->write((char*)data.data(), (int)data.length());
}
int srs_api_response_json_code(ISrsHttpResponseWriter* w, int code)
{
std::stringstream ss;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(code)
<< SRS_JOBJECT_END;
return srs_api_response_json(w, ss.str());
}
int srs_api_response(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string json)
{
string callback = r->query_get("callback");
bool jsonp = !callback.empty();
// no jsonp, directly response.
if (!jsonp) {
return srs_api_response_json(w, json);
}
// jsonp, get function name from query("callback")
return srs_api_response_jsonp(w, callback, json);
}
int srs_api_response_code(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, int code)
{
string callback = r->query_get("callback");
bool jsonp = !callback.empty();
// no jsonp, directly response.
if (!jsonp) {
return srs_api_response_json_code(w, code);
}
// jsonp, get function name from query("callback")
return srs_api_response_jsonp_code(w, callback, code);
}
SrsGoApiRoot::SrsGoApiRoot() SrsGoApiRoot::SrsGoApiRoot()
{ {
} }
@ -64,7 +153,7 @@ int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiApi::SrsGoApiApi() SrsGoApiApi::SrsGoApiApi()
@ -88,7 +177,7 @@ int SrsGoApiApi::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiV1::SrsGoApiV1() SrsGoApiV1::SrsGoApiV1()
@ -129,7 +218,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiVersion::SrsGoApiVersion() SrsGoApiVersion::SrsGoApiVersion()
@ -156,7 +245,7 @@ int SrsGoApiVersion::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiSummaries::SrsGoApiSummaries() SrsGoApiSummaries::SrsGoApiSummaries()
@ -171,7 +260,7 @@ int SrsGoApiSummaries::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
std::stringstream ss; std::stringstream ss;
srs_api_dump_summaries(ss); srs_api_dump_summaries(ss);
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiRusages::SrsGoApiRusages() SrsGoApiRusages::SrsGoApiRusages()
@ -182,39 +271,39 @@ SrsGoApiRusages::~SrsGoApiRusages()
{ {
} }
int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* req) int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
SrsStatistic* stat = SrsStatistic::instance(); SrsStatistic* stat = SrsStatistic::instance();
std::stringstream ss; std::stringstream ss;
SrsRusage* r = srs_get_system_rusage(); SrsRusage* ru = srs_get_system_rusage();
ss << SRS_JOBJECT_START ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(ERROR_SUCCESS) << SRS_JFIELD_CONT << SRS_JFIELD_ERROR(ERROR_SUCCESS) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("data", SRS_JOBJECT_START) << SRS_JFIELD_ORG("data", SRS_JOBJECT_START)
<< SRS_JFIELD_ORG("ok", (r->ok? "true":"false")) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ok", (ru->ok? "true":"false")) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("sample_time", r->sample_time) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("sample_time", ru->sample_time) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_utime", r->r.ru_utime.tv_sec) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_utime", ru->r.ru_utime.tv_sec) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_stime", r->r.ru_stime.tv_sec) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_stime", ru->r.ru_stime.tv_sec) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_maxrss", r->r.ru_maxrss) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_maxrss", ru->r.ru_maxrss) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_ixrss", r->r.ru_ixrss) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_ixrss", ru->r.ru_ixrss) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_idrss", r->r.ru_idrss) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_idrss", ru->r.ru_idrss) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_isrss", r->r.ru_isrss) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_isrss", ru->r.ru_isrss) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_minflt", r->r.ru_minflt) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_minflt", ru->r.ru_minflt) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_majflt", r->r.ru_majflt) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_majflt", ru->r.ru_majflt) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_nswap", r->r.ru_nswap) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_nswap", ru->r.ru_nswap) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_inblock", r->r.ru_inblock) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_inblock", ru->r.ru_inblock) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_oublock", r->r.ru_oublock) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_oublock", ru->r.ru_oublock) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_msgsnd", r->r.ru_msgsnd) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_msgsnd", ru->r.ru_msgsnd) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_msgrcv", r->r.ru_msgrcv) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_msgrcv", ru->r.ru_msgrcv) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_nsignals", r->r.ru_nsignals) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_nsignals", ru->r.ru_nsignals) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_nvcsw", r->r.ru_nvcsw) << SRS_JFIELD_CONT << SRS_JFIELD_ORG("ru_nvcsw", ru->r.ru_nvcsw) << SRS_JFIELD_CONT
<< SRS_JFIELD_ORG("ru_nivcsw", r->r.ru_nivcsw) << SRS_JFIELD_ORG("ru_nivcsw", ru->r.ru_nivcsw)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiSelfProcStats::SrsGoApiSelfProcStats() SrsGoApiSelfProcStats::SrsGoApiSelfProcStats()
@ -286,7 +375,7 @@ int SrsGoApiSelfProcStats::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiSystemProcStats::SrsGoApiSystemProcStats() SrsGoApiSystemProcStats::SrsGoApiSystemProcStats()
@ -323,7 +412,7 @@ int SrsGoApiSystemProcStats::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiMemInfos::SrsGoApiMemInfos() SrsGoApiMemInfos::SrsGoApiMemInfos()
@ -361,7 +450,7 @@ int SrsGoApiMemInfos::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiAuthors::SrsGoApiAuthors() SrsGoApiAuthors::SrsGoApiAuthors()
@ -390,7 +479,7 @@ int SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiFeatures::SrsGoApiFeatures() SrsGoApiFeatures::SrsGoApiFeatures()
@ -516,7 +605,7 @@ int SrsGoApiFeatures::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiRequests::SrsGoApiRequests() SrsGoApiRequests::SrsGoApiRequests()
@ -579,7 +668,7 @@ int SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END << SRS_JOBJECT_END
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiVhosts::SrsGoApiVhosts() SrsGoApiVhosts::SrsGoApiVhosts()
@ -605,7 +694,7 @@ int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
if (vid > 0 && (vhost = stat->find_vhost(vid)) == NULL) { if (vid > 0 && (vhost = stat->find_vhost(vid)) == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND; ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("vhost id=%d not found. ret=%d", vid, ret); srs_error("vhost id=%d not found. ret=%d", vid, ret);
return srs_http_response_code(w, ret); return srs_api_response_code(w, r, ret);
} }
if (r->is_http_get()) { if (r->is_http_get()) {
@ -629,10 +718,10 @@ int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
} }
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
SrsGoApiStreams::SrsGoApiStreams() SrsGoApiStreams::SrsGoApiStreams()
@ -658,7 +747,7 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) { if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND; ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("stream stream_id=%d not found. ret=%d", sid, ret); srs_error("stream stream_id=%d not found. ret=%d", sid, ret);
return srs_http_response_code(w, ret); return srs_api_response_code(w, r, ret);
} }
if (r->is_http_get()) { if (r->is_http_get()) {
@ -682,7 +771,7 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
} }
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} }
return ret; return ret;
@ -711,7 +800,7 @@ int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
if (cid >= 0 && (client = stat->find_client(cid)) == NULL) { if (cid >= 0 && (client = stat->find_client(cid)) == NULL) {
ret = ERROR_RTMP_STREAM_NOT_FOUND; ret = ERROR_RTMP_STREAM_NOT_FOUND;
srs_error("stream client_id=%d not found. ret=%d", cid, ret); srs_error("stream client_id=%d not found. ret=%d", cid, ret);
return srs_http_response_code(w, ret); return srs_api_response_code(w, r, ret);
} }
if (r->is_http_delete()) { if (r->is_http_delete()) {
@ -719,7 +808,7 @@ int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
client->conn->expire(); client->conn->expire();
srs_warn("delete client=%d ok", cid); srs_warn("delete client=%d ok", cid);
return srs_http_response_code(w, ret); return srs_api_response_code(w, r, ret);
} else if (r->is_http_get()) { } else if (r->is_http_get()) {
std::stringstream data; std::stringstream data;
@ -741,7 +830,7 @@ int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
<< SRS_JOBJECT_END; << SRS_JOBJECT_END;
} }
return srs_http_response_json(w, ss.str()); return srs_api_response(w, r, ss.str());
} else { } else {
return srs_go_http_error(w, SRS_CONSTS_HTTP_MethodNotAllowed); return srs_go_http_error(w, SRS_CONSTS_HTTP_MethodNotAllowed);
} }
@ -759,7 +848,7 @@ SrsGoApiError::~SrsGoApiError()
int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
return srs_http_response_code(w, 100); return srs_api_response_code(w, r, 100);
} }

View file

@ -673,6 +673,11 @@ string SrsHttpMessage::path()
return _uri->get_path(); return _uri->get_path();
} }
string SrsHttpMessage::query()
{
return _uri->get_query();
}
string SrsHttpMessage::ext() string SrsHttpMessage::ext()
{ {
return _ext; return _ext;

View file

@ -245,6 +245,7 @@ public:
virtual std::string url(); virtual std::string url();
virtual std::string host(); virtual std::string host();
virtual std::string path(); virtual std::string path();
virtual std::string query();
virtual std::string ext(); virtual std::string ext();
/** /**
* get the RESTful matched id. * get the RESTful matched id.

View file

@ -137,27 +137,6 @@ int srs_go_http_error(ISrsHttpResponseWriter* w, int code, string error)
return ret; return ret;
} }
int srs_http_response_json(ISrsHttpResponseWriter* w, string data)
{
SrsHttpHeader* h = w->header();
h->set_content_length(data.length());
h->set_content_type("application/json");
return w->write((char*)data.data(), (int)data.length());
}
int srs_http_response_code(ISrsHttpResponseWriter* w, int code)
{
std::stringstream ss;
ss << SRS_JOBJECT_START
<< SRS_JFIELD_ERROR(code)
<< SRS_JOBJECT_END;
return srs_http_response_json(w, ss.str());
}
SrsHttpHeader::SrsHttpHeader() SrsHttpHeader::SrsHttpHeader()
{ {
} }
@ -261,17 +240,23 @@ SrsHttpRedirectHandler::~SrsHttpRedirectHandler()
int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
string msg = "Moved Permsanently";
string location = url;
if (!r->query().empty()) {
location += "?" + r->query();
}
string msg = "Redirect to" + location;
w->header()->set_content_type("text/plain; charset=utf-8"); w->header()->set_content_type("text/plain; charset=utf-8");
w->header()->set_content_length(msg.length()); w->header()->set_content_length(msg.length());
w->header()->set("Location", url); w->header()->set("Location", location);
w->write_header(code); w->write_header(code);
w->write((char*)msg.data(), (int)msg.length()); w->write((char*)msg.data(), (int)msg.length());
w->final_request(); w->final_request();
srs_info("redirect to %s.", url.c_str()); srs_info("redirect to %s.", location.c_str());
return ret; return ret;
} }
@ -636,7 +621,7 @@ int SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handler)
entry = new SrsHttpMuxEntry(); entry = new SrsHttpMuxEntry();
entry->explicit_match = false; entry->explicit_match = false;
entry->handler = new SrsHttpRedirectHandler(pattern, SRS_CONSTS_HTTP_MovedPermanently); entry->handler = new SrsHttpRedirectHandler(pattern, SRS_CONSTS_HTTP_Found);
entry->pattern = pattern; entry->pattern = pattern;
entry->handler->entry = entry; entry->handler->entry = entry;

View file

@ -81,14 +81,6 @@ class ISrsHttpResponseWriter;
extern int srs_go_http_error(ISrsHttpResponseWriter* w, int code); extern int srs_go_http_error(ISrsHttpResponseWriter* w, int code);
extern int srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error); extern int srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error);
// helper function: response in json format.
extern int srs_http_response_json(ISrsHttpResponseWriter* w, std::string data);
/**
* response a typical code object, for example:
* {code : 100}
*/
extern int srs_http_response_code(ISrsHttpResponseWriter* w, int code);
// get the status text of code. // get the status text of code.
extern std::string srs_generate_http_status_text(int status); extern std::string srs_generate_http_status_text(int status);
@ -497,6 +489,7 @@ public:
virtual std::string url() = 0; virtual std::string url() = 0;
virtual std::string host() = 0; virtual std::string host() = 0;
virtual std::string path() = 0; virtual std::string path() = 0;
virtual std::string query() = 0;
virtual std::string ext() = 0; virtual std::string ext() = 0;
/** /**
* get the RESTful id, * get the RESTful id,