From 15edbeac3e3cfb5b4fddceecf605fc4d0c5110ac Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Thu, 30 Sep 2021 16:10:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86http=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/source/mk_httpclient.cpp | 6 +- server/WebHook.cpp | 32 ++++---- src/Common/Parser.cpp | 8 +- src/Common/Parser.h | 48 +++++++----- src/Http/HttpBody.cpp | 5 +- src/Http/HttpBody.h | 2 +- src/Http/HttpClient.cpp | 123 +++++++++++++++++++----------- src/Http/HttpClient.h | 141 ++++++++++++++++++----------------- src/Http/HttpRequester.cpp | 40 +++++----- src/Http/HttpRequester.h | 25 ++++--- tests/test_httpClient.cpp | 30 +++----- 11 files changed, 251 insertions(+), 209 deletions(-) diff --git a/api/source/mk_httpclient.cpp b/api/source/mk_httpclient.cpp index 50e02b86..0152d5a6 100755 --- a/api/source/mk_httpclient.cpp +++ b/api/source/mk_httpclient.cpp @@ -104,7 +104,7 @@ API_EXPORT void API_CALL mk_http_requester_add_header(mk_http_requester ctx,cons API_EXPORT const char* API_CALL mk_http_requester_get_response_status(mk_http_requester ctx){ assert(ctx); HttpRequester::Ptr *obj = (HttpRequester::Ptr *)ctx; - return (*obj)->responseStatus().c_str(); + return (*obj)->response().Url().c_str(); } API_EXPORT const char* API_CALL mk_http_requester_get_response_header(mk_http_requester ctx,const char *key){ @@ -131,8 +131,8 @@ API_EXPORT mk_parser API_CALL mk_http_requester_get_response(mk_http_requester c API_EXPORT void API_CALL mk_http_requester_set_cb(mk_http_requester ctx,on_mk_http_requester_complete cb, void *user_data){ assert(ctx && cb); HttpRequester::Ptr *obj = (HttpRequester::Ptr *)ctx; - (*obj)->setOnResult([cb,user_data](const SockException &ex,const string &status,const StrCaseMap &header,const string &strRecvBody){ - cb(user_data, ex.getErrCode(),ex.what()); + (*obj)->setOnResult([cb, user_data](const SockException &ex, const Parser &res) { + cb(user_data, ex.getErrCode(), ex.what()); }); } diff --git a/server/WebHook.cpp b/server/WebHook.cpp index 47a173fe..29bc6a9b 100755 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -71,33 +71,31 @@ onceToken token([](){ static void parse_http_response(const SockException &ex, - const string &status, - const HttpClient::HttpHeader &header, - const string &strRecvBody, + const Parser &res, const function &fun){ - if(ex){ + if (ex) { auto errStr = StrPrinter << "[network err]:" << ex.what() << endl; - fun(Json::nullValue,errStr); + fun(Json::nullValue, errStr); return; } - if(status != "200"){ - auto errStr = StrPrinter << "[bad http status code]:" << status << endl; - fun(Json::nullValue,errStr); + if (res.Url() != "200") { + auto errStr = StrPrinter << "[bad http status code]:" << res.Url() << endl; + fun(Json::nullValue, errStr); return; } try { - stringstream ss(strRecvBody); + stringstream ss(res.Content()); Value result; ss >> result; - if(result["code"].asInt() != 0) { + if (result["code"].asInt() != 0) { auto errStr = StrPrinter << "[json code]:" << "code=" << result["code"] << ",msg=" << result["msg"] << endl; - fun(Json::nullValue,errStr); + fun(Json::nullValue, errStr); return; } - fun(result,""); - }catch (std::exception &ex){ + fun(result, ""); + } catch (std::exception &ex) { auto errStr = StrPrinter << "[parse json failed]:" << ex.what() << endl; - fun(Json::nullValue,errStr); + fun(Json::nullValue, errStr); } } @@ -144,13 +142,11 @@ void do_http_hook(const string &url,const ArgsType &body,const function pTicker(new Ticker); requester->startRequester(url, [url, func, bodyStr, requester, pTicker](const SockException &ex, - const string &status, - const HttpClient::HttpHeader &header, - const string &strRecvBody) mutable{ + const Parser &res) mutable{ onceToken token(nullptr, [&]() mutable{ requester.reset(); }); - parse_http_response(ex,status,header,strRecvBody,[&](const Value &obj,const string &err){ + parse_http_response(ex, res, [&](const Value &obj, const string &err) { if (func) { func(obj, err); } diff --git a/src/Common/Parser.cpp b/src/Common/Parser.cpp index 1a41bbc4..14b739d2 100644 --- a/src/Common/Parser.cpp +++ b/src/Common/Parser.cpp @@ -119,12 +119,12 @@ const string &Parser::Params() const { return _params; } -void Parser::setUrl(const string &url) { - this->_strUrl = url; +void Parser::setUrl(string url) { + this->_strUrl = std::move(url); } -void Parser::setContent(const string &content) { - this->_strContent = content; +void Parser::setContent(string content) { + this->_strContent = std::move(content); } StrCaseMap &Parser::getHeader() const { diff --git a/src/Common/Parser.h b/src/Common/Parser.h index 24d12749..547b6c45 100644 --- a/src/Common/Parser.h +++ b/src/Common/Parser.h @@ -14,10 +14,11 @@ #include #include #include "Util/util.h" + using namespace std; using namespace toolkit; -namespace mediakit{ +namespace mediakit { string FindField(const char *buf, const char *start, const char *end, size_t bufSize = 0); @@ -27,33 +28,32 @@ struct StrCaseCompare { } }; - -class StrCaseMap : public multimap{ - public: - typedef multimap Super ; +class StrCaseMap : public multimap { +public: + using Super = multimap; StrCaseMap() = default; ~StrCaseMap() = default; - string &operator[](const string &k){ + string &operator[](const string &k) { auto it = find(k); - if(it == end()){ - it = Super::emplace(k,""); + if (it == end()) { + it = Super::emplace(k, ""); } return it->second; } - template + template void emplace(const string &k, V &&v) { auto it = find(k); - if(it != end()){ + if (it != end()) { return; } - Super::emplace(k,std::forward(v)); + Super::emplace(k, std::forward(v)); } - template - void emplace_force(const string k , V &&v) { - Super::emplace(k,std::forward(v)); + template + void emplace_force(const string k, V &&v) { + Super::emplace(k, std::forward(v)); } }; @@ -62,34 +62,49 @@ class Parser { public: Parser(); ~Parser(); + //解析信令 void Parse(const char *buf); + //获取命令字 const string &Method() const; + //获取中间url,不包含?后面的参数 const string &Url() const; + //获取中间url,包含?后面的参数 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); + void setUrl(string url); + //重新设置content - void setContent(const string &content); + void setContent(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; @@ -101,7 +116,6 @@ private: mutable StrCaseMap _mapUrlArgs; }; - }//namespace mediakit #endif //ZLMEDIAKIT_PARSER_H diff --git a/src/Http/HttpBody.cpp b/src/Http/HttpBody.cpp index a360645d..f2e28efa 100644 --- a/src/Http/HttpBody.cpp +++ b/src/Http/HttpBody.cpp @@ -23,8 +23,8 @@ namespace mediakit { -HttpStringBody::HttpStringBody(const string &str){ - _str = str; +HttpStringBody::HttpStringBody(string str){ + _str = std::move(str); } ssize_t HttpStringBody::remainSize() { @@ -43,6 +43,7 @@ Buffer::Ptr HttpStringBody::readData(size_t size) { } ////////////////////////////////////////////////////////////////// + HttpFileBody::HttpFileBody(const string &filePath){ std::shared_ptr fp(fopen(filePath.data(), "rb"), [](FILE *fp) { if(fp){ diff --git a/src/Http/HttpBody.h b/src/Http/HttpBody.h index 31d7ef5b..fa097cb7 100644 --- a/src/Http/HttpBody.h +++ b/src/Http/HttpBody.h @@ -68,7 +68,7 @@ public: class HttpStringBody : public HttpBody{ public: typedef std::shared_ptr Ptr; - HttpStringBody(const string &str); + HttpStringBody(string str); ~HttpStringBody() override = default; ssize_t remainSize() override; diff --git a/src/Http/HttpClient.cpp b/src/Http/HttpClient.cpp index 41217047..d2101abc 100644 --- a/src/Http/HttpClient.cpp +++ b/src/Http/HttpClient.cpp @@ -14,13 +14,6 @@ namespace mediakit { - -HttpClient::HttpClient() { -} - -HttpClient::~HttpClient() { -} - void HttpClient::sendRequest(const string &strUrl, float fTimeOutSec) { _aliveTicker.resetTime(); _url = strUrl; @@ -60,7 +53,8 @@ void HttpClient::sendRequest(const string &strUrl, float fTimeOutSec) { _header.emplace("Connection", "keep-alive"); _header.emplace("Accept", "*/*"); _header.emplace("Accept-Language", "zh-CN,zh;q=0.8"); - _header.emplace("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"); + _header.emplace("User-Agent", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"); if (_body && _body->remainSize()) { _header.emplace("Content-Length", to_string(_body->remainSize())); @@ -72,19 +66,17 @@ void HttpClient::sendRequest(const string &strUrl, float fTimeOutSec) { _isHttps = isHttps; _fTimeOutSec = fTimeOutSec; - auto cookies = HttpCookieStorage::Instance().get(_lastHost,_path); + auto cookies = HttpCookieStorage::Instance().get(_lastHost, _path); _StrPrinter printer; - for(auto &cookie : cookies){ + for (auto &cookie : cookies) { printer << cookie->getKey() << "=" << cookie->getVal() << ";"; } - if(!printer.empty()){ + if (!printer.empty()) { printer.pop_back(); _header.emplace("Cookie", printer); } - if (!alive() || bChanged) { - //InfoL << "reconnet:" << _lastHost; startConnect(host, port, fTimeOutSec); } else { SockException ex; @@ -92,6 +84,51 @@ void HttpClient::sendRequest(const string &strUrl, float fTimeOutSec) { } } +void HttpClient::clear() { + _header.clear(); + _body.reset(); + _method.clear(); + _path.clear(); + _parser.Clear(); + _recvedBodySize = 0; + _totalBodySize = 0; + _aliveTicker.resetTime(); + _chunkedSplitter.reset(); + HttpRequestSplitter::reset(); +} + +void HttpClient::setMethod(string method) { + _method = std::move(method); +} + +void HttpClient::setHeader(HttpHeader header) { + _header = std::move(header); +} + +HttpClient &HttpClient::addHeader(string key, string val, bool force) { + if (!force) { + _header.emplace(std::move(key), std::move(val)); + } else { + _header[std::move(key)] = std::move(val); + } + return *this; +} + +void HttpClient::setBody(string body) { + _body.reset(new HttpStringBody(std::move(body))); +} + +void HttpClient::setBody(HttpBody::Ptr body) { + _body = std::move(body); +} + +const Parser &HttpClient::response() const { + return _parser; +} + +const string &HttpClient::getUrl() const { + return _url; +} void HttpClient::onConnect(const SockException &ex) { _aliveTicker.resetTime(); @@ -131,16 +168,16 @@ void HttpClient::onErr(const SockException &ex) { ssize_t HttpClient::onRecvHeader(const char *data, size_t len) { _parser.Parse(data); - if(_parser.Url() == "302" || _parser.Url() == "301"){ + if (_parser.Url() == "302" || _parser.Url() == "301") { auto newUrl = _parser["Location"]; - if(newUrl.empty()){ - shutdown(SockException(Err_shutdown,"未找到Location字段(跳转url)")); + if (newUrl.empty()) { + shutdown(SockException(Err_shutdown, "未找到Location字段(跳转url)")); return 0; } - if(onRedirectUrl(newUrl,_parser.Url() == "302")){ + if (onRedirectUrl(newUrl, _parser.Url() == "302")) { HttpClient::clear(); setMethod("GET"); - HttpClient::sendRequest(newUrl,_fTimeOutSec); + HttpClient::sendRequest(newUrl, _fTimeOutSec); return 0; } } @@ -148,26 +185,26 @@ ssize_t HttpClient::onRecvHeader(const char *data, size_t len) { checkCookie(_parser.getHeader()); _totalBodySize = onResponseHeader(_parser.Url(), _parser.getHeader()); - if(!_parser["Content-Length"].empty()){ + if (!_parser["Content-Length"].empty()) { //有Content-Length字段时忽略onResponseHeader的返回值 _totalBodySize = atoll(_parser["Content-Length"].data()); } - if(_parser["Transfer-Encoding"] == "chunked"){ + if (_parser["Transfer-Encoding"] == "chunked") { //如果Transfer-Encoding字段等于chunked,则认为后续的content是不限制长度的 _totalBodySize = -1; - _chunkedSplitter = std::make_shared([this](const char *data,size_t len){ - if(len > 0){ + _chunkedSplitter = std::make_shared([this](const char *data, size_t len) { + if (len > 0) { auto recvedBodySize = _recvedBodySize + len; onResponseBody(data, len, recvedBodySize, SIZE_MAX); _recvedBodySize = recvedBodySize; - }else{ + } else { onResponseCompleted_l(); } }); } - if(_totalBodySize == 0){ + if (_totalBodySize == 0) { //后续没content,本次http请求结束 onResponseCompleted_l(); return 0; @@ -182,12 +219,12 @@ ssize_t HttpClient::onRecvHeader(const char *data, size_t len) { } void HttpClient::onRecvContent(const char *data, size_t len) { - if(_chunkedSplitter){ - _chunkedSplitter->input(data,len); + if (_chunkedSplitter) { + _chunkedSplitter->input(data, len); return; } auto recvedBodySize = _recvedBodySize + len; - if(_totalBodySize < 0){ + if (_totalBodySize < 0) { //不限长度的content,最大支持SIZE_MAX个字节 onResponseBody(data, len, recvedBodySize, SIZE_MAX); _recvedBodySize = recvedBodySize; @@ -195,7 +232,7 @@ void HttpClient::onRecvContent(const char *data, size_t len) { } //固定长度的content - if (recvedBodySize < (size_t)_totalBodySize ) { + if (recvedBodySize < (size_t) _totalBodySize) { //content还未接收完毕 onResponseBody(data, len, recvedBodySize, _totalBodySize); _recvedBodySize = recvedBodySize; @@ -204,9 +241,9 @@ void HttpClient::onRecvContent(const char *data, size_t len) { //content接收完毕 onResponseBody(data, _totalBodySize - _recvedBodySize, _totalBodySize, _totalBodySize); - bool biggerThanExpected = recvedBodySize > (size_t)_totalBodySize; + bool biggerThanExpected = recvedBodySize > (size_t) _totalBodySize; onResponseCompleted_l(); - if(biggerThanExpected) { + if (biggerThanExpected) { //声明的content数据比真实的小,那么我们只截取前面部分的并断开链接 shutdown(SockException(Err_shutdown, "http response content size bigger than expected")); } @@ -214,7 +251,7 @@ void HttpClient::onRecvContent(const char *data, size_t len) { void HttpClient::onFlush() { _aliveTicker.resetTime(); - GET_CONFIG(uint32_t,sendBufSize,Http::kSendBufSize); + GET_CONFIG(uint32_t, sendBufSize, Http::kSendBufSize); while (_body && _body->remainSize() && !isSocketBusy()) { auto buffer = _body->readData(sendBufSize); if (!buffer) { @@ -250,34 +287,34 @@ void HttpClient::onResponseCompleted_l() { void HttpClient::checkCookie(HttpClient::HttpHeader &headers) { //Set-Cookie: IPTV_SERVER=8E03927B-CC8C-4389-BC00-31DBA7EC7B49;expires=Sun, Sep 23 2018 15:07:31 GMT;path=/index/api/ - for(auto it_set_cookie = headers.find("Set-Cookie") ; it_set_cookie != headers.end() ; ++it_set_cookie ){ - auto key_val = Parser::parseArgs(it_set_cookie->second,";","="); + for (auto it_set_cookie = headers.find("Set-Cookie"); it_set_cookie != headers.end(); ++it_set_cookie) { + auto key_val = Parser::parseArgs(it_set_cookie->second, ";", "="); HttpCookie::Ptr cookie = std::make_shared(); cookie->setHost(_lastHost); int index = 0; auto arg_vec = split(it_set_cookie->second, ";"); for (string &key_val : arg_vec) { - auto key = FindField(key_val.data(),NULL,"="); - auto val = FindField(key_val.data(),"=", NULL); + auto key = FindField(key_val.data(), NULL, "="); + auto val = FindField(key_val.data(), "=", NULL); - if(index++ == 0){ - cookie->setKeyVal(key,val); + if (index++ == 0) { + cookie->setKeyVal(key, val); continue; } - if(key == "path") { + if (key == "path") { cookie->setPath(val); continue; } - if(key == "expires"){ - cookie->setExpires(val,headers["Date"]); + if (key == "expires") { + cookie->setExpires(val, headers["Date"]); continue; } } - if(!(*cookie)){ + if (!(*cookie)) { //无效的cookie continue; } @@ -285,6 +322,4 @@ void HttpClient::checkCookie(HttpClient::HttpHeader &headers) { } } - -} /* namespace mediakit */ - +} /* namespace mediakit */ \ No newline at end of file diff --git a/src/Http/HttpClient.h b/src/Http/HttpClient.h index c3cce623..61354f7d 100644 --- a/src/Http/HttpClient.h +++ b/src/Http/HttpClient.h @@ -24,84 +24,88 @@ #include "HttpChunkedSplitter.h" #include "strCoding.h" #include "HttpBody.h" + using namespace std; using namespace toolkit; namespace mediakit { -class HttpArgs : public map { +class HttpArgs : public map { public: - HttpArgs(){} - virtual ~HttpArgs(){} + HttpArgs() = default; + ~HttpArgs() = default; + string make() const { string ret; - for(auto &pr : *this){ + for (auto &pr : *this) { ret.append(pr.first); ret.append("="); ret.append(strCoding::UrlEncode(pr.second)); ret.append("&"); } - if(ret.size()){ + if (ret.size()) { ret.pop_back(); } return ret; } }; -class HttpClient : public TcpClient , public HttpRequestSplitter{ +class HttpClient : public TcpClient, public HttpRequestSplitter { public: - typedef StrCaseMap HttpHeader; - typedef std::shared_ptr Ptr; - HttpClient(); - virtual ~HttpClient(); - virtual void sendRequest(const string &url,float fTimeOutSec); + using HttpHeader = StrCaseMap; + using Ptr = std::shared_ptr; - virtual void clear(){ - _header.clear(); - _body.reset(); - _method.clear(); - _path.clear(); - _parser.Clear(); - _recvedBodySize = 0; - _totalBodySize = 0; - _aliveTicker.resetTime(); - _chunkedSplitter.reset(); - HttpRequestSplitter::reset(); - } + HttpClient() = default; + ~HttpClient() override = default; - void setMethod(const string &method){ - _method = method; - } - void setHeader(const HttpHeader &header){ - _header = header; - } - HttpClient & addHeader(const string &key,const string &val,bool force = false){ - if(!force){ - _header.emplace(key,val); - }else{ - _header[key] = val; - } - return *this; - } - void setBody(const string &body){ - _body.reset(new HttpStringBody(body)); - } - void setBody(const HttpBody::Ptr &body){ - _body = body; - } - const string &responseStatus() const{ - return _parser.Url(); - } - const HttpHeader &responseHeader() const{ - return _parser.getHeader(); - } - const Parser& response() const{ - return _parser; - } + /** + * 发送http[s]请求 + * @param url 请求url + * @param fTimeOutSec 超时时间 + */ + virtual void sendRequest(const string &url, float fTimeOutSec); + + /** + * 重置对象 + */ + virtual void clear(); + + /** + * 设置http方法 + * @param method GET/POST等 + */ + void setMethod(string method); + + /** + * 覆盖http头 + * @param header + */ + void setHeader(HttpHeader header); + + HttpClient &addHeader(string key, string val, bool force = false); + + /** + * 设置http content + * @param body http content + */ + void setBody(string body); + + /** + * 设置http content + * @param body http content + */ + void setBody(HttpBody::Ptr body); + + /** + * 获取回复,在收到完整回复后有效 + */ + const Parser &response() const; + + /** + * 获取请求url + */ + const string &getUrl() const; - const string &getUrl() const{ - return _url; - } protected: /** * 收到http回复头 @@ -110,7 +114,7 @@ protected: * @return 返回后续content的长度;-1:后续数据全是content;>=0:固定长度content * 需要指出的是,在http头中带有Content-Length字段时,该返回值无效 */ - virtual ssize_t onResponseHeader(const string &status,const HttpHeader &headers){ + virtual ssize_t onResponseHeader(const string &status, const HttpHeader &headers) { //无Content-Length字段时默认后面全是content return -1; } @@ -129,7 +133,7 @@ protected: /** * 接收http回复完毕, */ - virtual void onResponseCompleted(){ + virtual void onResponseCompleted() { DebugL; } @@ -137,7 +141,7 @@ protected: * http链接断开回调 * @param ex 断开原因 */ - virtual void onDisconnect(const SockException &ex){} + virtual void onDisconnect(const SockException &ex) {} /** * 重定向事件 @@ -145,22 +149,23 @@ protected: * @param temporary 是否为临时重定向 * @return 是否继续 */ - virtual bool onRedirectUrl(const string &url,bool temporary){ return true;}; + virtual bool onRedirectUrl(const string &url, bool temporary) { return true; }; - //HttpRequestSplitter override - ssize_t onRecvHeader(const char *data,size_t len) override; - void onRecvContent(const char *data,size_t len) override; + //// HttpRequestSplitter override //// + ssize_t onRecvHeader(const char *data, size_t len) override; + void onRecvContent(const char *data, size_t len) override; protected: - virtual void onConnect(const SockException &ex) override; - virtual void onRecv(const Buffer::Ptr &pBuf) override; - virtual void onErr(const SockException &ex) override; - virtual void onFlush() override; - virtual void onManager() override; + //// TcpClient override //// + void onConnect(const SockException &ex) override; + void onRecv(const Buffer::Ptr &pBuf) override; + void onErr(const SockException &ex) override; + void onFlush() override; + void onManager() override; private: void onResponseCompleted_l(); - void checkCookie(HttpHeader &headers ); + void checkCookie(HttpHeader &headers); protected: bool _isHttps; diff --git a/src/Http/HttpRequester.cpp b/src/Http/HttpRequester.cpp index 37ccadd5..30b70a8f 100644 --- a/src/Http/HttpRequester.cpp +++ b/src/Http/HttpRequester.cpp @@ -10,42 +10,36 @@ #include "HttpRequester.h" -namespace mediakit{ +namespace mediakit { -HttpRequester::HttpRequester(){ - -} -HttpRequester::~HttpRequester(){ - -} - -ssize_t HttpRequester::onResponseHeader(const string &status,const HttpHeader &headers) { +ssize_t HttpRequester::onResponseHeader(const string &status, const HttpHeader &headers) { _strRecvBody.clear(); return HttpClientImp::onResponseHeader(status, headers); } - -void HttpRequester::onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) { - _strRecvBody.append(buf,size); + +void HttpRequester::onResponseBody(const char *buf, size_t size, size_t recvedSize, size_t totalSize) { + _strRecvBody.append(buf, size); } - + void HttpRequester::onResponseCompleted() { - if(_onResult){ - _onResult(SockException(),responseStatus(),responseHeader(),_strRecvBody); + const_cast (response()).setContent(std::move(_strRecvBody)); + if (_onResult) { + _onResult(SockException(), response()); _onResult = nullptr; } } - -void HttpRequester::onDisconnect(const SockException &ex){ - if(_onResult){ - const_cast(response()).setContent(_strRecvBody); - _onResult(ex,responseStatus(),responseHeader(),_strRecvBody); + +void HttpRequester::onDisconnect(const SockException &ex) { + const_cast (response()).setContent(std::move(_strRecvBody)); + if (_onResult) { + _onResult(ex, response()); _onResult = nullptr; } } - -void HttpRequester::startRequester(const string &url,const HttpRequesterResult &onResult , float timeOutSecond){ + +void HttpRequester::startRequester(const string &url, const HttpRequesterResult &onResult, float timeOutSecond) { _onResult = onResult; - sendRequest(url,timeOutSecond); + sendRequest(url, timeOutSecond); } void HttpRequester::clear() { diff --git a/src/Http/HttpRequester.h b/src/Http/HttpRequester.h index a653e13e..dc602f5d 100644 --- a/src/Http/HttpRequester.h +++ b/src/Http/HttpRequester.h @@ -13,23 +13,26 @@ #include "HttpClientImp.h" -namespace mediakit{ +namespace mediakit { -class HttpRequester : public HttpClientImp -{ +class HttpRequester : public HttpClientImp { public: - typedef std::shared_ptr Ptr; - typedef std::function HttpRequesterResult; - HttpRequester(); - virtual ~HttpRequester(); + using Ptr = std::shared_ptr; + using HttpRequesterResult = std::function; + + HttpRequester() = default; + ~HttpRequester() override = default; + void setOnResult(const HttpRequesterResult &onResult); - void startRequester(const string &url,const HttpRequesterResult &onResult,float timeOutSecond = 10); - void clear() override ; + void startRequester(const string &url, const HttpRequesterResult &onResult, float timeOutSecond = 10); + void clear() override; + private: - ssize_t onResponseHeader(const string &status,const HttpHeader &headers) override; - void onResponseBody(const char *buf,size_t size,size_t recvedSize,size_t totalSize) override; + ssize_t onResponseHeader(const string &status, const HttpHeader &headers) override; + void onResponseBody(const char *buf, size_t size, size_t recvedSize, size_t totalSize) override; void onResponseCompleted() override; void onDisconnect(const SockException &ex) override; + private: string _strRecvBody; HttpRequesterResult _onResult; diff --git a/tests/test_httpClient.cpp b/tests/test_httpClient.cpp index 8f5b73e7..869c5121 100644 --- a/tests/test_httpClient.cpp +++ b/tests/test_httpClient.cpp @@ -76,9 +76,7 @@ int main(int argc, char *argv[]) { //开启请求,该api会返回当前主机外网ip等信息 requesterGet->startRequester("http://pv.sohu.com/cityjson?ie=utf-8",//url地址 [](const SockException &ex, //网络相关的失败信息,如果为空就代表成功 - const string &status, //http回复的状态码,比如说200/404 - const HttpClient::HttpHeader &header, //http回复头 - const string &strRecvBody) { //http回复body + const Parser &parser) { //http回复body DebugL << "=====================HttpRequester GET==========================="; if (ex) { //网络相关的错误 @@ -86,12 +84,12 @@ int main(int argc, char *argv[]) { } else { //打印http回复信息 _StrPrinter printer; - for (auto &pr: header) { + for (auto &pr: parser.getHeader()) { printer << pr.first << ":" << pr.second << "\r\n"; } - InfoL << "status:" << status << "\r\n" + InfoL << "status:" << parser.Url() << "\r\n" << "header:\r\n" << (printer << endl) - << "\r\nbody:" << strRecvBody; + << "\r\nbody:" << parser.Content(); } }); @@ -114,9 +112,7 @@ int main(int argc, char *argv[]) { //开启请求 requesterPost->startRequester("http://fanyi.baidu.com/langdetect",//url地址 [](const SockException &ex, //网络相关的失败信息,如果为空就代表成功 - const string &status, //http回复的状态码,比如说200/404 - const HttpClient::HttpHeader &header, //http回复头 - const string &strRecvBody) { //http回复body + const Parser &parser) { //http回复body DebugL << "=====================HttpRequester POST=========================="; if (ex) { //网络相关的错误 @@ -124,12 +120,12 @@ int main(int argc, char *argv[]) { } else { //打印http回复信息 _StrPrinter printer; - for (auto &pr: header) { + for (auto &pr: parser.getHeader()) { printer << pr.first << ":" << pr.second << "\r\n"; } - InfoL << "status:" << status << "\r\n" + InfoL << "status:" << parser.Url() << "\r\n" << "header:\r\n" << (printer << endl) - << "\r\nbody:" << strRecvBody; + << "\r\nbody:" << parser.Content(); } }); @@ -153,9 +149,7 @@ int main(int argc, char *argv[]) { //开启请求 requesterUploader->startRequester("http://fanyi.baidu.com/langdetect",//url地址 [](const SockException &ex, //网络相关的失败信息,如果为空就代表成功 - const string &status, //http回复的状态码,比如说200/404 - const HttpClient::HttpHeader &header, //http回复头 - const string &strRecvBody) { //http回复body + const Parser &parser) { //http回复body DebugL << "=====================HttpRequester Uploader=========================="; if (ex) { //网络相关的错误 @@ -163,12 +157,12 @@ int main(int argc, char *argv[]) { } else { //打印http回复信息 _StrPrinter printer; - for (auto &pr: header) { + for (auto &pr: parser.getHeader()) { printer << pr.first << ":" << pr.second << "\r\n"; } - InfoL << "status:" << status << "\r\n" + InfoL << "status:" << parser.Url() << "\r\n" << "header:\r\n" << (printer << endl) - << "\r\nbody:" << strRecvBody; + << "\r\nbody:" << parser.Content(); } });