diff --git a/examples/HttpDemo/HttpServer/Http2Imp.cpp b/examples/HttpDemo/HttpServer/Http2Imp.cpp index ef4551a..892beb3 100644 --- a/examples/HttpDemo/HttpServer/Http2Imp.cpp +++ b/examples/HttpDemo/HttpServer/Http2Imp.cpp @@ -15,14 +15,13 @@ */ #include "Http2Imp.h" -#include "util/tc_http2session.h" #include "servant/Application.h" using namespace std; TC_SpinLock Http2Imp::_mutex; -unordered_map Http2Imp::_http2Sessions; +unordered_map Http2Imp::_http2; ////////////////////////////////////////////////////// void Http2Imp::initialize() @@ -51,13 +50,13 @@ int Http2Imp::doRequest(TarsCurrentPtr current, vector &buffer) { vector vtReqid; - TC_Http2Session::doRequest(current->getRequestBuffer(), vtReqid); + TC_Http2Server::doRequest(current->getRequestBuffer(), vtReqid); cout << "doRequest:" << TC_Common::tostr(vtReqid.begin(), vtReqid.end(), ", ") << endl; - TC_Http2Session* session = getHttp2Session(current->getUId()); + TC_Http2Server* session = getHttp2(current->getUId()); - TC_Http2Session::Http2Response rsp; + TC_Http2Server::Http2Response rsp; rsp.status = 200; rsp.about = "OK"; rsp.body = "response helloworld"; @@ -73,7 +72,7 @@ int Http2Imp::doRequest(TarsCurrentPtr current, vector &buffer) int Http2Imp::doClose(TarsCurrentPtr current) { - delHttp2Session(current->getUId()); + delHttp2(current->getUId()); return 0; } \ No newline at end of file diff --git a/examples/HttpDemo/HttpServer/Http2Imp.h b/examples/HttpDemo/HttpServer/Http2Imp.h index 6c69d6c..982f6fc 100644 --- a/examples/HttpDemo/HttpServer/Http2Imp.h +++ b/examples/HttpDemo/HttpServer/Http2Imp.h @@ -19,7 +19,7 @@ #include "servant/Application.h" #include "util/tc_spin_lock.h" -#include "util/tc_http2session.h" +#include "util/tc_http2.h" /** * @@ -53,37 +53,35 @@ public: */ int doClose(TarsCurrentPtr current); - static TC_Http2Session *getHttp2Session(uint32_t uid) + static TC_Http2Server *getHttp2(uint32_t uid) { TC_LockT lock(_mutex); - auto it = _http2Sessions.find(uid); + auto it = _http2.find(uid); - if(it != _http2Sessions.end()) + if(it != _http2.end()) { return it->second; } return NULL; } - static void addHttp2Session(uint32_t uid, TC_Http2Session* ptr) + static void addHttp2(uint32_t uid, TC_Http2Server* ptr) { TC_LockT lock(_mutex); - _http2Sessions[uid] = ptr; + _http2[uid] = ptr; } - static void delHttp2Session(uint32_t uid) + static void delHttp2(uint32_t uid) { TC_LockT lock(_mutex); - auto it = _http2Sessions.find(uid); + auto it = _http2.find(uid); - if(it != _http2Sessions.end()) + if(it != _http2.end()) { - delete it->second; - - _http2Sessions.erase(it); + _http2.erase(it); } } @@ -91,7 +89,7 @@ protected: static TC_SpinLock _mutex; - static unordered_map _http2Sessions; + static unordered_map _http2; }; ///////////////////////////////////////////////////// #endif diff --git a/examples/HttpDemo/HttpServer/HttpServer.cpp b/examples/HttpDemo/HttpServer/HttpServer.cpp index d6279a2..8dd0ee2 100644 --- a/examples/HttpDemo/HttpServer/HttpServer.cpp +++ b/examples/HttpDemo/HttpServer/HttpServer.cpp @@ -17,7 +17,7 @@ #include "HttpServer.h" #include "HttpImp.h" #include "Http2Imp.h" -#include "util/tc_http2session.h" +#include "util/tc_http2.h" using namespace std; @@ -25,19 +25,17 @@ HttpServer g_app; TC_NetWorkBuffer::PACKET_TYPE parseHttp2(TC_NetWorkBuffer&in, vector &out) { - TC_Http2Session *session = (TC_Http2Session*)(in.getContextData()); + TC_Http2Server*session = (TC_Http2Server*)(in.getContextData()); if(session == NULL) { - session = new TC_Http2Session(); - in.setContextData(session); + session = new TC_Http2Server(); + in.setContextData(session, [=]{delete session;}); TC_EpollServer::Connection *connection = (TC_EpollServer::Connection *)in.getConnection(); - Http2Imp::addHttp2Session(connection->getId(), session); + Http2Imp::addHttp2(connection->getId(), session); } - cout << "parseHttp2:" << in.getBufferLength() << ", " << session << endl; - return session->parse(in, out); } diff --git a/servant/libservant/AdapterProxy.cpp b/servant/libservant/AdapterProxy.cpp index 39c517d..6e2a013 100755 --- a/servant/libservant/AdapterProxy.cpp +++ b/servant/libservant/AdapterProxy.cpp @@ -24,7 +24,7 @@ #include "tup/tup.h" #include "servant/StatF.h" #include "servant/StatReport.h" -#include "util/tc_nghttp2.h" +#include "util/tc_http2.h" // #include "util/tc_http2clientmgr.h" #ifdef _USE_OPENTRACKING #include "servant/text_map_carrier.h" diff --git a/servant/libservant/AppProtocol.cpp b/servant/libservant/AppProtocol.cpp index 9b135f8..4e7139c 100644 --- a/servant/libservant/AppProtocol.cpp +++ b/servant/libservant/AppProtocol.cpp @@ -24,7 +24,7 @@ #include #if TARS_HTTP2 -#include "util/tc_nghttp2.h" +#include "util/tc_http2.h" // #include "util/tc_http2clientmgr.h" #endif @@ -163,80 +163,21 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http1Response(TC_NetWorkBuffer &in, return TC_NetWorkBuffer::PACKET_LESS; } -// vector encodeHttp2(RequestPacket& request, TC_NgHttp2* session) -// { -// std::vector nva; - -// const std::string method(":method"); -// nghttp2_nv nv1 = MAKE_STRING_NV(method, request.sFuncName); -// if (!request.sFuncName.empty()) -// nva.push_back(nv1); - -// const std::string path(":path"); -// nghttp2_nv nv2 = MAKE_STRING_NV(path, request.sServantName); -// if (!request.sServantName.empty()) -// nva.push_back(nv2); - -// for (std::map::const_iterator -// it(request.context.begin()); -// it != request.context.end(); -// ++ it) -// { -// nghttp2_nv nv = MAKE_STRING_NV(it->first, it->second); -// nva.push_back(nv); -// } - -// nghttp2_data_provider* pData = NULL; -// nghttp2_data_provider data; -// if (!request.sBuffer.empty()) -// { -// pData = &data; -// data.source.ptr = (void*)&request.sBuffer; -// data.read_callback = reqbody_read_callback; -// } - -// int32_t sid = nghttp2_submit_request(session->session(), -// NULL, -// &nva[0], -// nva.size(), -// pData, -// NULL); -// if (sid < 0) -// { -// TLOGERROR("encodeHttp2::Fatal error: nghttp2_submit_request return: " << sid << endl); -// return vector(); -// } - -// request.iRequestId = sid; -// nghttp2_session_send(session->session()); - -// // 交给tars发送 -// // std::string out; -// // out.swap(session->sendBuffer()); -// // return out; - -// vector out; - -// out.assign(session->sendBuffer().begin(), session->sendBuffer().end()); - -// return out; -// } - // ENCODE function, called by network thread vector ProxyProtocol::http2Request(RequestPacket& request, Transceiver *trans) { // TC_NgHttp2* session = Http2ClientSessionManager::getInstance()->getSession(request.iRequestId); - TC_NgHttp2* session = trans->getHttp2Session(); + TC_Http2Client* session = trans->getHttp2Client(); assert(session != NULL); - if (session->getState() == TC_NgHttp2::None) - { - session->Init(); - session->settings(); - } + // if (session->getState() == TC_NgHttp2::None) + // { + // session->Init(); + // session->settings(); + // } - assert (session->getState() == TC_NgHttp2::Http2); + // assert (session->getState() == TC_NgHttp2::Http2); // return encodeHttp2(request, session); std::vector nva; @@ -282,25 +223,25 @@ vector ProxyProtocol::http2Request(RequestPacket& request, Transceiver *tr nghttp2_session_send(session->session()); // 交给tars发送 - // std::string out; - // out.swap(session->sendBuffer()); - // return out; - vector out; - - out.assign(session->sendBuffer().begin(), session->sendBuffer().end()); - session->sendBuffer().clear(); - - cout << "iRequestId:" << request.iRequestId << ", size:" << out.size() << endl; - + out.swap(session->sendBuffer()); return out; + + // vector out; + + // out.assign(session->sendBuffer().begin(), session->sendBuffer().end()); + // session->sendBuffer().clear(); + + // cout << "iRequestId:" << request.iRequestId << ", size:" << out.size() << endl; + + // return out; } // TC_NetWorkBuffer::PACKET_TYPE http2Response(TC_NetWorkBuffer &in, list& done, void* userptr) TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in, ResponsePacket& rsp) { cout << "http2Response1:" << in.getBufferLength() << endl; - TC_NgHttp2* session = ((Transceiver*)(in.getConnection()))->getHttp2Session(); + TC_Http2Client* session = ((Transceiver*)(in.getConnection()))->getHttp2Client(); // assert (session->getState() == TC_NgHttp2::Http2); @@ -339,19 +280,6 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http2Response(TC_NetWorkBuffer &in, cout << "http2Response2 size:" << session->doneResponses().size() << ", iRequestId:" << rsp.iRequestId << endl; - // std::map::const_iterator it(session->_doneResponses.begin()); - // for (; it != session->_doneResponses.end(); ++ it) - // { - // ResponsePacket rsp; - - // rsp.iRequestId = it->second.streamId; - // rsp.status = it->second.headers; - // rsp.sBuffer.assign(it->second.body.begin(), it->second.body.end()); - - // done.push_back(rsp); - // } - - // session->_doneResponses.clear(); return TC_NetWorkBuffer::PACKET_FULL; } diff --git a/servant/libservant/Transceiver.cpp b/servant/libservant/Transceiver.cpp index d6f001c..6c496f3 100755 --- a/servant/libservant/Transceiver.cpp +++ b/servant/libservant/Transceiver.cpp @@ -27,8 +27,7 @@ #endif #if TARS_HTTP2 -#include "util/tc_nghttp2.h" -// #include "util/tc_http2clientmgr.h" +#include "util/tc_http2.h" #endif namespace tars { @@ -277,11 +276,10 @@ void Transceiver::close() #endif #if TARS_HTTP2 - // Http2ClientSessionManager::getInstance()->delSession(_adapterProxy->getId()); - if(_http2Session) + if(_http2Client) { - nghttp2_session_del(_http2Session->session()); - _http2Session = NULL; + delete _http2Client; + _http2Client = NULL; } #endif @@ -307,20 +305,16 @@ void Transceiver::close() } #if TARS_HTTP2 -TC_NgHttp2* Transceiver::getHttp2Session() +TC_Http2Client* Transceiver::getHttp2Client() { - if(_http2Session == NULL) + if(_http2Client == NULL) { - _http2Session = new TC_NgHttp2(false); - - // if (_http2Session->getState() == TC_NgHttp2::None) - // { - // _http2Session->Init(); - // _http2Session->settings(); - // } + _http2Client = new TC_Http2Client(); + // _http2Client->Init(); + _http2Client->settings(); } - return _http2Session; + return _http2Client; } #endif diff --git a/servant/servant/Transceiver.h b/servant/servant/Transceiver.h index cfbcaa8..93b06ae 100755 --- a/servant/servant/Transceiver.h +++ b/servant/servant/Transceiver.h @@ -34,7 +34,7 @@ namespace tars #endif #if TARS_HTTP2 - class TC_NgHttp2; + class TC_Http2Client; #endif class AdapterProxy; @@ -227,7 +227,7 @@ public: bool sendAuthData(const BasicAuthInfo& ); #if TARS_HTTP2 - TC_NgHttp2* getHttp2Session(); + TC_Http2Client* getHttp2Client(); #endif protected: /** @@ -281,7 +281,7 @@ protected: #endif #if TARS_HTTP2 - TC_NgHttp2* _http2Session = NULL; + TC_Http2Client* _http2Client = NULL; #endif /* * 发送buffer diff --git a/util/include/util/tc_http2clientmgr.h b/util/include/util/tc_http2clientmgr.h deleted file mode 100644 index 5ac908d..0000000 --- a/util/include/util/tc_http2clientmgr.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -#ifndef __TC_HTTP2CLIENTMANAGER_H -#define __TC_HTTP2CLIENTMANAGER_H - -#if TARS_HTTP2 - -#include - -#include "util/tc_singleton.h" - -namespace tars -{ - -///////////////////////////////////////////////// -/** - *@file tc_http2clientmgr.h - *@brief http2客户端session集合 - */ -///////////////////////////////////////////////// - -class TC_NgHttp2; - -class Http2ClientSessionManager : public TC_Singleton -{ -public: - Http2ClientSessionManager(); - ~Http2ClientSessionManager(); - - TC_NgHttp2* getSession(int id, bool isServer = false); - - bool delSession(int id); - -private: - typedef std::map SESSION_MAP; - SESSION_MAP _sessions; -}; - -} // end namespace tars - -#endif // end #if TARS_SSL - -#endif - diff --git a/util/include/util/tc_http2session.h b/util/include/util/tc_http2session.h deleted file mode 100644 index fb7a938..0000000 --- a/util/include/util/tc_http2session.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef __TC_HTTP2_H__ -#define __TC_HTTP2_H__ - -#if TARS_HTTP2 - -#include "util/tc_thread.h" -#include "util/tc_autoptr.h" -#include "util/tc_http.h" -#include "util/tc_network_buffer.h" -#include "util/tc_spin_lock.h" -#include "nghttp2/nghttp2.h" - -namespace tars -{ - -typedef enum -{ - REQUEST_GET, - REQUEST_POST, - REQUEST_OPTIONS, - REQUEST_HEAD, - REQUEST_PUT, - REQUEST_DELETE -}Req_Type; - -typedef int (*ResponseFunc)(const Req_Type reqtype, - const string &requri, - const TC_Http::http_header_type &reqHeader, - const string &reqBody, - int &resopnseStatus, - string &resopnseAbout, - TC_Http::http_header_type &responseHeader, - string &responseBody); - - -class TC_Http2Session: public TC_HandleBase -{ -public: - - TC_Http2Session(); - - ~TC_Http2Session(); - - struct Http2Response - { - int status; - string about; - TC_Http::http_header_type header; - string body; - }; - - /** - * get all http2 request id - * @param in - * @param out - * @return - */ - static int doRequest(const vector &request, vector& vtReqid); - - /** - * http2 - * @param in - * @param out - * @return - */ - TC_NetWorkBuffer::PACKET_TYPE parse(TC_NetWorkBuffer&in, vector &out); - - int doResponse(int32_t reqid, const Http2Response &response, vector& out); - - int doRequest(const vector &request, vector& response); - - void setResponseFunc(ResponseFunc func) { responseFunc_ = func; } - - int getMethod(int32_t reqid, Req_Type &method); - - int getUri(int32_t reqid, string &uri); - - int getHeader(int32_t reqid, TC_Http::http_header_type &header); - - int getBody(int32_t reqid, string &body); - - struct RequestPack - { - RequestPack():streamId(0), bFinish(false){} - - Req_Type method; - string uri; - TC_Http::http_header_type header; - string body; - int32_t streamId; - bool bFinish; - }; - - struct DataPack - { - DataPack(){} - - DataPack(string &data, int pos):dataBuf(data), readPos(pos){} - - string dataBuf; - unsigned int readPos; - }; - - - TC_SpinLock responseBufLock_; - string responseBuf_; - - TC_SpinLock reqLock_; - map mReq_; - - vector reqout_; - -protected: - - -private: - - int (*responseFunc_)(const Req_Type reqtype, - const string &requri, - const TC_Http::http_header_type &reqHeader, - const string &reqBody, - int &resopnseStatus, - string &resopnseAbout, - TC_Http::http_header_type &responseHeader, - string &responseBody); - - nghttp2_session *session_; - - bool bNewCon_; - - TC_SpinLock nghttpLock; - - // bool bOldVersion_; - // bool bUpgrade_; -}; - -typedef TC_AutoPtr TC_Http2SessionPtr; - -} - -#endif - -#endif diff --git a/util/include/util/tc_nghttp2.h b/util/include/util/tc_nghttp2.h deleted file mode 100644 index 055fc37..0000000 --- a/util/include/util/tc_nghttp2.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -#ifndef __TC_NGHTTP2_H -#define __TC_NGHTTP2_H - -#if TARS_HTTP2 - -#include -#include -#include -#include "nghttp2/nghttp2.h" - -namespace tars -{ - -// struct RequestPacket; -// struct ResponsePacket; - -enum ResponseState -{ - ResponseNone, - ResponseHeadersDone, - ResponseBodyDone, -}; - -struct Http2Response -{ - int streamId; - std::map headers; - std::string body; - ResponseState state; - - void swap(Http2Response& other); -}; - -///////////////////////////////////////////////// -/** - *@file tc_nghttp2.h - *@brief NGHTTP2封装 - * - */ -///////////////////////////////////////////////// - -/** - *@brief 注册给taf client网络线程使用的打包函数 - */ -// void http2Request(const RequestPacket& , std::string& ); - -/** - *@brief NGHTTP2封装 - */ -class TC_NgHttp2 -{ - // friend const vector & http2Request(const RequestPacket&); - // friend size_t http2Response(const char* , size_t , std::list& , void*); -public: - /** - *@brief 注册给ng session的send回调 - */ - static ssize_t onSend(nghttp2_session *session, const unsigned char* data, size_t length, int flags, void *user_data); - /** - *@brief 注册给ng session的收到新流回调 - */ - static int onBeginHeaders(nghttp2_session *session, const nghttp2_frame *frame, void *user_data); - /** - *@brief 注册给ng session的收到header kv - */ - static int onHeader(nghttp2_session *session, const nghttp2_frame *frame, - const uint8_t *name, size_t namelen, - const uint8_t *value, size_t valuelen, - uint8_t flags, void *user_data); - /** - *@brief 注册给ng session的收到完整frame - */ - static int onFrameRecv(nghttp2_session *session, const nghttp2_frame *frame, void *user_data) ; - /** - *@brief 注册给ng session的收到data frame - */ - static int onDataChunkRecv(nghttp2_session *session, uint8_t flags, - int32_t stream_id, const uint8_t *data, - size_t len, void *user_data); - - /** - *@brief 注册给ng session的收到完整stream - */ - static int onStreamClose(nghttp2_session *session, int32_t stream_id, - uint32_t error_code, void *user_data); -public: - enum State - { - None, - Negotiating, - Http2, // use HTTP-2 - Http1, // please use HTTP-1 - }; - - /** - * @brief 构造函数. - */ - explicit - TC_NgHttp2(bool isServer = false); - - /** - * @brief 析构函数. - */ - ~TC_NgHttp2(); - - /** - * @brief 当前状态 - */ - int getState() const; - -private: - /** - * @brief 禁止复制 - */ - TC_NgHttp2(const TC_NgHttp2& ); - void operator=(const TC_NgHttp2& ); - -public: - /** - * @brief 初始化 - */ - void Init(); - /** - * @brief 协商结果 - */ - void onNegotiateDone(bool succ); - /** - * @brief HTTP2握手+setting - */ - int settings(unsigned int maxCurrentStreams = 1); - /** - * @brief 当前缓冲区 - */ - std::string& sendBuffer(); - - /** - * @brief session - */ - nghttp2_session* session() const; - - /** - * @brief 响应包 - */ - std::map &doneResponses() { return _doneResponses; } -private: - /** - * session - */ - nghttp2_session* _session; - - /** - * 状态 - */ - State _state; - - /** - * 是否服务端 - */ - bool _isServer; - /** - * 发送缓存区,由send callback填充 - */ - std::string _sendBuf; - - /** - * 收到的响应 - */ - std::map _responses; - /** - * 收到的完整响应 - */ - std::map _doneResponses; - - /** - *协商升级使用 - */ - std::string _settings; -}; - -} // end namespace tars - -#endif // end #if TARS_HTTP2 - -#endif - diff --git a/util/src/tc_http2clientmgr.cpp b/util/src/tc_http2clientmgr.cpp deleted file mode 100644 index cbbade0..0000000 --- a/util/src/tc_http2clientmgr.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -#if TARS_HTTP2 - -#include -#include - -#include "util/tc_nghttp2.h" -#include "util/tc_http2clientmgr.h" - -namespace tars -{ - -Http2ClientSessionManager::Http2ClientSessionManager() -{ -} - -Http2ClientSessionManager::~Http2ClientSessionManager() -{ -} - -TC_NgHttp2* Http2ClientSessionManager::getSession(int id, bool isServer) -{ - SESSION_MAP::iterator it(_sessions.find(id)); - if (it == _sessions.end()) - { - TC_NgHttp2* http2 = new TC_NgHttp2(isServer); - it = _sessions.insert(std::make_pair(id, http2)).first; - } - - return it->second; -} - -bool Http2ClientSessionManager::delSession(int id) -{ - SESSION_MAP::iterator it(_sessions.find(id)); - if (it == _sessions.end()) - return false; - - nghttp2_session_del(it->second->session()); - _sessions.erase(it); - return true; -} - -} // end namespace tars - -#endif // end #if TARS_SSL - diff --git a/util/src/tc_http2session.cpp b/util/src/tc_http2session.cpp deleted file mode 100644 index a87cc83..0000000 --- a/util/src/tc_http2session.cpp +++ /dev/null @@ -1,496 +0,0 @@ -#if TARS_HTTP2 - -#include "util/tc_http.h" -#include "util/tc_http2session.h" -#include "util/tc_epoll_server.h" - -namespace tars -{ - -#define MAKE_NV(NAME, VALUE) \ -{ \ -(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \ - NGHTTP2_NV_FLAG_NONE \ -} - -#define ARRLEN(x) (sizeof(x) / sizeof(x[0])) - -#define MIN(x, y) ((x < y)?x:y) - -static ssize_t str_read_callback(nghttp2_session *session, int32_t stream_id, - uint8_t *buf, size_t length, - uint32_t *data_flags, - nghttp2_data_source *source, - void *user_data) -{ - TC_Http2Session::DataPack *dataPack = (TC_Http2Session::DataPack*)(source->ptr); - size_t size = MIN(dataPack->dataBuf.size() - dataPack->readPos, length); - - memcpy(buf, dataPack->dataBuf.c_str() + dataPack->readPos, size); - - dataPack->readPos += size; - - if(dataPack->readPos == dataPack->dataBuf.size()) - { - //TLOGDEBUG("[str_read_callback] finish:" << size << endl); - *data_flags |= NGHTTP2_DATA_FLAG_EOF; - } - - //TLOGDEBUG("[str_read_callback] size:" << size << " length:" << length<< endl); - - return size; -} - -static ssize_t send_callback(nghttp2_session *session, const uint8_t *data, - size_t length, int flags, void *user_data) -{ - TC_Http2Session *ptr = (TC_Http2Session*)user_data; - { - TC_LockT lock(ptr->responseBufLock_); - ptr->responseBuf_.append((char*)data, length); - } - //TLOGDEBUG("[send_callback] length:" << length << endl); - return (ssize_t)length; -} - -static int on_header_callback(nghttp2_session *session, - const nghttp2_frame *frame, const uint8_t *name, - size_t namelen, const uint8_t *value, - size_t valuelen, uint8_t flags, void *user_data) -{ - cout << "[on_header_callback] streamid:" << frame->hd.stream_id << " name:" << name << " value:" << value << " flags:" << flags << endl; - - TC_Http2Session *ptr = (TC_Http2Session*)user_data; - { - TC_LockTlock(ptr->reqLock_); - map::iterator it = ptr->mReq_.find(frame->hd.stream_id); - if (it != ptr->mReq_.end()) - { - string skey((char*)name, namelen); - string svalue((char*)value, valuelen); - it->second.header.insert(std::pair(skey, svalue)); - - skey = TC_Common::lower(TC_Common::trim(skey)); - if (skey == ":method") - { - string sMethod = TC_Common::upper(TC_Common::trim(svalue)); - if (sMethod == "GET") - it->second.method = REQUEST_GET; - else if (sMethod == "POST") - it->second.method = REQUEST_POST; - else if (sMethod == "OPTIONS") - it->second.method = REQUEST_OPTIONS; - else if (sMethod == "HEAD") - it->second.method = REQUEST_HEAD; - else if (sMethod == "PUT") - it->second.method = REQUEST_PUT; - else if (sMethod == "DELETE") - it->second.method = REQUEST_DELETE; - } - else if (skey == ":path") - { - it->second.uri = svalue; - } - } - } - return 0; -} - -static int on_begin_headers_callback(nghttp2_session *session, - const nghttp2_frame *frame, - void *user_data) -{ - cout << "[on_begin_headers_callback] streamid:" << frame->hd.stream_id << endl; - TC_Http2Session *ptr = (TC_Http2Session*)user_data; - - if (frame->hd.type != NGHTTP2_HEADERS || frame->headers.cat != NGHTTP2_HCAT_REQUEST) { - return 0; - } - - { - TC_LockT lock(ptr->reqLock_); - ptr->mReq_[frame->hd.stream_id].streamId = frame->hd.stream_id; - } - - return 0; -} - -static int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, void *user_data) -{ - //TLOGDEBUG("[on_frame_recv_callback] id:" << frame->hd.stream_id << " type:" << int(frame->hd.type) << endl); - cout << "[on_frame_recv_callback] id:" << frame->hd.stream_id << " type:" << int(frame->hd.type) << endl; - - TC_Http2Session *ptr = (TC_Http2Session*)user_data; - - switch (frame->hd.type) - { - case NGHTTP2_DATA: - case NGHTTP2_HEADERS: - /* Check that the client request has finished */ - if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) - { - cout << "[on_frame_recv_callback] NGHTTP2_FLAG_END_STREAM" << endl; - - { - TC_LockT lock(ptr->reqLock_); - map::iterator it = ptr->mReq_.find(frame->hd.stream_id); - if (it != ptr->mReq_.end()) - { - it->second.bFinish = true; - - if(it->second.header.find(":method") != it->second.header.end() || - it->second.header.find(":path") != it->second.header.end() || - it->second.header.find(":scheme") != it->second.header.end()) - { - cout << "insert reqout_" << endl; - char *tmpptr = (char*)&(it->second); - ptr->reqout_.insert(ptr->reqout_.end(), (char*)&tmpptr, (char*)&tmpptr + sizeof(TC_Http2Session::RequestPack *)); - } - } - } - return 0; - } - break; - default: - break; - } - return 0; -} - -static int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags, - int32_t stream_id, const uint8_t *data, - size_t len, void *user_data) -{ - cout << "[on_data_chunk_recv_callback] stream_id:" << stream_id << endl; - - TC_Http2Session *ptr = (TC_Http2Session*)user_data; - { - TC_LockT lock(ptr->reqLock_); - map::iterator it = ptr->mReq_.find(stream_id); - if (it != ptr->mReq_.end()) - { - it->second.body.append((char*)data, len); - } - } - return 0; -} - -static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, uint32_t error_code, void *user_data) -{ - cout << "[on_stream_close_callback] streamid:" << stream_id << endl; - - TC_Http2Session *ptr = (TC_Http2Session*)user_data; - - { - TC_LockT lock(ptr->reqLock_); - map::iterator it = ptr->mReq_.find(stream_id); - if (it != ptr->mReq_.end()) - { - if (it->second.bFinish != true) - { - ptr->mReq_.erase(stream_id); - } - } - } - return 0; -} - -TC_Http2Session::TC_Http2Session():session_(NULL), bNewCon_(true) -{ - nghttp2_session_callbacks *callbacks; - - nghttp2_session_callbacks_new(&callbacks); - - nghttp2_session_callbacks_set_send_callback(callbacks, send_callback); - - nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks, on_frame_recv_callback); - - nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks, on_data_chunk_recv_callback); - - nghttp2_session_callbacks_set_on_stream_close_callback(callbacks, on_stream_close_callback); - - nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header_callback); - - nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks, on_begin_headers_callback); - - nghttp2_session_server_new(&session_, callbacks, ((void*)this)); - - *(int32_t*)((char*)session_ + 2380) = 100000000; - - //TLOGDEBUG("window size:" << nghttp2_session_get_remote_window_size(session_) << endl); - - nghttp2_session_callbacks_del(callbacks); -} - -TC_Http2Session::~TC_Http2Session() -{ - nghttp2_session_del(session_); -} - -TC_NetWorkBuffer::PACKET_TYPE TC_Http2Session::parse(TC_NetWorkBuffer&in, vector &out) -{ - if(bNewCon_) - { - bNewCon_ = false; - - nghttp2_settings_entry iv[2] = {{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100}, - {NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, 100*1024*1024}}; - nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, iv, ARRLEN(iv)); - } - - vector buff = in.getBuffers(); - - int readlen = nghttp2_session_mem_recv(session_, (uint8_t *)buff.data(), buff.size()); - - cout << "parse:" << readlen << ", reqout_ size: " << reqout_.size() << endl; - - if(readlen < 0) - { - return TC_NetWorkBuffer::PACKET_ERR; - } - else - { - in.moveHeader(readlen); - - if (reqout_.empty()) - { - return TC_NetWorkBuffer::PACKET_LESS; - } - - out.insert(out.end(), reqout_.begin(), reqout_.end()); - reqout_.clear(); - } - - return TC_NetWorkBuffer::PACKET_FULL; -} - -int TC_Http2Session::doRequest(const vector &request, vector& vtReqid) -{ - vtReqid.clear(); - - string responseAbout; - TC_Http::http_header_type responseHeader; - string sstatus; - for (unsigned int i = 0; i < request.size(); i += sizeof(TC_Http2Session::RequestPack *)) - { - RequestPack *ptr; - memcpy(&ptr, (char*)&(request[i]), sizeof(TC_Http2Session::RequestPack *)); - - vtReqid.push_back(ptr->streamId); - } - - return 0; -} - -int TC_Http2Session::doResponse(int32_t reqid, const Http2Response &response, vector& out) -{ - { - TC_LockT lock(reqLock_); - map::iterator 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 = 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) - return -1; - - while (nghttp2_session_want_write(session_)) { - ret = nghttp2_session_send(session_); - if (ret != 0) - return -1; - } - } - - delete [] hdrs; - - { - TC_LockT lock(responseBufLock_); - out.clear(); - out.insert(out.end(), responseBuf_.begin(), responseBuf_.end()); - - responseBuf_.clear(); - } - - { - TC_LockT lock(reqLock_); - mReq_.erase(reqid); - } - - return 0; -} - -int TC_Http2Session::doRequest(const vector &request, vector& response) -{ - int responseStatus = 0; - string responseAbout; - TC_Http::http_header_type responseHeader; - string sstatus; - for (unsigned int i = 0; i < request.size(); i += sizeof(TC_Http2Session::RequestPack *)) - { - RequestPack *ptr; - memcpy(&ptr, (char*)&(request[i]), sizeof(TC_Http2Session::RequestPack *)); - - string sMethod = TC_Common::upper(TC_Common::trim(ptr->header.find(":method")->second)); - if (sMethod == "GET") - responseStatus = REQUEST_GET; - else if (sMethod == "POST") - responseStatus = REQUEST_POST; - else if (sMethod == "OPTIONS") - responseStatus = REQUEST_OPTIONS; - else if (sMethod == "HEAD") - responseStatus = REQUEST_HEAD; - else if (sMethod == "PUT") - responseStatus = REQUEST_PUT; - else if (sMethod == "DELETE") - responseStatus = REQUEST_DELETE; - else - { - continue; - } - sstatus = ptr->header.find(":path")->second; - responseAbout.clear(); - responseHeader.clear(); - DataPack dataPack; - dataPack.readPos = 0; - responseFunc_((Req_Type)responseStatus, - sstatus, - ptr->header, - ptr->body, - responseStatus, - responseAbout, - responseHeader, - dataPack.dataBuf); - - sstatus = TC_Common::tostr(responseStatus); - - const char* strstatus = ":status"; - nghttp2_nv *hdrs = new nghttp2_nv[responseHeader.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 = responseHeader.begin(); - for (int n = 1; it != responseHeader.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 = str_read_callback; - int ret ; - { - TC_LockT lock(nghttpLock); - - ret = nghttp2_submit_response(session_, ptr->streamId, hdrs, responseHeader.size()+1, &data_prd); - if (ret != 0) - ;//TLOGERROR("Fatal error: %s", nghttp2_strerror(ret)); - - while (nghttp2_session_want_write(session_)) { - ret = nghttp2_session_send(session_); - if (ret != 0) - ;//TLOGERROR("Fatal error: %s", nghttp2_strerror(ret)); - } - response.clear(); - response.insert(response.end(), responseBuf_.begin(), responseBuf_.end()); - - responseBuf_.clear(); - } - - delete [] hdrs; - { - TC_LockT lock(reqLock_); - mReq_.erase(ptr->streamId); - } - - } - - return 0; -} - -int TC_Http2Session::getMethod(int32_t reqid, Req_Type &method) -{ - TC_LockT lock(reqLock_); - map::iterator it = mReq_.find(reqid); - if (it != mReq_.end()) - method = it->second.method; - else - return -1; - - return 0; -} - -int TC_Http2Session::getUri(int32_t reqid, string &uri) -{ - TC_LockT lock(reqLock_); - map::iterator it = mReq_.find(reqid); - if (it != mReq_.end()) - uri = it->second.uri; - else - return -1; - - return 0; -} - -int TC_Http2Session::getHeader(int32_t reqid, TC_Http::http_header_type &header) -{ - TC_LockT lock(reqLock_); - map::iterator it = mReq_.find(reqid); - if (it != mReq_.end()) - header = it->second.header; - else - return -1; - - return 0; -} - -int TC_Http2Session::getBody(int32_t reqid, string &body) -{ - TC_LockT lock(reqLock_); - map::iterator it = mReq_.find(reqid); - if (it != mReq_.end()) - body = it->second.body; - else - return -1; - - return 0; -} -} - -#endif - diff --git a/util/src/tc_nghttp2.cpp b/util/src/tc_nghttp2.cpp deleted file mode 100644 index de51903..0000000 --- a/util/src/tc_nghttp2.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/** - * Tencent is pleased to support the open source community by making Tars available. - * - * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -#if TARS_HTTP2 - -#include -#include -#include -#include "nghttp2/nghttp2.h" - -#include "util/tc_nghttp2.h" -// #include "util/tc_http2clientmgr.h" -#include "util/tc_base64.h" - - -namespace tars -{ - -void 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); -} - -ssize_t TC_NgHttp2::onSend(nghttp2_session* session, - const uint8_t* data, - size_t length, - int flags, - void* user_data) -{ - TC_NgHttp2* nghttp2 = (TC_NgHttp2* )user_data; - nghttp2->_sendBuf.append((const char*)data, length); - return length; -} - -int TC_NgHttp2::onBeginHeaders(nghttp2_session* session, - const nghttp2_frame* frame, - void* user_data) -{ - TC_NgHttp2* nghttp2 = (TC_NgHttp2* )user_data; - - if (frame->hd.type == NGHTTP2_HEADERS) - { - if (frame->headers.cat == NGHTTP2_HCAT_RESPONSE) - { - Http2Response rsp; - rsp.streamId = frame->hd.stream_id; - rsp.state = ResponseNone; - nghttp2->_responses[rsp.streamId] = rsp; - } - } - - return 0; -} - -int TC_NgHttp2::onHeader(nghttp2_session* session, const nghttp2_frame* frame, - const uint8_t* name, size_t namelen, - const uint8_t* value, size_t valuelen, - uint8_t flags, void* user_data) -{ - TC_NgHttp2* nghttp2 = (TC_NgHttp2* )user_data; - - int streamId = frame->hd.stream_id; - std::map::iterator it = nghttp2->_responses.find(streamId); - if (it == nghttp2->_responses.end()) - { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - std::string n((const char*)name, namelen); - std::string v((const char*)value, valuelen); - it->second.headers.insert(std::make_pair(n, v)); - - return 0; -} - -int TC_NgHttp2::onFrameRecv(nghttp2_session* session, - const nghttp2_frame* frame, - void* user_data) -{ - TC_NgHttp2* nghttp2 = (TC_NgHttp2* )user_data; - - int streamId = frame->hd.stream_id; - if (streamId == 0) - return 0; - - std::map::iterator it = nghttp2->_responses.find(streamId); - if (it == nghttp2->_responses.end()) - { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - switch (frame->hd.type) - { - case NGHTTP2_HEADERS: - if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS) - { - it->second.state = ResponseHeadersDone; - } - return 0; - - default: - break; - } - - return 0; -} - -int TC_NgHttp2::onDataChunkRecv(nghttp2_session* session, uint8_t flags, - int32_t stream_id, const uint8_t* data, - size_t len, void* user_data) -{ - TC_NgHttp2* nghttp2 = (TC_NgHttp2* )user_data; - std::map::iterator it = nghttp2->_responses.find(stream_id); - if (it == nghttp2->_responses.end()) - { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - it->second.body.append((const char* )data, len); - return 0; -} - -int TC_NgHttp2::onStreamClose(nghttp2_session* session, int32_t stream_id, - uint32_t error_code, void* user_data) -{ - TC_NgHttp2* nghttp2 = (TC_NgHttp2* )user_data; - std::map::iterator it = nghttp2->_responses.find(stream_id); - if (it == nghttp2->_responses.end()) - { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - it->second.state = ResponseBodyDone; - - nghttp2->_doneResponses[stream_id].swap(it->second); - nghttp2->_responses.erase(it); - - return 0; -} - - - -TC_NgHttp2::TC_NgHttp2(bool isServer) : - _session(NULL), - _state(None), - _isServer(isServer) -{ - nghttp2_session_callbacks* callbacks; - nghttp2_session_callbacks_new(&callbacks); - nghttp2_session_callbacks_set_send_callback(callbacks, &TC_NgHttp2::onSend); - nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks, &TC_NgHttp2::onBeginHeaders); - nghttp2_session_callbacks_set_on_header_callback(callbacks, &TC_NgHttp2::onHeader); - nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks, &TC_NgHttp2::onFrameRecv); - nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks, &TC_NgHttp2::onDataChunkRecv); - nghttp2_session_callbacks_set_on_stream_close_callback(callbacks, &TC_NgHttp2::onStreamClose); - - if (isServer) - nghttp2_session_server_new(&_session, callbacks, this); - else - nghttp2_session_client_new(&_session, callbacks, this); - - nghttp2_session_callbacks_del(callbacks); -} - -TC_NgHttp2::~TC_NgHttp2() -{ -} - -int TC_NgHttp2::getState() const -{ - return (int)_state; -} - -void TC_NgHttp2::Init() -{ - if (_state != None) - return; - - _state = Http2; -} - -int TC_NgHttp2::settings(unsigned int maxCurrentStreams) -{ - nghttp2_settings_entry iv[2] = { - {NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, maxCurrentStreams}, - {NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, 1024 * 1024 * 1024}, - }; - - /* 24 bytes magic string also will be sent*/ - int rv = nghttp2_submit_settings(_session, - NGHTTP2_FLAG_NONE, - iv, - sizeof(iv)/sizeof(iv[0])); - rv = nghttp2_session_send(_session); - return rv; -} - -void TC_NgHttp2::onNegotiateDone(bool succ) -{ - // assert (_state == Negotiating); - _state = succ ? Http2: Http1; - if (succ) - { - int rv = nghttp2_session_upgrade(_session, - (const uint8_t*)_settings.data(), - _settings.size(), - NULL); - if (rv) - cerr << "nghttp2_session_upgrade error: " << nghttp2_strerror(rv) << endl; - } -} - -string& TC_NgHttp2::sendBuffer() -{ - return _sendBuf; -} - -nghttp2_session* TC_NgHttp2::session() const -{ - return _session; -} - -} // end namespace tars - -#endif // end #if TARS_HTTP2 -