From 96c0a8bbd1ed2a12d25792a6c2318c12258c5ae3 Mon Sep 17 00:00:00 2001 From: jarodruan Date: Mon, 17 Feb 2020 20:16:18 +0800 Subject: [PATCH] http2 sync and async succ, modify async interface --- examples/HttpDemo/Http2Client/main.cpp | 4 +- examples/HttpDemo/Http2Server/Http2Imp.cpp | 61 +-- examples/HttpDemo/Http2Server/HttpServer.cpp | 7 +- servant/libservant/AppProtocol.cpp | 22 +- servant/libservant/ServantProxy.cpp | 6 +- servant/servant/ServantProxy.h | 4 +- util/include/util/tc_http.h | 35 +- util/include/util/tc_http2.h | 97 ++--- util/src/tc_http.cpp | 8 + util/src/tc_http2.cpp | 427 +++---------------- 10 files changed, 138 insertions(+), 533 deletions(-) diff --git a/examples/HttpDemo/Http2Client/main.cpp b/examples/HttpDemo/Http2Client/main.cpp index 95e863b..d7198b9 100644 --- a/examples/HttpDemo/Http2Client/main.cpp +++ b/examples/HttpDemo/Http2Client/main.cpp @@ -112,8 +112,6 @@ void asyncRpc2(int c) int64_t t = TC_Common::now2us(); std::map header; - header[":path"] = "/"; - header[":method"] = "POST"; header[":authority"] = "domain.com"; header[":scheme"] = "http"; @@ -124,7 +122,7 @@ void asyncRpc2(int c) try { - param.servant2Prx->http_call_async(header, "helloworld", p); + param.servant2Prx->http_call_async("POST", "/", header, "helloworld", p); } catch(exception& e) { diff --git a/examples/HttpDemo/Http2Server/Http2Imp.cpp b/examples/HttpDemo/Http2Server/Http2Imp.cpp index 9b30c79..823e19e 100644 --- a/examples/HttpDemo/Http2Server/Http2Imp.cpp +++ b/examples/HttpDemo/Http2Server/Http2Imp.cpp @@ -36,33 +36,21 @@ void Http2Imp::destroy() //destroy servant here: //... } -// -//void doRequestFunc(const TC_Http2Server::Req_Type reqtype, const string &requri, const TC_Http::http_header_type &reqHeader, const string &reqBody, TC_Http2Server::Http2Response &rsp) -//{ -// rsp.status = 200; -// rsp.about = "OK"; -// rsp.body = "response helloworld 2"; -//} int Http2Imp::doRequest(TarsCurrentPtr current, vector &buffer) { shared_ptr session = getHttp2(current->getUId()); -// cout << "doRequest:" << session << ", buffer size:" << current->getRequestBuffer().size() << endl; - - vector contexts; - - session->decodeRequest(contexts); - -// cout << "doRequest context size:" << contexts.size() << endl; + vector> contexts = session->decodeRequest(); for(size_t i = 0; i< contexts.size(); ++i) { - TC_Http2Server::Http2Context & context = contexts[i]; + shared_ptr context = contexts[i]; + vector data; - context.response.setHeader("X-Header", "TARS"); - context.response.setResponse(200, "OK", context.request.getContent()); + context->response.setHeader("X-Header", "TARS"); + context->response.setResponse(200, "OK", context->request.getContent()); int ret = session->encodeResponse(context, data); if(ret != 0) @@ -72,50 +60,11 @@ int Http2Imp::doRequest(TarsCurrentPtr current, vector &buffer) buffer.insert(buffer.end(), data.begin(), data.end()); } -// cout << "doRequest buffer size:" << buffer.size() << endl; - -// static bool flag = true; -// if(flag) -// { -// //method 1: -// vector vtReqid; -// TC_Http2Server::doRequest(current->getRequestBuffer(), vtReqid); -// -// // cout << "doRequest size:" << vtReqid.size() << endl; -// -// TC_Http2Server::Http2Response rsp; -// rsp.status = 200; -// rsp.about = "OK"; -// rsp.body = "response helloworld 1"; -// -// for(size_t i = 0; i < vtReqid.size(); i++) -// { -// string rbody; -// session->getBody(vtReqid[i], rbody); -// -//// cout << vtReqid[i] << ", " << rbody << endl; -// -// vector data; -// session->doResponse(vtReqid[i], rsp, data); -// buffer.insert(buffer.end(), data.begin(), data.end()); -// -// -// } -// } -// else -// { -// //method 2: -// session->doRequest(current->getRequestBuffer(), doRequestFunc, buffer); -// } - - // flag = !flag; - return 0; } int Http2Imp::doClose(TarsCurrentPtr current) { - cout << "doClose" << endl; delHttp2(current->getUId()); return 0; diff --git a/examples/HttpDemo/Http2Server/HttpServer.cpp b/examples/HttpDemo/Http2Server/HttpServer.cpp index eff7dd2..dad0406 100644 --- a/examples/HttpDemo/Http2Server/HttpServer.cpp +++ b/examples/HttpDemo/Http2Server/HttpServer.cpp @@ -29,7 +29,6 @@ TC_NetWorkBuffer::PACKET_TYPE parseHttp2(TC_NetWorkBuffer&in, vector &out) if(sessionPtr == NULL) { shared_ptr session(new TC_Http2Server()); -// in.setContextData(session, [=]{delete session;}); in.setContextData(session.get()); session->settings(3000); @@ -40,11 +39,7 @@ TC_NetWorkBuffer::PACKET_TYPE parseHttp2(TC_NetWorkBuffer&in, vector &out) sessionPtr = session.get(); } - TC_NetWorkBuffer::PACKET_TYPE flag = sessionPtr->parse(in, out); - -// cout << "parseHttp2:" << session << ", out size:" << out.size() << endl; - - return flag; + return sessionPtr->parse(in, out); } diff --git a/servant/libservant/AppProtocol.cpp b/servant/libservant/AppProtocol.cpp index 21d8b99..85b0408 100644 --- a/servant/libservant/AppProtocol.cpp +++ b/servant/libservant/AppProtocol.cpp @@ -169,8 +169,6 @@ static ssize_t reqbody_read_callback(nghttp2_session *session, int32_t stream_id // ENCODE function, called by network thread vector ProxyProtocol::http2Request(RequestPacket& request, Transceiver *trans) { -// std::lock_guard l(m); - TC_Http2Client* session = (TC_Http2Client*)trans->getSendBuffer()->getContextData(); if(session == NULL) { @@ -208,7 +206,6 @@ vector ProxyProtocol::http2Request(RequestPacket& request, Transceiver *tr data.read_callback = reqbody_read_callback; } -// cout << "pData:" << pData << ", " << data.read_callback << endl; int32_t sid = nghttp2_submit_request(session->session(), NULL, nva.data(), @@ -230,15 +227,8 @@ vector ProxyProtocol::http2Request(RequestPacket& request, Transceiver *tr TLOGERROR("[TARS]http2Request::Fatal error: nghttp2_session_send return: " << nghttp2_strerror(rv) << ", " << std::this_thread::get_id() << ", session:" << session << endl); return vector(); } -// else -// { -// cout << "send" << endl; -// } - // cout << "nghttp2_session_send, id:" << request.iRequestId << ", buff size:" << session->_buffer().size() << endl; vector out; -// out.swap(session->buffer()); - session->swap(out); return out; @@ -246,8 +236,6 @@ vector ProxyProtocol::http2Request(RequestPacket& request, Transceiver *tr TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in, ResponsePacket& rsp) { -// std::lock_guard l(m); - TC_Http2Client* session = (TC_Http2Client*)((Transceiver*)(in.getConnection()))->getSendBuffer()->getContextData(); if(session == NULL) { @@ -273,7 +261,6 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in, pair buffer = in.getBufferPointer(); -// cout << "size:" << buffer.second << endl; int readlen = nghttp2_session_mem_recv(session->session(), (const uint8_t*)buffer.first, buffer.second); if (readlen < 0) { @@ -286,16 +273,13 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in, if(session->doneResponses().empty()) { -// cout << "doneResponses empty" << endl; return TC_NetWorkBuffer::PACKET_LESS; } it = session->doneResponses().begin(); - rsp.iRequestId = it->second.streamId; - rsp.status = it->second.headers; - rsp.sBuffer.swap(it->second.body); - -// cout << "http2Response id:" << it->second.streamId << endl; + rsp.iRequestId = it->first; + it->second->getHeaders(rsp.status); + rsp.sBuffer.assign(it->second->getContent().begin(), it->second->getContent().end()); session->doneResponses().erase(it); diff --git a/servant/libservant/ServantProxy.cpp b/servant/libservant/ServantProxy.cpp index 8652ca4..c2e8cde 100644 --- a/servant/libservant/ServantProxy.cpp +++ b/servant/libservant/ServantProxy.cpp @@ -893,7 +893,9 @@ void ServantProxy::http_call(const std::string& method, msg = NULL; } -void ServantProxy::http_call_async(const std::map& headers, +void ServantProxy::http_call_async(const std::string& method, + const std::string& uri, + const std::map& headers, const std::string& body, const HttpCallbackPtr &cb) { @@ -902,6 +904,8 @@ void ServantProxy::http_call_async(const std::map& hea msg->init(ReqMessage::ASYNC_CALL, NULL, ""); msg->bFromRpc = true; + msg->request.sServantName = uri; + msg->request.sFuncName = method; // 使用下面两个字段保存头部和包体 msg->request.context = headers; msg->request.sBuffer.assign(body.begin(), body.end()); diff --git a/servant/servant/ServantProxy.h b/servant/servant/ServantProxy.h index 553bf4e..f80d2e9 100644 --- a/servant/servant/ServantProxy.h +++ b/servant/servant/ServantProxy.h @@ -644,7 +644,9 @@ public: /** * http2协议异步远程调用 */ - void http_call_async(const std::map& headers, + void http_call_async(const std::string& method, + const std::string& uri, + const std::map& headers, const std::string& body, const HttpCallbackPtr &cb); diff --git a/util/include/util/tc_http.h b/util/include/util/tc_http.h index 0fea608..4510c5b 100755 --- a/util/include/util/tc_http.h +++ b/util/include/util/tc_http.h @@ -380,7 +380,7 @@ public: /** * @brief 删除头部. - * + * * @param sHeader:头部信息 */ void eraseHeader(const string &sHeader) { _headers.erase(sHeader); } @@ -489,12 +489,12 @@ public: */ void setHeaderMulti(const string &sHeadName, const string &sHeadValue) { - _headers.insert(multimap::value_type(sHeadName, sHeadValue)); + _headers.insert(multimap::value_type(sHeadName, sHeadValue)); } /** * @brief 获取头(重复的也提取). - * + * * @param sHeadName header的名字 * @return vectorheader的值 */ @@ -534,6 +534,23 @@ public: */ string &getContent() { return _content; } + /** + * append content + * @param append + * @param bUpdateContentLength + */ + void appendContent(const char *buff, size_t len, bool bUpdateContentLength = false) + { + _content.append(buff, len); + + if(bUpdateContentLength) + { + eraseHeader("Content-Length"); + if(_content.length() > 0) + setContentLength(_content.length()); + } + } + /** * @brief 设置http body(默认不修改content-length). * @@ -572,12 +589,18 @@ public: * * @return http_header_type& */ - const http_header_type& getHeaders() const{return _headers;} + const http_header_type& getHeaders() const{return _headers;} + + /** + * get headers + * @param header + */ + void getHeaders(map &header); /** * @brief 重置 */ - void reset(); + void reset(); /** * @brief 读取一行. @@ -945,7 +968,7 @@ public: /** * @brief 获取Set-Cookie. - * + * * @return vector */ vector getSetCookie() const; diff --git a/util/include/util/tc_http2.h b/util/include/util/tc_http2.h index af0b869..475e66f 100644 --- a/util/include/util/tc_http2.h +++ b/util/include/util/tc_http2.h @@ -23,6 +23,9 @@ public: */ virtual ~TC_Http2(); + /** + * data pack + */ struct DataPack { DataPack(const char *data, size_t length) : _dataBuf(data), _length(length) {} @@ -94,16 +97,24 @@ class TC_Http2Server : public TC_Http2 { public: + /** + * constructor + */ TC_Http2Server(); + /** + * deconstructor + */ ~TC_Http2Server(); + /** + * context + */ struct Http2Context { -// Http2Context(int32_t id) : reqId(id) {} + Http2Context(int32_t id) : reqId(id) {} int32_t reqId; - bool bFinish = false; TC_HttpRequest request; TC_HttpResponse response; }; @@ -111,10 +122,10 @@ public: /** * parse all request * @param request - * @param unordered_map> + * @param vector> * @return */ - void decodeRequest(vector &contexts); + vector> decodeRequest(); /** * @@ -123,7 +134,7 @@ public: * @param out * @return */ - int encodeResponse(const Http2Context &context, vector &out); + int encodeResponse(const shared_ptr &context, vector &out); /** * http2 @@ -133,7 +144,6 @@ public: */ TC_NetWorkBuffer::PACKET_TYPE parse(TC_NetWorkBuffer&in, vector &out); - void onHeaderCallback(int32_t streamId); void onHeaderCallback(int32_t streamId, const string &skey, const string &svalue); void onFrameRecvCallback(int32_t streamId); @@ -142,28 +152,20 @@ public: protected: - Http2Context &getContext(int32_t streamId); + shared_ptr getContext(int32_t streamId); + void deleteContext(int32_t streamId); protected: -// TC_SpinLock _contextLock; -// TC_ThreadMutex _contextLock; + TC_ThreadMutex _nghttpLock; -// TC_SpinLock reqLock_; -// unordered_map _mReq; + unordered_map> _context; -// unordered_map _mReq; -// unordered_map> _context; - unordered_map _context; - - vector _contextFinished; + vector> _contextFinished; vector _reqout; - bool _bNewCon; - - TC_ThreadMutex _nghttpLock; }; ///////////////////////////////////////////////////////////////////////////////// @@ -172,72 +174,37 @@ class TC_Http2Client : public TC_Http2 { public: - enum ResponseState - { - ResponseNone, - ResponseHeadersDone, - ResponseBodyDone, - }; - - struct Http2Response - { - int streamId; - std::map headers; - vector body; - ResponseState state; - - void swap(Http2Response& other); - }; - + /** + * constructor + */ TC_Http2Client(); + /** + * deconstructor + */ ~TC_Http2Client(); -public: -// /** -// * @brief HTTP2握手+setting -// */ -// int settings(unsigned int maxCurrentStreams = 2000); -// /** -// * @brief 当前缓冲区 -// */ -// vector& sendBuffer() { return _sendBuf; } -// -// /** -// * @brief session -// */ -// nghttp2_session* session() const { return _session; } - - /** + /** * @brief response */ - std::unordered_map &responses() { return _responses; } + std::unordered_map> &responses() { return _responses; } /** * @brief response finished */ - std::unordered_map &doneResponses() { return _doneResponses; } + std::unordered_map> &doneResponses() { return _doneResponses; } private: -// /** -// * session -// */ -// nghttp2_session* _session; -// -// /** -// * 发送缓存区,由send callback填充 -// */ -// vector _sendBuf; /** * 收到的响应 */ - std::unordered_map _responses; + std::unordered_map> _responses; /** * 收到的完整响应 */ - std::unordered_map _doneResponses; + std::unordered_map> _doneResponses; }; } diff --git a/util/src/tc_http.cpp b/util/src/tc_http.cpp index 72a0d73..6fecade 100755 --- a/util/src/tc_http.cpp +++ b/util/src/tc_http.cpp @@ -708,6 +708,14 @@ void TC_Http::reset() _bIsChunked = false; } +void TC_Http::getHeaders(map &header) +{ + for(auto it = _headers.begin(); it != _headers.end(); ++it) + { + header.insert(map::value_type(it->first, it->second)); + } +} + /********************* TC_HttpCookie ***********************/ bool TC_HttpCookie::matchDomain(const string &sCookieDomain, const string &sDomain) diff --git a/util/src/tc_http2.cpp b/util/src/tc_http2.cpp index ad1e423..bbb9a3a 100644 --- a/util/src/tc_http2.cpp +++ b/util/src/tc_http2.cpp @@ -168,95 +168,63 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, void TC_Http2Server::onHeaderCallback(int streamId) { -// TC_LockT lock(_nghttpLock); - - _context[streamId].reqId = streamId; + _context[streamId] = std::make_shared(streamId); } void TC_Http2Server::onHeaderCallback(int32_t streamId, const string &skey, const string &svalue) { - TC_Http2Server::Http2Context & context = getContext(streamId); + shared_ptr context = getContext(streamId); if (TC_Port::strcasecmp(skey.c_str(), ":method") == 0) { - context.request.setMethod(svalue.c_str()); + context->request.setMethod(svalue.c_str()); } else if (TC_Port::strcasecmp(skey.c_str(), ":path") == 0) { - context.request.setPath(svalue.c_str()); + context->request.setPath(svalue.c_str()); } else if (TC_Port::strcasecmp(skey.c_str(), ":scheme") == 0) { - context.request.setScheme(svalue.c_str()); + context->request.setScheme(svalue.c_str()); } else if (TC_Port::strcasecmp(skey.c_str(), ":authority") == 0) { - context.request.setDomain(svalue.c_str()); + context->request.setDomain(svalue.c_str()); } - context.request.setHeader(skey, svalue); + context->request.setHeader(skey, svalue); } void TC_Http2Server::onFrameRecvCallback(int32_t streamId) { - TC_Http2Server::Http2Context& context = getContext(streamId); + shared_ptr context = getContext(streamId); -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(streamId); -// if (it != _mReq.end()) -// { -// it->second.bFinish = true; - - if(context.request.getHeaders().find(":method") != context.request.getHeaders().end() || - context.request.getHeaders().find(":path") != context.request.getHeaders().end() || - context.request.getHeaders().find(":scheme") != context.request.getHeaders().end()) + if(context->request.getHeaders().find(":method") != context->request.getHeaders().end() || + context->request.getHeaders().find(":path") != context->request.getHeaders().end() || + context->request.getHeaders().find(":scheme") != context->request.getHeaders().end()) { - context.bFinish = true; _contextFinished.push_back(context); _reqout.insert(_reqout.end(), (char*)&streamId, (char*)&streamId + sizeof(int32_t)); deleteContext(streamId); - } -// } } void TC_Http2Server::onDataChunkRecvCallback(int32_t streamId, const char *data, size_t len) { - TC_Http2Server::Http2Context &context = getContext(streamId); + shared_ptr context = getContext(streamId); - context.request.getContent().append(data, len); -// -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(streamId); -// if (it != _mReq.end()) -// { -// it->second.body.append(data, len); -// } + context->request.getContent().append(data, len); } void TC_Http2Server::onStreamCloseCallback(int32_t streamId) { -// TC_Http2Server::Http2Context & context = getContext(streamId); -// { deleteContext(streamId); -// } - -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(streamId); -// if (it != _mReq.end()) -// { -// if (it->second.bFinish != true) -// { -// _mReq.erase(streamId); -// } -// } } - -TC_Http2Server::TC_Http2Server(): _bNewCon(true) +TC_Http2Server::TC_Http2Server() { nghttp2_session_callbacks *callbacks; @@ -285,21 +253,11 @@ TC_Http2Server::~TC_Http2Server() TC_NetWorkBuffer::PACKET_TYPE TC_Http2Server::parse(TC_NetWorkBuffer&in, vector &out) { -// cout << "parse:" << in.getBufferLength() << endl; - -// if(_bNewCon) -// { -// _bNewCon = false; -// -// } - in.mergeBuffers(); auto buff = in.getBufferPointer(); -// int readlen; - - TC_LockT lock2(_nghttpLock); + TC_LockT lock(_nghttpLock); int readlen = nghttp2_session_mem_recv(_session, (uint8_t *) buff.first, buff.second); @@ -311,8 +269,6 @@ TC_NetWorkBuffer::PACKET_TYPE TC_Http2Server::parse(TC_NetWorkBuffer&in, vector< { in.moveHeader(readlen); -// TC_LockT lock1(reqLock_); - if (_reqout.empty()) { return TC_NetWorkBuffer::PACKET_LESS; @@ -325,16 +281,8 @@ TC_NetWorkBuffer::PACKET_TYPE TC_Http2Server::parse(TC_NetWorkBuffer&in, vector< return TC_NetWorkBuffer::PACKET_FULL; } -//void TC_Http2Server::createReq(int32_t streamId) -//{ -// TC_LockT lock(reqLock_); -// -// _context[streamId] = std::make_shared(); -//} - -TC_Http2Server::Http2Context& TC_Http2Server::getContext(int32_t streamId) +shared_ptr TC_Http2Server::getContext(int32_t streamId) { -// TC_LockT lock(_nghttpLock); auto it = _context.find(streamId); if (it != _context.end()) { @@ -342,62 +290,40 @@ TC_Http2Server::Http2Context& TC_Http2Server::getContext(int32_t streamId) } assert(false); - + return NULL; } void TC_Http2Server::deleteContext(int32_t streamId) { -// TC_LockT lock(_nghttpLock); - _context.erase(streamId); } -void TC_Http2Server::decodeRequest(vector &contexts) +vector> TC_Http2Server::decodeRequest() { + vector> contexts; + TC_LockT lock(_nghttpLock); _contextFinished.swap(contexts); -// return context; + return contexts; } -// -//vector TC_Http2Server::parseReqId(const vector &request) -//{ -// vector vtReqid; -// for (unsigned int i = 0; i < request.size(); i += sizeof(int32_t)) -// { -// int32_t reqId; -// memcpy(&reqId, &request[i], sizeof(int32_t)); -// vtReqid.push_back(reqId); -// } -// -// return vtReqid; -//} -int TC_Http2Server::encodeResponse(const TC_Http2Server::Http2Context &context, vector &out) +int TC_Http2Server::encodeResponse(const shared_ptr &context, vector &out) { -// { -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(reqid); -// if (it == _mReq.end()) -// return -1; -// } - -// deleteContext(context->reqId); - - string sstatus = TC_Common::tostr(context.response.getStatus()); + string sstatus = TC_Common::tostr(context->response.getStatus()); const char* strstatus = ":status"; - nghttp2_nv *hdrs = new nghttp2_nv[context.response.getHeaders().size() + 1]; + nghttp2_nv *hdrs = new nghttp2_nv[context->response.getHeaders().size() + 1]; hdrs[0].flags = NGHTTP2_NV_FLAG_NONE; hdrs[0].name = (uint8_t*)strstatus; hdrs[0].namelen = 7; hdrs[0].value = (uint8_t*)sstatus.c_str(); hdrs[0].valuelen = sstatus.size(); - TC_Http::http_header_type::const_iterator it = context.response.getHeaders().begin(); - for (int n = 1; it != context.response.getHeaders().end(); n++, it++) + TC_Http::http_header_type::const_iterator it = context->response.getHeaders().begin(); + for (int n = 1; it != context->response.getHeaders().end(); n++, it++) { hdrs[n].flags = NGHTTP2_NV_FLAG_NONE; hdrs[n].name = (uint8_t*)it->first.c_str(); @@ -406,11 +332,7 @@ int TC_Http2Server::encodeResponse(const TC_Http2Server::Http2Context &context, hdrs[n].valuelen = it->second.size(); } - const string &body = context.response.getContent(); - - DataPack dataPack(body.c_str(), body.size()); -// dataPack.readPos = 0; -// dataPack.dataBuf = response.body; + DataPack dataPack(context->response.getContent().c_str(), context->response.getContent().size()); nghttp2_data_provider data_prd; data_prd.source.ptr = (void*)&dataPack; @@ -418,7 +340,7 @@ int TC_Http2Server::encodeResponse(const TC_Http2Server::Http2Context &context, { TC_LockT lock(_nghttpLock); - _err = nghttp2_submit_response(_session, context.reqId, hdrs, context.response.getHeaders().size()+1, &data_prd); + _err = nghttp2_submit_response(_session, context->reqId, hdrs, context->response.getHeaders().size()+1, &data_prd); if (_err != 0 ) { delete [] hdrs; @@ -440,267 +362,20 @@ int TC_Http2Server::encodeResponse(const TC_Http2Server::Http2Context &context, delete [] hdrs; return 0; - -// { -// TC_LockT lock(_responseBufLock); -// out.swap(_responseBuf); -// _responseBuf.clear(); -// } -// -// { -// TC_LockT lock(reqLock_); -// _mReq.erase(reqid); -// } } -// -//int TC_Http2Server::doRequest(const vector &request, vector& vtReqid) -//{ -// vtReqid.clear(); -// -// for (unsigned int i = 0; i < request.size(); i += sizeof(int32_t)) -// { -//// RequestPack *ptr; -//// memcpy(&ptr, (char*)&(request[i]), sizeof(TC_Http2Server::RequestPack *)); -// -// int32_t reqId; -// memcpy(&reqId, &request[i], sizeof(int32_t)); -// vtReqid.push_back(reqId); -// } -// -// return 0; -//} -// -//int TC_Http2Server::doResponse(int32_t reqid, const Http2Response &response, vector& out) -//{ -// { -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(reqid); -// if (it == _mReq.end()) -// return -1; -// } -// string sstatus = TC_Common::tostr(response.status); -// -// const char* strstatus = ":status"; -// nghttp2_nv *hdrs = new nghttp2_nv[response.header.size() + 1]; -// hdrs[0].flags = NGHTTP2_NV_FLAG_NONE; -// hdrs[0].name = (uint8_t*)strstatus; -// hdrs[0].namelen = 7; -// hdrs[0].value = (uint8_t*)sstatus.c_str(); -// hdrs[0].valuelen = sstatus.size(); -// TC_Http::http_header_type::const_iterator it = response.header.begin(); -// for (int n = 1; it != response.header.end(); n++, it++) -// { -// hdrs[n].flags = NGHTTP2_NV_FLAG_NONE; -// hdrs[n].name = (uint8_t*)it->first.c_str(); -// hdrs[n].namelen = it->first.size(); -// hdrs[n].value = (uint8_t*)it->second.c_str(); -// hdrs[n].valuelen = it->second.size(); -// } -// -// DataPack dataPack; -// dataPack.readPos = 0; -// dataPack.dataBuf = response.body; -// -// nghttp2_data_provider data_prd; -// data_prd.source.ptr = (void*)&dataPack; -// data_prd.read_callback = server::str_read_callback; -// int ret ; -// { -// TC_LockT lock(_nghttpLock); -// -// ret = nghttp2_submit_response(_session, reqid, hdrs, response.header.size()+1, &data_prd); -// if (ret != 0) { -// cout << "nghttp2_submit_response error" << endl; -// return -1; -// } -// -// while (nghttp2_session_want_write(_session)) { -// ret = nghttp2_session_send(_session); -// if (ret != 0) { -// cout << "nghttp2_session_send error" << endl; -// return -1; -// } -// } -// } -// -// delete [] hdrs; -// -// this->swap(out); -//// { -//// TC_LockT lock(_responseBufLock); -//// out.swap(_responseBuf); -//// _responseBuf.clear(); -//// } -// -// { -// TC_LockT lock(reqLock_); -// _mReq.erase(reqid); -// } -// -// return 0; -//} -// -//int TC_Http2Server::doRequest(const vector &request, TC_Http2Server::RequestFunc requestFunc, vector& response) -//{ -// for (unsigned int i = 0; i < request.size(); i += sizeof(TC_Http2Server::RequestPack *)) -// { -// Http2Response rsp; -// -// RequestPack *ptr; -// memcpy(&ptr, (char*)&(request[i]), sizeof(TC_Http2Server::RequestPack *)); -// -// Req_Type qstatus; -// -// const char* sMethod = ptr->header.find(":method")->second.c_str(); //TC_Common::upper(TC_Common::trim(ptr->header.find(":method")->second)); -// if (TC_Port::strcasecmp(sMethod, "GET") == 0) -// qstatus = REQUEST_GET; -// else if (TC_Port::strcasecmp(sMethod, "POST") == 0) -// qstatus = REQUEST_POST; -// else if (TC_Port::strcasecmp(sMethod, "OPTIONS") == 0) -// qstatus = REQUEST_OPTIONS; -// else if (TC_Port::strcasecmp(sMethod, "HEAD") == 0) -// qstatus = REQUEST_HEAD; -// else if (TC_Port::strcasecmp(sMethod, "PUT") == 0) -// qstatus = REQUEST_PUT; -// else if (TC_Port::strcasecmp(sMethod, "DELETE") == 0) -// qstatus = REQUEST_DELETE; -// else -// { -// continue; -// } -// string sstatus = ptr->header.find(":path")->second; -// -// requestFunc(qstatus, sstatus, ptr->header, ptr->body, rsp); -// -// DataPack dataPack; -// dataPack.readPos = 0; -// dataPack.dataBuf = rsp.body; -// -// sstatus = TC_Common::tostr(rsp.status); -// -// const char* strstatus = ":status"; -// nghttp2_nv *hdrs = new nghttp2_nv[rsp.header.size() + 1]; -// hdrs[0].flags = NGHTTP2_NV_FLAG_NONE; -// hdrs[0].name = (uint8_t*)strstatus; -// hdrs[0].namelen = 7; -// hdrs[0].value = (uint8_t*)sstatus.c_str(); -// hdrs[0].valuelen = sstatus.size(); -// TC_Http::http_header_type::iterator it = rsp.header.begin(); -// for (int n = 1; it != rsp.header.end(); n++, it++) -// { -// hdrs[n].flags = NGHTTP2_NV_FLAG_NONE; -// hdrs[n].name = (uint8_t*)it->first.c_str(); -// hdrs[n].namelen = it->first.size(); -// hdrs[n].value = (uint8_t*)it->second.c_str(); -// hdrs[n].valuelen = it->second.size(); -// } -// -// nghttp2_data_provider data_prd; -// data_prd.source.ptr = (void*)&dataPack; -// data_prd.read_callback = server::str_read_callback; -// -// { -// TC_LockT lock(_nghttpLock); -// -// int ret = nghttp2_submit_response(_session, ptr->streamId, hdrs, rsp.header.size()+1, &data_prd); -// if (ret != 0) -// { -// cout << "nghttp2_submit_response error:" << nghttp2_strerror(ret) << endl; -// } -// ;//TLOGERROR("Fatal error: %s", nghttp2_strerror(ret)); -// -// while (nghttp2_session_want_write(_session)) { -// ret = nghttp2_session_send(_session); -// if (ret != 0) -// { -// cout << "nghttp2_submit_response error:" << nghttp2_strerror(ret) << endl; -// } -// ;//TLOGERROR("Fatal error: %s", nghttp2_strerror(ret)); -// } -// } -// -// vector out; -// swap(out); -// response.insert(response.begin(), out.begin(), out.end()); -//// -//// { -//// TC_LockT lock(_responseBufLock); -//// response.insert(response.begin(), _responseBuf.begin(), _responseBuf.end()); -//// _responseBuf.clear(); -//// } -// -// delete [] hdrs; -// { -// TC_LockT lock(reqLock_); -// _mReq.erase(ptr->streamId); -// } -// -// } -// -// return 0; -//} -// -//int TC_Http2Server::getMethod(int32_t reqid, Req_Type &method) -//{ -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(reqid); -// if (it != _mReq.end()) -// method = it->second.method; -// else -// return -1; -// -// return 0; -//} -// -//int TC_Http2Server::getUri(int32_t reqid, string &uri) -//{ -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(reqid); -// if (it != _mReq.end()) -// uri = it->second.uri; -// else -// return -1; -// -// return 0; -//} -// -//int TC_Http2Server::getHeader(int32_t reqid, TC_Http::http_header_type &header) -//{ -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(reqid); -// if (it != _mReq.end()) -// header = it->second.header; -// else -// return -1; -// -// return 0; -//} -// -//int TC_Http2Server::getBody(int32_t reqid, string &body) -//{ -// TC_LockT lock(reqLock_); -// auto it = _mReq.find(reqid); -// if (it != _mReq.end()) -// body = it->second.body; -// else -// return -1; -// -// return 0; -//} - //////////////////////////////////////////////////////////////////////////////////////// - -void TC_Http2Client::Http2Response::swap(Http2Response& other) -{ - if (this == &other) - return; - - std::swap(streamId, other.streamId); - headers.swap(other.headers); - body.swap(other.body); - std::swap(state, other.state); -} +// +//void TC_Http2Client::Http2Response::swap(Http2Response& other) +//{ +// if (this == &other) +// return; +// +// std::swap(streamId, other.streamId); +// headers.swap(other.headers); +// body.swap(other.body); +// std::swap(state, other.state); +//} /////////////////////////////////////////////////////////////////////////////////////// @@ -722,10 +397,10 @@ static int on_begin_headers_callback(nghttp2_session* session, const nghttp2_fra { if (frame->headers.cat == NGHTTP2_HCAT_RESPONSE) { - TC_Http2Client::Http2Response rsp; - rsp.streamId = frame->hd.stream_id; - rsp.state = TC_Http2Client::ResponseNone; - nghttp2->responses()[rsp.streamId] = rsp; +// TC_HttpResponse rsp; +// rsp.streamId = frame->hd.stream_id; +// rsp.state = TC_Http2Client::ResponseNone; + nghttp2->responses()[frame->hd.stream_id] = std::make_shared(); } } @@ -749,7 +424,7 @@ static int on_header_callback(nghttp2_session* session, const nghttp2_frame* fra std::string n((const char*)name, namelen); std::string v((const char*)value, valuelen); - it->second.headers.insert(std::make_pair(n, v)); + it->second->setHeader(n, v); return 0; } @@ -772,8 +447,9 @@ static int on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* { case NGHTTP2_HEADERS: if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS) - { - it->second.state = TC_Http2Client::ResponseHeadersDone; + { + ; +// it->second.state = TC_Http2Client::ResponseHeadersDone; } return 0; @@ -794,7 +470,7 @@ static int on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, return NGHTTP2_ERR_CALLBACK_FAILURE; } - it->second.body.insert(it->second.body.end(), (const char* )data, (const char* )data + len); + it->second->appendContent((const char* )data, len); return 0; } @@ -808,10 +484,10 @@ static int on_stream_close_callback(nghttp2_session* session, int32_t stream_id, return NGHTTP2_ERR_CALLBACK_FAILURE; } - it->second.state = TC_Http2Client::ResponseBodyDone; +// it->second.state = TC_Http2Client::ResponseBodyDone; - nghttp2->doneResponses()[stream_id].swap(it->second); - nghttp2->responses().erase(it); + nghttp2->doneResponses()[stream_id] = it->second; + nghttp2->responses().erase(it); return 0; } @@ -836,7 +512,6 @@ TC_Http2Client::TC_Http2Client() TC_Http2Client::~TC_Http2Client() { -// nghttp2_session_del(_session); } // void TC_Http2Client::onNegotiateDone(bool succ)