整理解析器

This commit is contained in:
xiongziliang 2020-04-20 18:13:45 +08:00
parent 003cd58371
commit 1d5c6cb141
9 changed files with 151 additions and 125 deletions

View File

@ -114,7 +114,7 @@ API_EXPORT const char* API_CALL mk_parser_get_tail(const mk_parser ctx){
API_EXPORT const char* API_CALL mk_parser_get_header(const mk_parser ctx,const char *key){ API_EXPORT const char* API_CALL mk_parser_get_header(const mk_parser ctx,const char *key){
assert(ctx && key); assert(ctx && key);
Parser *parser = (Parser *)ctx; Parser *parser = (Parser *)ctx;
return parser->getValues()[key].c_str(); return parser->getHeader()[key].c_str();
} }
API_EXPORT const char* API_CALL mk_parser_get_content(const mk_parser ctx, int *length){ API_EXPORT const char* API_CALL mk_parser_get_content(const mk_parser ctx, int *length){
assert(ctx); assert(ctx);
@ -274,7 +274,7 @@ API_EXPORT void API_CALL mk_http_response_invoker_do_file(const mk_http_response
assert(ctx && request_parser && response_header && response_file_path); assert(ctx && request_parser && response_header && response_file_path);
auto header = get_http_header(response_header); auto header = get_http_header(response_header);
HttpSession::HttpResponseInvoker *invoker = (HttpSession::HttpResponseInvoker *)ctx; HttpSession::HttpResponseInvoker *invoker = (HttpSession::HttpResponseInvoker *)ctx;
(*invoker).responseFile(((Parser*)(request_parser))->getValues(),header,response_file_path); (*invoker).responseFile(((Parser *) (request_parser))->getHeader(), header, response_file_path);
} }
API_EXPORT void API_CALL mk_http_response_invoker_do(const mk_http_response_invoker ctx, API_EXPORT void API_CALL mk_http_response_invoker_do(const mk_http_response_invoker ctx,

View File

@ -154,7 +154,7 @@ static inline void addHttpListener(){
val["code"] = API::Success; val["code"] = API::Success;
HttpSession::KeyValue headerOut; HttpSession::KeyValue headerOut;
auto allArgs = getAllArgs(parser); auto allArgs = getAllArgs(parser);
HttpSession::KeyValue &headerIn = parser.getValues(); HttpSession::KeyValue &headerIn = parser.getHeader();
GET_CONFIG(string,charSet,Http::kCharSet); GET_CONFIG(string,charSet,Http::kCharSet);
headerOut["Content-Type"] = StrPrinter << "application/json; charset=" << charSet; headerOut["Content-Type"] = StrPrinter << "application/json; charset=" << charSet;
if(api_debug){ if(api_debug){

View File

@ -444,7 +444,7 @@ void installWebHook(){
body["path"] = path; body["path"] = path;
body["is_dir"] = is_dir; body["is_dir"] = is_dir;
body["params"] = parser.Params(); body["params"] = parser.Params();
for(auto &pr : parser.getValues()){ for(auto &pr : parser.getHeader()){
body[string("header.") + pr.first] = pr.second; body[string("header.") + pr.first] = pr.second;
} }
//执行hook //执行hook

View File

@ -35,4 +35,113 @@ string FindField(const char* buf, const char* start, const char *end ,int bufSiz
return string(msg_start, msg_end); return string(msg_start, msg_end);
} }
Parser::Parser() {}
Parser::~Parser() {}
void Parser::Parse(const char *buf) {
//解析
const char *start = buf;
Clear();
while (true) {
auto line = FindField(start, NULL, "\r\n");
if (line.size() == 0) {
break;
}
if (start == buf) {
_strMethod = FindField(line.data(), NULL, " ");
_strFullUrl = FindField(line.data(), " ", " ");
auto args_pos = _strFullUrl.find('?');
if (args_pos != string::npos) {
_strUrl = _strFullUrl.substr(0, args_pos);
_params = _strFullUrl.substr(args_pos + 1);
_mapUrlArgs = parseArgs(_params);
} else {
_strUrl = _strFullUrl;
}
_strTail = FindField(line.data(), (_strFullUrl + " ").data(), NULL);
} else {
auto field = FindField(line.data(), NULL, ": ");
auto value = FindField(line.data(), ": ", NULL);
if (field.size() != 0) {
_mapHeaders.emplace_force(field, value);
}
}
start = start + line.size() + 2;
if (strncmp(start, "\r\n", 2) == 0) { //协议解析完毕
_strContent = FindField(start, "\r\n", NULL);
break;
}
}
}
const string &Parser::Method() const {
return _strMethod;
}
const string &Parser::Url() const {
return _strUrl;
}
const string &Parser::FullUrl() const {
return _strFullUrl;
}
const string &Parser::Tail() const {
return _strTail;
}
const string &Parser::operator[](const char *name) const {
auto it = _mapHeaders.find(name);
if (it == _mapHeaders.end()) {
return _strNull;
}
return it->second;
}
const string &Parser::Content() const {
return _strContent;
}
void Parser::Clear() {
_strMethod.clear();
_strUrl.clear();
_strFullUrl.clear();
_params.clear();
_strTail.clear();
_strContent.clear();
_mapHeaders.clear();
_mapUrlArgs.clear();
}
const string &Parser::Params() const {
return _params;
}
void Parser::setUrl(const string &url) {
this->_strUrl = url;
}
void Parser::setContent(const string &content) {
this->_strContent = content;
}
StrCaseMap &Parser::getHeader() const {
return _mapHeaders;
}
StrCaseMap &Parser::getUrlArgs() const {
return _mapUrlArgs;
}
StrCaseMap Parser::parseArgs(const string &str, const char *pair_delim, const char *key_delim) {
StrCaseMap ret;
auto arg_vec = split(str, pair_delim);
for (string &key_val : arg_vec) {
auto key = FindField(key_val.data(), NULL, key_delim);
auto val = FindField(key_val.data(), key_delim, NULL);
ret.emplace_force(trim(key), trim(val));
}
return ret;
}
}//namespace mediakit }//namespace mediakit

View File

@ -57,122 +57,39 @@ class StrCaseMap : public multimap<string, string, StrCaseCompare>{
} }
}; };
//rtsp/http/sip解析类
class Parser { class Parser {
public: public:
Parser() {} Parser();
~Parser();
virtual ~Parser() {} //解析信令
void Parse(const char *buf);
void Parse(const char *buf) { //获取命令字
//解析 const string &Method() const;
const char *start = buf; //获取中间url不包含?后面的参数
Clear(); const string &Url() const;
while (true) { //获取中间url包含?后面的参数
auto line = FindField(start, NULL, "\r\n"); const string &FullUrl() const;
if (line.size() == 0) { //获取命令协议名
break; const string &Tail() const;
} //根据header key名获取请求header value值
if (start == buf) { const string &operator[](const char *name) const;
_strMethod = FindField(line.data(), NULL, " "); //获取http body或sdp
_strFullUrl = FindField(line.data(), " ", " "); const string &Content() const;
auto args_pos = _strFullUrl.find('?'); //清空,为了重用
if (args_pos != string::npos) { void Clear();
_strUrl = _strFullUrl.substr(0, args_pos); //获取?后面的参数
_params = _strFullUrl.substr(args_pos + 1); const string &Params() const;
_mapUrlArgs = parseArgs(_params); //重新设置url
} else { void setUrl(const string &url);
_strUrl = _strFullUrl; //重新设置content
} void setContent(const string &content);
_strTail = FindField(line.data(), (_strFullUrl + " ").data(), NULL); //获取header列表
} else { StrCaseMap &getHeader() const;
auto field = FindField(line.data(), NULL, ": "); //获取url参数列表
auto value = FindField(line.data(), ": ", NULL); StrCaseMap &getUrlArgs() const;
if (field.size() != 0) { //解析?后面的参数
_mapHeaders.emplace_force(field,value); static StrCaseMap parseArgs(const string &str, const char *pair_delim = "&", const char *key_delim = "=");
}
}
start = start + line.size() + 2;
if (strncmp(start, "\r\n", 2) == 0) { //协议解析完毕
_strContent = FindField(start, "\r\n", NULL);
break;
}
}
}
const string &Method() const {
//rtsp方法
return _strMethod;
}
const string &Url() const {
//rtsp url
return _strUrl;
}
const string &FullUrl() const {
//rtsp url with args
return _strFullUrl;
}
const string &Tail() const {
//RTSP/1.0
return _strTail;
}
const string &operator[](const char *name) const {
//rtsp field
auto it = _mapHeaders.find(name);
if (it == _mapHeaders.end()) {
return _strNull;
}
return it->second;
}
const string &Content() const {
return _strContent;
}
void Clear() {
_strMethod.clear();
_strUrl.clear();
_strFullUrl.clear();
_params.clear();
_strTail.clear();
_strContent.clear();
_mapHeaders.clear();
_mapUrlArgs.clear();
}
const string &Params() const {
return _params;
}
void setUrl(const string &url) {
this->_strUrl = url;
}
void setContent(const string &content) {
this->_strContent = content;
}
StrCaseMap &getValues() const {
return _mapHeaders;
}
StrCaseMap &getUrlArgs() const {
return _mapUrlArgs;
}
static StrCaseMap parseArgs(const string &str, const char *pair_delim = "&", const char *key_delim = "=") {
StrCaseMap ret;
auto arg_vec = split(str, pair_delim);
for (string &key_val : arg_vec) {
auto key = FindField(key_val.data(), NULL, key_delim);
auto val = FindField(key_val.data(), key_delim, NULL);
ret.emplace_force(trim(key),trim(val));
}
return ret;
}
private: private:
string _strMethod; string _strMethod;
string _strUrl; string _strUrl;

View File

@ -147,8 +147,8 @@ int64_t HttpClient::onRecvHeader(const char *data, uint64_t len) {
} }
} }
checkCookie(_parser.getValues()); checkCookie(_parser.getHeader());
_totalBodySize = onResponseHeader(_parser.Url(), _parser.getValues()); _totalBodySize = onResponseHeader(_parser.Url(), _parser.getHeader());
if(!_parser["Content-Length"].empty()){ if(!_parser["Content-Length"].empty()){
//有Content-Length字段时忽略onResponseHeader的返回值 //有Content-Length字段时忽略onResponseHeader的返回值

View File

@ -94,7 +94,7 @@ public:
return _parser.Url(); return _parser.Url();
} }
const HttpHeader &responseHeader() const{ const HttpHeader &responseHeader() const{
return _parser.getValues(); return _parser.getHeader();
} }
const Parser& response() const{ const Parser& response() const{
return _parser; return _parser;

View File

@ -325,7 +325,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
auto path = parser.Url(); auto path = parser.Url();
//先根据http头中的cookie字段获取cookie //先根据http头中的cookie字段获取cookie
HttpServerCookie::Ptr cookie = HttpCookieManager::Instance().getCookie(kCookieName, parser.getValues()); HttpServerCookie::Ptr cookie = HttpCookieManager::Instance().getCookie(kCookieName, parser.getHeader());
//如果不是从http头中找到的cookie,我们让http客户端设置下cookie //如果不是从http头中找到的cookie,我们让http客户端设置下cookie
bool cookie_from_header = true; bool cookie_from_header = true;
if (!cookie && !uid.empty()) { if (!cookie && !uid.empty()) {
@ -488,7 +488,7 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
} }
cb(codeOut.data(), HttpFileManager::getContentType(strFile.data()), headerOut, body); cb(codeOut.data(), HttpFileManager::getContentType(strFile.data()), headerOut, body);
}; };
invoker.responseFile(parser.getValues(), httpHeader, strFile); invoker.responseFile(parser.getHeader(), httpHeader, strFile);
}; };
if (!is_hls) { if (!is_hls) {

View File

@ -64,7 +64,7 @@ void initEventListener(){
} }
///////////////header////////////////// ///////////////header//////////////////
printer << "\r\nheader:\r\n"; printer << "\r\nheader:\r\n";
for(auto &pr : parser.getValues()){ for(auto &pr : parser.getHeader()){
printer << "\t" << pr.first << " : " << pr.second << "\r\n"; printer << "\t" << pr.first << " : " << pr.second << "\r\n";
} }
////////////////content///////////////// ////////////////content/////////////////