From 1d5c6cb141518860115d55464cd29d3f99ae6e8b Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Mon, 20 Apr 2020 18:13:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E8=A7=A3=E6=9E=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/source/mk_events_objects.cpp | 4 +- server/WebApi.cpp | 2 +- server/WebHook.cpp | 2 +- src/Common/Parser.cpp | 109 +++++++++++++++++++++++ src/Common/Parser.h | 147 +++++++------------------------ src/Http/HttpClient.cpp | 4 +- src/Http/HttpClient.h | 2 +- src/Http/HttpFileManager.cpp | 4 +- tests/test_httpApi.cpp | 2 +- 9 files changed, 151 insertions(+), 125 deletions(-) diff --git a/api/source/mk_events_objects.cpp b/api/source/mk_events_objects.cpp index d4249563..5b243023 100644 --- a/api/source/mk_events_objects.cpp +++ b/api/source/mk_events_objects.cpp @@ -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, diff --git a/server/WebApi.cpp b/server/WebApi.cpp index f932dd66..c22be830 100644 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -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){ diff --git a/server/WebHook.cpp b/server/WebHook.cpp index 113f2b41..34e9127e 100644 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -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 diff --git a/src/Common/Parser.cpp b/src/Common/Parser.cpp index 158201cd..1c866a64 100644 --- a/src/Common/Parser.cpp +++ b/src/Common/Parser.cpp @@ -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 \ No newline at end of file diff --git a/src/Common/Parser.h b/src/Common/Parser.h index 3630f8cd..00d2a4cb 100644 --- a/src/Common/Parser.h +++ b/src/Common/Parser.h @@ -57,122 +57,39 @@ class StrCaseMap : public multimap{ } }; +//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; diff --git a/src/Http/HttpClient.cpp b/src/Http/HttpClient.cpp index 6238afde..a1163a15 100644 --- a/src/Http/HttpClient.cpp +++ b/src/Http/HttpClient.cpp @@ -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的返回值 diff --git a/src/Http/HttpClient.h b/src/Http/HttpClient.h index e1f80b47..f78934d2 100644 --- a/src/Http/HttpClient.h +++ b/src/Http/HttpClient.h @@ -94,7 +94,7 @@ public: return _parser.Url(); } const HttpHeader &responseHeader() const{ - return _parser.getValues(); + return _parser.getHeader(); } const Parser& response() const{ return _parser; diff --git a/src/Http/HttpFileManager.cpp b/src/Http/HttpFileManager.cpp index 90a37992..1dec693f 100644 --- a/src/Http/HttpFileManager.cpp +++ b/src/Http/HttpFileManager.cpp @@ -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) { diff --git a/tests/test_httpApi.cpp b/tests/test_httpApi.cpp index 4cf3ab85..5d24c40f 100644 --- a/tests/test_httpApi.cpp +++ b/tests/test_httpApi.cpp @@ -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/////////////////