mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 11:51:57 +00:00
refine the http url handler match. refine json encode
This commit is contained in:
parent
bfa07465f0
commit
a14267d2b4
9 changed files with 323 additions and 211 deletions
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -427,7 +427,7 @@ MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_socke
|
||||||
"srs_app_codec" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder"
|
"srs_app_codec" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder"
|
||||||
"srs_app_http" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log"
|
"srs_app_http" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log"
|
||||||
"srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api"
|
"srs_app_config" "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api"
|
||||||
"srs_app_http_conn" "srs_app_http_hooks")
|
"srs_app_http_conn" "srs_app_http_hooks" "srs_app_json")
|
||||||
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
|
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
|
||||||
APP_OBJS="${MODULE_OBJS[@]}"
|
APP_OBJS="${MODULE_OBJS[@]}"
|
||||||
#
|
#
|
||||||
|
|
|
@ -39,6 +39,22 @@ using namespace std;
|
||||||
|
|
||||||
#define SRS_HTTP_HEADER_BUFFER 1024
|
#define SRS_HTTP_HEADER_BUFFER 1024
|
||||||
|
|
||||||
|
bool srs_path_equals(const char* expect, const char* path, int nb_path)
|
||||||
|
{
|
||||||
|
int size = strlen(expect);
|
||||||
|
|
||||||
|
if (size != nb_path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !memcmp(expect, path, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpHandlerMatch::SrsHttpHandlerMatch()
|
||||||
|
{
|
||||||
|
handler = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SrsHttpHandler::SrsHttpHandler()
|
SrsHttpHandler::SrsHttpHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -59,21 +75,34 @@ int SrsHttpHandler::initialize()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/, const char** /*pnext_path*/)
|
bool SrsHttpHandler::can_handle(const char* /*path*/, int /*length*/, const char** /*pchild*/)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpHandler::process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/, const char* /*path*/, int /*length*/)
|
int SrsHttpHandler::process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
|
{
|
||||||
|
if (req->method() == HTTP_OPTIONS) {
|
||||||
|
return res_options(skt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return do_process_request(skt, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpHandler::do_process_request(SrsSocket* /*skt*/, SrsHttpMessage* /*req*/)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength)
|
int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsHttpHandler* handler = NULL;
|
||||||
|
const char* match_start = NULL;
|
||||||
|
int match_length = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// ensure cur is not NULL.
|
// ensure cur is not NULL.
|
||||||
// ensure p not NULL and has bytes to parse.
|
// ensure p not NULL and has bytes to parse.
|
||||||
|
@ -86,23 +115,23 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph
|
||||||
}
|
}
|
||||||
|
|
||||||
// whether the handler can handler the node.
|
// whether the handler can handler the node.
|
||||||
const char* pnext = p;
|
const char* pchild = p;
|
||||||
if (!can_handle(path, p - path, &pnext)) {
|
if (!can_handle(path, p - path, &pchild)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// save current handler, it's ok for current handler atleast.
|
// save current handler, it's ok for current handler atleast.
|
||||||
*phandler = this;
|
handler = this;
|
||||||
*pstart = path;
|
match_start = path;
|
||||||
*plength = p - path;
|
match_length = p - path;
|
||||||
|
|
||||||
// find the best matched child handler.
|
// find the best matched child handler.
|
||||||
std::vector<SrsHttpHandler*>::iterator it;
|
std::vector<SrsHttpHandler*>::iterator it;
|
||||||
for (it = handlers.begin(); it != handlers.end(); ++it) {
|
for (it = handlers.begin(); it != handlers.end(); ++it) {
|
||||||
SrsHttpHandler* handler = *it;
|
SrsHttpHandler* h = *it;
|
||||||
|
|
||||||
// matched, donot search more.
|
// matched, donot search more.
|
||||||
if (handler->best_match(pnext, length - (pnext - path), phandler, pstart, plength) == ERROR_SUCCESS) {
|
if (h->best_match(pchild, length - (pchild - path), ppmatch) == ERROR_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,11 +140,22 @@ int SrsHttpHandler::best_match(const char* path, int length, SrsHttpHandler** ph
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*phandler == NULL) {
|
// if already matched by child, return.
|
||||||
|
if (*ppmatch) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not matched, error.
|
||||||
|
if (handler == NULL) {
|
||||||
ret = ERROR_HTTP_HANDLER_MATCH_URL;
|
ret = ERROR_HTTP_HANDLER_MATCH_URL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// matched by this handler.
|
||||||
|
*ppmatch = new SrsHttpHandlerMatch();
|
||||||
|
(*ppmatch)->handler = handler;
|
||||||
|
(*ppmatch)->matched_url.append(match_start, match_length);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +173,13 @@ SrsHttpHandler* SrsHttpHandler::res_content_type(std::stringstream& ss)
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsHttpHandler* SrsHttpHandler::res_content_type_json(std::stringstream& ss)
|
||||||
|
{
|
||||||
|
ss << "Content-Type: application/json;charset=utf-8" << __CRLF
|
||||||
|
<< "Allow: DELETE, GET, HEAD, OPTIONS, POST, PUT" << __CRLF;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
SrsHttpHandler* SrsHttpHandler::res_content_length(std::stringstream& ss, int64_t length)
|
SrsHttpHandler* SrsHttpHandler::res_content_length(std::stringstream& ss, int64_t length)
|
||||||
{
|
{
|
||||||
ss << "Content-Length: "<< length << __CRLF;
|
ss << "Content-Length: "<< length << __CRLF;
|
||||||
|
@ -189,6 +236,18 @@ int SrsHttpHandler::res_text(SrsSocket* skt, std::string body)
|
||||||
return res_flush(skt, ss);
|
return res_flush(skt, ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsHttpHandler::res_json(SrsSocket* skt, std::string json)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
res_status_line(ss)->res_content_type_json(ss)
|
||||||
|
->res_content_length(ss, (int)json.length())->res_enable_crossdomain(ss)
|
||||||
|
->res_header_eof(ss)
|
||||||
|
->res_body(ss, json);
|
||||||
|
|
||||||
|
return res_flush(skt, ss);
|
||||||
|
}
|
||||||
|
|
||||||
SrsHttpHandler* SrsHttpHandler::create_http_api()
|
SrsHttpHandler* SrsHttpHandler::create_http_api()
|
||||||
{
|
{
|
||||||
return new SrsApiRoot();
|
return new SrsApiRoot();
|
||||||
|
@ -204,11 +263,15 @@ SrsHttpMessage::SrsHttpMessage()
|
||||||
{
|
{
|
||||||
_body = new SrsBuffer();
|
_body = new SrsBuffer();
|
||||||
_state = SrsHttpParseStateInit;
|
_state = SrsHttpParseStateInit;
|
||||||
|
_uri = new SrsHttpUri();
|
||||||
|
_match = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpMessage::~SrsHttpMessage()
|
SrsHttpMessage::~SrsHttpMessage()
|
||||||
{
|
{
|
||||||
srs_freep(_body);
|
srs_freep(_body);
|
||||||
|
srs_freep(_uri);
|
||||||
|
srs_freep(_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpMessage::reset()
|
void SrsHttpMessage::reset()
|
||||||
|
@ -218,6 +281,11 @@ void SrsHttpMessage::reset()
|
||||||
_url = "";
|
_url = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsHttpMessage::parse_uri()
|
||||||
|
{
|
||||||
|
return _uri->initialize(_url);
|
||||||
|
}
|
||||||
|
|
||||||
bool SrsHttpMessage::is_complete()
|
bool SrsHttpMessage::is_complete()
|
||||||
{
|
{
|
||||||
return _state == SrsHttpParseStateComplete;
|
return _state == SrsHttpParseStateComplete;
|
||||||
|
@ -230,7 +298,17 @@ u_int8_t SrsHttpMessage::method()
|
||||||
|
|
||||||
string SrsHttpMessage::url()
|
string SrsHttpMessage::url()
|
||||||
{
|
{
|
||||||
return _url;
|
return _uri->get_url();
|
||||||
|
}
|
||||||
|
|
||||||
|
string SrsHttpMessage::path()
|
||||||
|
{
|
||||||
|
return _uri->get_path();
|
||||||
|
}
|
||||||
|
|
||||||
|
string SrsHttpMessage::query()
|
||||||
|
{
|
||||||
|
return _uri->get_query();
|
||||||
}
|
}
|
||||||
|
|
||||||
string SrsHttpMessage::body()
|
string SrsHttpMessage::body()
|
||||||
|
@ -254,6 +332,11 @@ int64_t SrsHttpMessage::content_length()
|
||||||
return _header.content_length;
|
return _header.content_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsHttpHandlerMatch* SrsHttpMessage::match()
|
||||||
|
{
|
||||||
|
return _match;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsHttpMessage::set_url(std::string url)
|
void SrsHttpMessage::set_url(std::string url)
|
||||||
{
|
{
|
||||||
_url = url;
|
_url = url;
|
||||||
|
@ -269,6 +352,12 @@ void SrsHttpMessage::set_header(http_parser* header)
|
||||||
memcpy(&_header, header, sizeof(http_parser));
|
memcpy(&_header, header, sizeof(http_parser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsHttpMessage::set_match(SrsHttpHandlerMatch* match)
|
||||||
|
{
|
||||||
|
srs_freep(_match);
|
||||||
|
_match = match;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsHttpMessage::append_body(const char* body, int length)
|
void SrsHttpMessage::append_body(const char* body, int length)
|
||||||
{
|
{
|
||||||
_body->append(body, length);
|
_body->append(body, length);
|
||||||
|
@ -489,22 +578,25 @@ int SrsHttpUri::initialize(std::string _url)
|
||||||
path = get_uri_field(url, &hp_u, UF_PATH);
|
path = get_uri_field(url, &hp_u, UF_PATH);
|
||||||
srs_info("parse url %s success", purl);
|
srs_info("parse url %s success", purl);
|
||||||
|
|
||||||
|
query = get_uri_field(url, &hp_u, UF_QUERY);
|
||||||
|
srs_trace("parse query %s success", purl);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SrsHttpUri::get_url()
|
const char* SrsHttpUri::get_url()
|
||||||
{
|
{
|
||||||
return url.c_str();
|
return url.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SrsHttpUri::get_schema()
|
const char* SrsHttpUri::get_schema()
|
||||||
{
|
{
|
||||||
return schema.c_str();
|
return schema.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SrsHttpUri::get_host()
|
const char* SrsHttpUri::get_host()
|
||||||
{
|
{
|
||||||
return host.c_str();
|
return host.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpUri::get_port()
|
int SrsHttpUri::get_port()
|
||||||
|
@ -514,7 +606,12 @@ int SrsHttpUri::get_port()
|
||||||
|
|
||||||
const char* SrsHttpUri::get_path()
|
const char* SrsHttpUri::get_path()
|
||||||
{
|
{
|
||||||
return path.c_str();
|
return path.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* SrsHttpUri::get_query()
|
||||||
|
{
|
||||||
|
return path.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SrsHttpUri::get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field)
|
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.
|
||||||
class SrsBuffer;
|
class SrsBuffer;
|
||||||
class SrsRequest;
|
class SrsRequest;
|
||||||
class SrsSocket;
|
class SrsSocket;
|
||||||
|
class SrsHttpUri;
|
||||||
class SrsHttpMessage;
|
class SrsHttpMessage;
|
||||||
|
class SrsHttpHandler;
|
||||||
|
|
||||||
// http specification
|
// http specification
|
||||||
// CR = <US-ASCII CR, carriage return (13)>
|
// CR = <US-ASCII CR, carriage return (13)>
|
||||||
|
@ -62,6 +64,12 @@ class SrsHttpMessage;
|
||||||
|
|
||||||
// linux path seprator
|
// linux path seprator
|
||||||
#define __PATH_SEP '/'
|
#define __PATH_SEP '/'
|
||||||
|
// query string seprator
|
||||||
|
#define __QUERY_SEP '?'
|
||||||
|
|
||||||
|
// compare the path.
|
||||||
|
// full compare, extractly match.
|
||||||
|
extern bool srs_path_equals(const char* expect, const char* path, int nb_path);
|
||||||
|
|
||||||
// state of message
|
// state of message
|
||||||
enum SrsHttpParseState {
|
enum SrsHttpParseState {
|
||||||
|
@ -70,6 +78,18 @@ enum SrsHttpParseState {
|
||||||
SrsHttpParseStateComplete
|
SrsHttpParseStateComplete
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the matched handler info.
|
||||||
|
*/
|
||||||
|
class SrsHttpHandlerMatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SrsHttpHandler* handler;
|
||||||
|
std::string matched_url;
|
||||||
|
public:
|
||||||
|
SrsHttpHandlerMatch();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resource handler for HTTP RESTful api.
|
* resource handler for HTTP RESTful api.
|
||||||
*/
|
*/
|
||||||
|
@ -90,21 +110,29 @@ public:
|
||||||
virtual int initialize();
|
virtual int initialize();
|
||||||
/**
|
/**
|
||||||
* whether current handler can handle the specified path.
|
* whether current handler can handle the specified path.
|
||||||
* @pnext_path set the next path, if needed.
|
* @pchild set the next child path, if needed.
|
||||||
|
* for example, the root handler will reset pchild to path,
|
||||||
|
* to reparse the path use child handlers.
|
||||||
*/
|
*/
|
||||||
virtual bool can_handle(const char* path, int length, const char** pnext_path);
|
virtual bool can_handle(const char* path, int length, const char** pchild);
|
||||||
/**
|
/**
|
||||||
* use the handler to process the request.
|
* use the handler to process the request.
|
||||||
|
* @remark sub classes should override the do_process_request.
|
||||||
*/
|
*/
|
||||||
virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
|
virtual int process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* find the best matched handler
|
* find the best matched handler
|
||||||
*/
|
*/
|
||||||
virtual int best_match(const char* path, int length, SrsHttpHandler** phandler, const char** pstart, int* plength);
|
virtual int best_match(const char* path, int length, SrsHttpHandlerMatch** ppmatch);
|
||||||
|
// factory methods
|
||||||
|
protected:
|
||||||
|
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
|
// response writer
|
||||||
public:
|
public:
|
||||||
virtual SrsHttpHandler* res_status_line(std::stringstream& ss);
|
virtual SrsHttpHandler* res_status_line(std::stringstream& ss);
|
||||||
virtual SrsHttpHandler* res_content_type(std::stringstream& ss);
|
virtual SrsHttpHandler* res_content_type(std::stringstream& ss);
|
||||||
|
virtual SrsHttpHandler* res_content_type_json(std::stringstream& ss);
|
||||||
virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length);
|
virtual SrsHttpHandler* res_content_length(std::stringstream& ss, int64_t length);
|
||||||
virtual SrsHttpHandler* res_enable_crossdomain(std::stringstream& ss);
|
virtual SrsHttpHandler* res_enable_crossdomain(std::stringstream& ss);
|
||||||
virtual SrsHttpHandler* res_header_eof(std::stringstream& ss);
|
virtual SrsHttpHandler* res_header_eof(std::stringstream& ss);
|
||||||
|
@ -113,6 +141,8 @@ public:
|
||||||
public:
|
public:
|
||||||
virtual int res_options(SrsSocket* skt);
|
virtual int res_options(SrsSocket* skt);
|
||||||
virtual int res_text(SrsSocket* skt, std::string body);
|
virtual int res_text(SrsSocket* skt, std::string body);
|
||||||
|
virtual int res_json(SrsSocket* skt, std::string json);
|
||||||
|
// object creator
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* create http api resource handler.
|
* create http api resource handler.
|
||||||
|
@ -148,23 +178,34 @@ private:
|
||||||
* @remark, user can use is_complete() to determine the state.
|
* @remark, user can use is_complete() to determine the state.
|
||||||
*/
|
*/
|
||||||
SrsHttpParseState _state;
|
SrsHttpParseState _state;
|
||||||
|
/**
|
||||||
|
* uri parser
|
||||||
|
*/
|
||||||
|
SrsHttpUri* _uri;
|
||||||
|
/**
|
||||||
|
* best matched handler.
|
||||||
|
*/
|
||||||
|
SrsHttpHandlerMatch* _match;
|
||||||
public:
|
public:
|
||||||
SrsHttpMessage();
|
SrsHttpMessage();
|
||||||
virtual ~SrsHttpMessage();
|
virtual ~SrsHttpMessage();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
virtual int parse_uri();
|
||||||
public:
|
public:
|
||||||
virtual bool is_complete();
|
virtual bool is_complete();
|
||||||
virtual u_int8_t method();
|
virtual u_int8_t method();
|
||||||
virtual std::string url();
|
virtual std::string url();
|
||||||
|
virtual std::string path();
|
||||||
|
virtual std::string query();
|
||||||
virtual std::string body();
|
virtual std::string body();
|
||||||
virtual int64_t body_size();
|
virtual int64_t body_size();
|
||||||
virtual int64_t content_length();
|
virtual int64_t content_length();
|
||||||
|
virtual SrsHttpHandlerMatch* match();
|
||||||
virtual void set_url(std::string url);
|
virtual void set_url(std::string url);
|
||||||
virtual void set_state(SrsHttpParseState state);
|
virtual void set_state(SrsHttpParseState state);
|
||||||
virtual void set_header(http_parser* header);
|
virtual void set_header(http_parser* header);
|
||||||
|
virtual void set_match(SrsHttpHandlerMatch* match);
|
||||||
virtual void append_body(const char* body, int length);
|
virtual void append_body(const char* body, int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,6 +261,7 @@ private:
|
||||||
std::string host;
|
std::string host;
|
||||||
int port;
|
int port;
|
||||||
std::string path;
|
std::string path;
|
||||||
|
std::string query;
|
||||||
public:
|
public:
|
||||||
SrsHttpUri();
|
SrsHttpUri();
|
||||||
virtual ~SrsHttpUri();
|
virtual ~SrsHttpUri();
|
||||||
|
@ -234,6 +276,7 @@ public:
|
||||||
virtual const char* get_host();
|
virtual const char* get_host();
|
||||||
virtual int get_port();
|
virtual int get_port();
|
||||||
virtual const char* get_path();
|
virtual const char* get_path();
|
||||||
|
virtual const char* get_query();
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* get the parsed url field.
|
* get the parsed url field.
|
||||||
|
|
|
@ -33,6 +33,7 @@ using namespace std;
|
||||||
#include <srs_app_http.hpp>
|
#include <srs_app_http.hpp>
|
||||||
#include <srs_app_socket.hpp>
|
#include <srs_app_socket.hpp>
|
||||||
#include <srs_core_autofree.hpp>
|
#include <srs_core_autofree.hpp>
|
||||||
|
#include <srs_app_json.hpp>
|
||||||
|
|
||||||
SrsApiRoot::SrsApiRoot()
|
SrsApiRoot::SrsApiRoot()
|
||||||
{
|
{
|
||||||
|
@ -43,24 +44,28 @@ SrsApiRoot::~SrsApiRoot()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsApiRoot::can_handle(const char* path, int length, const char** pnext_path)
|
bool SrsApiRoot::can_handle(const char* path, int length, const char** pchild)
|
||||||
{
|
{
|
||||||
// reset the next path for child to parse.
|
// reset the child path to path,
|
||||||
*pnext_path = path;
|
// for child to reparse the path.
|
||||||
|
*pchild = path;
|
||||||
|
|
||||||
return true;
|
// only compare the first char.
|
||||||
|
return srs_path_equals("/", path, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsApiRoot::process_request(SrsSocket* skt, SrsHttpMessage* req, const char* /*path*/, int /*length*/)
|
int SrsApiRoot::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
{
|
{
|
||||||
if (req->method() == HTTP_OPTIONS) {
|
std::stringstream ss;
|
||||||
return res_options(skt);
|
|
||||||
} else {
|
|
||||||
std::string body = "hello, root";
|
|
||||||
return res_text(skt, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
ss << JOBJECT_START
|
||||||
|
<< JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
|
||||||
|
<< JFIELD_ORG("urls", JOBJECT_START)
|
||||||
|
<< JFIELD_STR("v1", "the api version 1.0")
|
||||||
|
<< JOBJECT_END
|
||||||
|
<< JOBJECT_END;
|
||||||
|
|
||||||
|
return res_json(skt, ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsApiApi::SrsApiApi()
|
SrsApiApi::SrsApiApi()
|
||||||
|
@ -71,21 +76,15 @@ SrsApiApi::~SrsApiApi()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsApiApi::can_handle(const char* path, int length, const char** /*pnext_path*/)
|
bool SrsApiApi::can_handle(const char* path, int length, const char** /*pchild*/)
|
||||||
{
|
{
|
||||||
return !memcmp("/api", path, length);
|
return srs_path_equals("/api", path, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsApiApi::process_request(SrsSocket* skt, SrsHttpMessage* req, const char* /*path*/, int /*length*/)
|
int SrsApiApi::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
{
|
{
|
||||||
if (req->method() == HTTP_OPTIONS) {
|
|
||||||
return res_options(skt);
|
|
||||||
} else {
|
|
||||||
std::string body = "hello, api";
|
std::string body = "hello, api";
|
||||||
return res_text(skt, body);
|
return res_text(skt, body);
|
||||||
}
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
|
SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler)
|
||||||
|
@ -148,24 +147,30 @@ int SrsHttpApi::process_request(SrsSocket* skt, SrsHttpMessage* req)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// TODO: maybe need to parse the url.
|
// parse uri to schema/server:port/path?query
|
||||||
std::string uri = req->url();
|
if ((ret = req->parse_uri()) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int length = 0;
|
// TODO: maybe need to parse the url.
|
||||||
const char* start = NULL;
|
std::string url = req->path();
|
||||||
SrsHttpHandler* p = NULL;
|
|
||||||
if ((ret = handler->best_match(uri.data(), uri.length(), &p, &start, &length)) != ERROR_SUCCESS) {
|
SrsHttpHandlerMatch* p = NULL;
|
||||||
|
if ((ret = handler->best_match(url.data(), url.length(), &p)) != ERROR_SUCCESS) {
|
||||||
srs_warn("failed to find the best match handler for url. ret=%d", ret);
|
srs_warn("failed to find the best match handler for url. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if success, p and pstart should be valid.
|
// if success, p and pstart should be valid.
|
||||||
srs_assert(p);
|
srs_assert(p);
|
||||||
srs_assert(start);
|
srs_assert(p->handler);
|
||||||
srs_assert(length <= (int)uri.length());
|
srs_assert(p->matched_url.length() <= url.length());
|
||||||
|
srs_info("best match handler, matched_url=%s", p->matched_url.c_str());
|
||||||
|
|
||||||
|
req->set_match(p);
|
||||||
|
|
||||||
// use handler to process request.
|
// use handler to process request.
|
||||||
if ((ret = p->process_request(skt, req, start, length)) != ERROR_SUCCESS) {
|
if ((ret = p->handler->process_request(skt, req)) != ERROR_SUCCESS) {
|
||||||
srs_warn("handler failed to process http request. ret=%d", ret);
|
srs_warn("handler failed to process http request. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@ public:
|
||||||
SrsApiRoot();
|
SrsApiRoot();
|
||||||
virtual ~SrsApiRoot();
|
virtual ~SrsApiRoot();
|
||||||
public:
|
public:
|
||||||
virtual bool can_handle(const char* path, int length, const char** pnext_path);
|
virtual bool can_handle(const char* path, int length, const char** pchild);
|
||||||
virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
|
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsApiApi : public SrsHttpHandler
|
class SrsApiApi : public SrsHttpHandler
|
||||||
|
@ -58,8 +58,8 @@ public:
|
||||||
SrsApiApi();
|
SrsApiApi();
|
||||||
virtual ~SrsApiApi();
|
virtual ~SrsApiApi();
|
||||||
public:
|
public:
|
||||||
virtual bool can_handle(const char* path, int length, const char** pnext_path);
|
virtual bool can_handle(const char* path, int length, const char** pchild);
|
||||||
virtual int process_request(SrsSocket* skt, SrsHttpMessage* req, const char* path, int length);
|
virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsHttpApi : public SrsConnection
|
class SrsHttpApi : public SrsConnection
|
||||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
||||||
#include <srs_kernel_log.hpp>
|
#include <srs_kernel_log.hpp>
|
||||||
#include <srs_app_socket.hpp>
|
#include <srs_app_socket.hpp>
|
||||||
#include <srs_app_http.hpp>
|
#include <srs_app_http.hpp>
|
||||||
|
#include <srs_app_json.hpp>
|
||||||
|
|
||||||
#define SRS_HTTP_RESPONSE_OK "0"
|
#define SRS_HTTP_RESPONSE_OK "0"
|
||||||
|
|
||||||
|
@ -202,32 +203,14 @@ int SrsHttpHooks::on_connect(std::string url, int client_id, std::string ip, Srs
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << JOBJECT_START
|
||||||
// action
|
<< JFIELD_STR("action", "on_connect") << JFIELD_CONT
|
||||||
<< '"' << "action" << '"' << ':'
|
<< JFIELD_ORG("client_id", client_id) << JFIELD_CONT
|
||||||
<< '"' << "on_connect" << '"'
|
<< JFIELD_STR("ip", ip) << JFIELD_CONT
|
||||||
<< ','
|
<< JFIELD_STR("vhost", req->vhost) << JFIELD_CONT
|
||||||
// client_id
|
<< JFIELD_STR("app", req->app) << JFIELD_CONT
|
||||||
<< '"' << "client_id" << '"' << ':'
|
<< JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT
|
||||||
<< std::dec << client_id
|
<< JOBJECT_END;
|
||||||
<< ','
|
|
||||||
// ip
|
|
||||||
<< '"' << "ip" << '"' << ':'
|
|
||||||
<< '"' << ip << '"'
|
|
||||||
<< ','
|
|
||||||
// vhost
|
|
||||||
<< '"' << "vhost" << '"' << ':'
|
|
||||||
<< '"' << req->vhost << '"'
|
|
||||||
<< ','
|
|
||||||
// app
|
|
||||||
<< '"' << "app" << '"' << ':'
|
|
||||||
<< '"' << req->app << '"'
|
|
||||||
<< ','
|
|
||||||
// pageUrl
|
|
||||||
<< '"' << "pageUrl" << '"' << ':'
|
|
||||||
<< '"' << req->pageUrl << '"'
|
|
||||||
//<< ','
|
|
||||||
<< "}";
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
@ -273,28 +256,14 @@ void SrsHttpHooks::on_close(std::string url, int client_id, std::string ip, SrsR
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << JOBJECT_START
|
||||||
// action
|
<< JFIELD_STR("action", "on_close") << JFIELD_CONT
|
||||||
<< '"' << "action" << '"' << ':'
|
<< JFIELD_ORG("client_id", client_id) << JFIELD_CONT
|
||||||
<< '"' << "on_close" << '"'
|
<< JFIELD_STR("ip", ip) << JFIELD_CONT
|
||||||
<< ','
|
<< JFIELD_STR("vhost", req->vhost) << JFIELD_CONT
|
||||||
// client_id
|
<< JFIELD_STR("app", req->app) << JFIELD_CONT
|
||||||
<< '"' << "client_id" << '"' << ':'
|
<< JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT
|
||||||
<< std::dec << client_id
|
<< JOBJECT_END;
|
||||||
<< ','
|
|
||||||
// ip
|
|
||||||
<< '"' << "ip" << '"' << ':'
|
|
||||||
<< '"' << ip << '"'
|
|
||||||
<< ','
|
|
||||||
// vhost
|
|
||||||
<< '"' << "vhost" << '"' << ':'
|
|
||||||
<< '"' << req->vhost << '"'
|
|
||||||
<< ','
|
|
||||||
// app
|
|
||||||
<< '"' << "app" << '"' << ':'
|
|
||||||
<< '"' << req->app << '"'
|
|
||||||
//<< ','
|
|
||||||
<< "}";
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
@ -340,32 +309,15 @@ int SrsHttpHooks::on_publish(std::string url, int client_id, std::string ip, Srs
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << JOBJECT_START
|
||||||
// action
|
<< JFIELD_STR("action", "on_publish") << JFIELD_CONT
|
||||||
<< '"' << "action" << '"' << ':'
|
<< JFIELD_ORG("client_id", client_id) << JFIELD_CONT
|
||||||
<< '"' << "on_publish" << '"'
|
<< JFIELD_STR("ip", ip) << JFIELD_CONT
|
||||||
<< ','
|
<< JFIELD_STR("vhost", req->vhost) << JFIELD_CONT
|
||||||
// client_id
|
<< JFIELD_STR("app", req->app) << JFIELD_CONT
|
||||||
<< '"' << "client_id" << '"' << ':'
|
<< JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT
|
||||||
<< std::dec << client_id
|
<< JFIELD_STR("stream", req->stream) << JFIELD_CONT
|
||||||
<< ','
|
<< JOBJECT_END;
|
||||||
// ip
|
|
||||||
<< '"' << "ip" << '"' << ':'
|
|
||||||
<< '"' << ip << '"'
|
|
||||||
<< ','
|
|
||||||
// vhost
|
|
||||||
<< '"' << "vhost" << '"' << ':'
|
|
||||||
<< '"' << req->vhost << '"'
|
|
||||||
<< ','
|
|
||||||
// app
|
|
||||||
<< '"' << "app" << '"' << ':'
|
|
||||||
<< '"' << req->app << '"'
|
|
||||||
<< ','
|
|
||||||
// stream
|
|
||||||
<< '"' << "stream" << '"' << ':'
|
|
||||||
<< '"' << req->stream << '"'
|
|
||||||
//<< ','
|
|
||||||
<< "}";
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
@ -411,32 +363,15 @@ void SrsHttpHooks::on_unpublish(std::string url, int client_id, std::string ip,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << JOBJECT_START
|
||||||
// action
|
<< JFIELD_STR("action", "on_unpublish") << JFIELD_CONT
|
||||||
<< '"' << "action" << '"' << ':'
|
<< JFIELD_ORG("client_id", client_id) << JFIELD_CONT
|
||||||
<< '"' << "on_unpublish" << '"'
|
<< JFIELD_STR("ip", ip) << JFIELD_CONT
|
||||||
<< ','
|
<< JFIELD_STR("vhost", req->vhost) << JFIELD_CONT
|
||||||
// client_id
|
<< JFIELD_STR("app", req->app) << JFIELD_CONT
|
||||||
<< '"' << "client_id" << '"' << ':'
|
<< JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT
|
||||||
<< std::dec << client_id
|
<< JFIELD_STR("stream", req->stream) << JFIELD_CONT
|
||||||
<< ','
|
<< JOBJECT_END;
|
||||||
// ip
|
|
||||||
<< '"' << "ip" << '"' << ':'
|
|
||||||
<< '"' << ip << '"'
|
|
||||||
<< ','
|
|
||||||
// vhost
|
|
||||||
<< '"' << "vhost" << '"' << ':'
|
|
||||||
<< '"' << req->vhost << '"'
|
|
||||||
<< ','
|
|
||||||
// app
|
|
||||||
<< '"' << "app" << '"' << ':'
|
|
||||||
<< '"' << req->app << '"'
|
|
||||||
<< ','
|
|
||||||
// stream
|
|
||||||
<< '"' << "stream" << '"' << ':'
|
|
||||||
<< '"' << req->stream << '"'
|
|
||||||
//<< ','
|
|
||||||
<< "}";
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
@ -482,32 +417,15 @@ int SrsHttpHooks::on_play(std::string url, int client_id, std::string ip, SrsReq
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << JOBJECT_START
|
||||||
// action
|
<< JFIELD_STR("action", "on_play") << JFIELD_CONT
|
||||||
<< '"' << "action" << '"' << ':'
|
<< JFIELD_ORG("client_id", client_id) << JFIELD_CONT
|
||||||
<< '"' << "on_play" << '"'
|
<< JFIELD_STR("ip", ip) << JFIELD_CONT
|
||||||
<< ','
|
<< JFIELD_STR("vhost", req->vhost) << JFIELD_CONT
|
||||||
// client_id
|
<< JFIELD_STR("app", req->app) << JFIELD_CONT
|
||||||
<< '"' << "client_id" << '"' << ':'
|
<< JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT
|
||||||
<< std::dec << client_id
|
<< JFIELD_STR("stream", req->stream) << JFIELD_CONT
|
||||||
<< ','
|
<< JOBJECT_END;
|
||||||
// ip
|
|
||||||
<< '"' << "ip" << '"' << ':'
|
|
||||||
<< '"' << ip << '"'
|
|
||||||
<< ','
|
|
||||||
// vhost
|
|
||||||
<< '"' << "vhost" << '"' << ':'
|
|
||||||
<< '"' << req->vhost << '"'
|
|
||||||
<< ','
|
|
||||||
// app
|
|
||||||
<< '"' << "app" << '"' << ':'
|
|
||||||
<< '"' << req->app << '"'
|
|
||||||
<< ','
|
|
||||||
// stream
|
|
||||||
<< '"' << "stream" << '"' << ':'
|
|
||||||
<< '"' << req->stream << '"'
|
|
||||||
//<< ','
|
|
||||||
<< "}";
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
@ -553,32 +471,15 @@ void SrsHttpHooks::on_stop(std::string url, int client_id, std::string ip, SrsRe
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << JOBJECT_START
|
||||||
// action
|
<< JFIELD_STR("action", "on_stop") << JFIELD_CONT
|
||||||
<< '"' << "action" << '"' << ':'
|
<< JFIELD_ORG("client_id", client_id) << JFIELD_CONT
|
||||||
<< '"' << "on_stop" << '"'
|
<< JFIELD_STR("ip", ip) << JFIELD_CONT
|
||||||
<< ','
|
<< JFIELD_STR("vhost", req->vhost) << JFIELD_CONT
|
||||||
// client_id
|
<< JFIELD_STR("app", req->app) << JFIELD_CONT
|
||||||
<< '"' << "client_id" << '"' << ':'
|
<< JFIELD_STR("pageUrl", req->pageUrl) << JFIELD_CONT
|
||||||
<< std::dec << client_id
|
<< JFIELD_STR("stream", req->stream) << JFIELD_CONT
|
||||||
<< ','
|
<< JOBJECT_END;
|
||||||
// ip
|
|
||||||
<< '"' << "ip" << '"' << ':'
|
|
||||||
<< '"' << ip << '"'
|
|
||||||
<< ','
|
|
||||||
// vhost
|
|
||||||
<< '"' << "vhost" << '"' << ':'
|
|
||||||
<< '"' << req->vhost << '"'
|
|
||||||
<< ','
|
|
||||||
// app
|
|
||||||
<< '"' << "app" << '"' << ':'
|
|
||||||
<< '"' << req->app << '"'
|
|
||||||
<< ','
|
|
||||||
// stream
|
|
||||||
<< '"' << "stream" << '"' << ':'
|
|
||||||
<< '"' << req->stream << '"'
|
|
||||||
//<< ','
|
|
||||||
<< "}";
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|
||||||
|
|
24
trunk/src/app/srs_app_json.cpp
Normal file
24
trunk/src/app/srs_app_json.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013-2014 winlin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <srs_app_json.hpp>
|
40
trunk/src/app/srs_app_json.hpp
Normal file
40
trunk/src/app/srs_app_json.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013-2014 winlin
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRS_APP_JSON_HPP
|
||||||
|
#define SRS_APP_JSON_HPP
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <srs_app_json.hpp>
|
||||||
|
*/
|
||||||
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
|
// json encode macros
|
||||||
|
#define JOBJECT_START "{"
|
||||||
|
#define JFIELD_STR(k, v) "\"" << k << "\":\"" << v << "\""
|
||||||
|
#define JFIELD_ORG(k, v) "\"" << k << "\":" << std::dec << v
|
||||||
|
#define JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
|
||||||
|
#define JFIELD_CONT ","
|
||||||
|
#define JOBJECT_END "}"
|
||||||
|
|
||||||
|
#endif
|
|
@ -61,6 +61,8 @@ file
|
||||||
..\app\srs_app_http_conn.cpp,
|
..\app\srs_app_http_conn.cpp,
|
||||||
..\app\srs_app_http_hooks.hpp,
|
..\app\srs_app_http_hooks.hpp,
|
||||||
..\app\srs_app_http_hooks.cpp,
|
..\app\srs_app_http_hooks.cpp,
|
||||||
|
..\app\srs_app_json.hpp,
|
||||||
|
..\app\srs_app_json.cpp,
|
||||||
..\app\srs_app_log.hpp,
|
..\app\srs_app_log.hpp,
|
||||||
..\app\srs_app_log.cpp,
|
..\app\srs_app_log.cpp,
|
||||||
..\app\srs_app_refer.hpp,
|
..\app\srs_app_refer.hpp,
|
||||||
|
|
Loading…
Reference in a new issue