整理解析器

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){
assert(ctx && key);
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){
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);
auto header = get_http_header(response_header);
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,

View File

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

View File

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

View File

@ -57,122 +57,39 @@ class StrCaseMap : public multimap<string, string, StrCaseCompare>{
}
};
//rtsp/http/sip解析类
class Parser {
public:
Parser() {}
virtual ~Parser() {}
void 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 &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;
}
public:
Parser();
~Parser();
//解析信令
void Parse(const char *buf);
//获取命令字
const string &Method() const;
//获取中间url不包含?后面的参数
const string &Url() const;
//获取中间url包含?后面的参数
const string &FullUrl() const;
//获取命令协议名
const string &Tail() const;
//根据header key名获取请求header value值
const string &operator[](const char *name) const;
//获取http body或sdp
const string &Content() const;
//清空,为了重用
void Clear();
//获取?后面的参数
const string &Params() const;
//重新设置url
void setUrl(const string &url);
//重新设置content
void setContent(const string &content);
//获取header列表
StrCaseMap &getHeader() const;
//获取url参数列表
StrCaseMap &getUrlArgs() const;
//解析?后面的参数
static StrCaseMap parseArgs(const string &str, const char *pair_delim = "&", const char *key_delim = "=");
private:
string _strMethod;
string _strUrl;

View File

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

View File

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

View File

@ -325,7 +325,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
auto path = parser.Url();
//先根据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
bool cookie_from_header = true;
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);
};
invoker.responseFile(parser.getValues(), httpHeader, strFile);
invoker.responseFile(parser.getHeader(), httpHeader, strFile);
};
if (!is_hls) {

View File

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