From 21f58d250b7dcf677e6a8e7e5e7fd8b9fa79c61f Mon Sep 17 00:00:00 2001 From: ruanshudong Date: Wed, 4 Mar 2020 10:33:14 +0800 Subject: [PATCH] 1 udp in ipv6 bug 2 add tars.resource 3 fix rsp queue 4 add max buffer limit 5 send queue, data accumulate clear 6 Adjust cmake third library path 7 tc_network_buffer add iterator 8 optimize tc_http tc_http_async, improve http parser performance --- cmake/Thirdparty.cmake | 26 +- examples/CMakeLists.txt | 22 +- examples/UdpDemo/CMakeLists.txt | 5 + examples/UdpDemo/Client/CMakeLists.txt | 1 + examples/UdpDemo/Client/config.conf | 28 + examples/UdpDemo/Client/main.cpp | 243 ++++ examples/UdpDemo/Server/CMakeLists.txt | 2 + examples/UdpDemo/Server/Hello.h | 471 ++++++++ examples/UdpDemo/Server/Hello.tars | 26 + examples/UdpDemo/Server/HelloImp.cpp | 43 + examples/UdpDemo/Server/HelloImp.h | 53 + examples/UdpDemo/Server/HelloServer.cpp | 60 + examples/UdpDemo/Server/HelloServer.h | 50 + examples/UdpDemo/Server/config.conf | 87 ++ examples/scripts/run-udp.bat | 30 + examples/scripts/run-udp.sh | 28 + servant/libservant/AppProtocol.cpp | 8 +- servant/libservant/Application.cpp | 76 +- servant/libservant/Communicator.cpp | 15 +- servant/libservant/CommunicatorEpoll.cpp | 55 + servant/libservant/ObjectProxy.cpp | 15 +- servant/libservant/ServantProxy.cpp | 25 +- servant/libservant/StatReport.cpp | 61 +- servant/libservant/Transceiver.cpp | 34 +- servant/servant/Application.h | 19 +- servant/servant/Communicator.h | 6 + servant/servant/CommunicatorEpoll.h | 23 + servant/servant/EndpointInfo.h | 45 +- servant/servant/ObjectProxy.h | 45 +- servant/servant/ServantProxy.h | 16 + servant/servant/StatReport.h | 40 +- tools/tarsparse/tars.lex.cpp | 67 +- tools/tarsparse/tars.tab.cpp | 630 +++++----- tools/tarsparse/tars.tab.hpp | 7 +- util/include/util/tc_epoll_server.h | 232 ++-- util/include/util/tc_http.h | 116 +- util/include/util/tc_http_async.h | 46 +- util/include/util/tc_network_buffer.h | 340 +++++- util/src/tc_epoll_server.cpp | 259 +++- util/src/tc_http.cpp | 1407 ++++++++++++++-------- util/src/tc_http_async.cpp | 142 ++- util/src/tc_network_buffer.cpp | 43 +- 42 files changed, 3728 insertions(+), 1219 deletions(-) create mode 100644 examples/UdpDemo/CMakeLists.txt create mode 100644 examples/UdpDemo/Client/CMakeLists.txt create mode 100755 examples/UdpDemo/Client/config.conf create mode 100644 examples/UdpDemo/Client/main.cpp create mode 100644 examples/UdpDemo/Server/CMakeLists.txt create mode 100644 examples/UdpDemo/Server/Hello.h create mode 100644 examples/UdpDemo/Server/Hello.tars create mode 100644 examples/UdpDemo/Server/HelloImp.cpp create mode 100644 examples/UdpDemo/Server/HelloImp.h create mode 100644 examples/UdpDemo/Server/HelloServer.cpp create mode 100644 examples/UdpDemo/Server/HelloServer.h create mode 100755 examples/UdpDemo/Server/config.conf create mode 100644 examples/scripts/run-udp.bat create mode 100644 examples/scripts/run-udp.sh diff --git a/cmake/Thirdparty.cmake b/cmake/Thirdparty.cmake index 0bfb465..e6f1a0c 100755 --- a/cmake/Thirdparty.cmake +++ b/cmake/Thirdparty.cmake @@ -73,6 +73,7 @@ if (TARS_PROTOBUF) ExternalProject_Add(ADD_${LIB_PROTOBUF} URL http://cdn.tarsyun.com/src/protobuf-cpp-3.11.3.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND cmake cmake -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/src/protobuf -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON @@ -90,6 +91,7 @@ if (TARS_PROTOBUF) ExternalProject_Add(ADD_${LIB_PROTOBUF} URL http://cdn.tarsyun.com/src/protobuf-cpp-3.11.3.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND cmake cmake -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/src/protobuf -DBUILD_SHARED_LIBS=OFF @@ -104,8 +106,8 @@ if (TARS_PROTOBUF) endif () - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/protobuf/lib DESTINATION .) - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/protobuf/include/google DESTINATION include) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/protobuf/lib DESTINATION thirdparty) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/protobuf/include/google DESTINATION thirdparty/include) add_dependencies(thirdparty ADD_${LIB_PROTOBUF}) @@ -124,8 +126,8 @@ if (TARS_SSL) set(LIB_CRYPTO "libcrypto") ExternalProject_Add(ADD_${LIB_SSL} - DEPENDS ${LIB_ZLIB} URL http://cdn.tarsyun.com/src/openssl-1.1.1d.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND perl Configure --prefix=${CMAKE_BINARY_DIR}/src/openssl VC-WIN64A no-asm @@ -142,8 +144,8 @@ if (TARS_SSL) set(LIB_CRYPTO "crypto") ExternalProject_Add(ADD_${LIB_SSL} - DEPENDS ${LIB_ZLIB} URL http://cdn.tarsyun.com/src/openssl-1.1.1d.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND ./config --prefix=${CMAKE_BINARY_DIR}/src/openssl no-shared @@ -158,8 +160,8 @@ if (TARS_SSL) endif () - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/openssl/lib DESTINATION .) - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/openssl/include/openssl DESTINATION include) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/openssl/lib DESTINATION thirdparty) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/openssl/include/openssl DESTINATION thirdparty/include) add_dependencies(thirdparty ADD_${LIB_SSL}) endif () @@ -175,6 +177,7 @@ if (TARS_MYSQL) ExternalProject_Add(ADD_${LIB_MYSQL} URL http://cdn.tarsyun.com/src/mysql-connector-c-6.1.11-src.zip + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND cmake . -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/src/mysql -DBUILD_CONFIG=mysql_release @@ -192,6 +195,7 @@ if (TARS_MYSQL) ExternalProject_Add(ADD_${LIB_MYSQL} URL http://cdn.tarsyun.com/src/mysql-connector-c-6.1.11-src.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND cmake . -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/src/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DDISABLE_SHARED=1 @@ -206,9 +210,9 @@ if (TARS_MYSQL) endif () - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/mysql/lib DESTINATION .) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/mysql/lib DESTINATION thirdparty) - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/mysql/include/mysql DESTINATION include) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/mysql/include/mysql DESTINATION thirdparty/include) add_dependencies(thirdparty ADD_${LIB_MYSQL}) endif () @@ -228,6 +232,7 @@ if (TARS_HTTP2) if (WIN32) ExternalProject_Add(ADD_${LIB_HTTP2} URL http://cdn.tarsyun.com/src/nghttp2-1.40.0.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND cmake . -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/src/nghttp2 -DENABLE_LIB_ONLY=ON -DENABLE_STATIC_LIB=ON @@ -243,6 +248,7 @@ if (TARS_HTTP2) else () ExternalProject_Add(ADD_${LIB_HTTP2} URL http://cdn.tarsyun.com/src/nghttp2-1.40.0.tar.gz + DOWNLOAD_DIR ${CMAKE_SOURCE_DIR}/download PREFIX ${CMAKE_BINARY_DIR} INSTALL_DIR ${CMAKE_SOURCE_DIR} CONFIGURE_COMMAND cmake . -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/src/nghttp2 -DENABLE_LIB_ONLY=ON -DENABLE_STATIC_LIB=ON @@ -257,8 +263,8 @@ if (TARS_HTTP2) endif () - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/nghttp2/lib DESTINATION .) - INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/nghttp2/include/nghttp2 DESTINATION include) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/nghttp2/lib DESTINATION thirdparty) + INSTALL(DIRECTORY ${CMAKE_BINARY_DIR}/src/nghttp2/include/nghttp2 DESTINATION thirdparty/include) add_dependencies(thirdparty ADD_${LIB_HTTP2}) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index fdd737f..6c5fab3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -12,6 +12,7 @@ endif() add_subdirectory(PushDemo) add_subdirectory(QuickStartDemo) add_subdirectory(StressDemo) +add_subdirectory(UdpDemo) set(WORKING_DIRECTORY ${tars-cpp_SOURCE_DIR}) @@ -38,6 +39,13 @@ if(WIN32) COMMAND examples/scripts/run-auth.bat ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${WORKING_DIRECTORY} COMMENT "call run auth") + add_custom_target(run-udp + WORKING_DIRECTORY ${WORKING_DIRECTORY} + DEPENDS UdpServer UdpClient + USES_TERMINAL + COMMAND examples/scripts/run-udp.bat ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${WORKING_DIRECTORY} + COMMENT "call run udp") + if(TARS_HTTP2) add_custom_target(run-http2 WORKING_DIRECTORY ${WORKING_DIRECTORY} @@ -117,10 +125,16 @@ else(WIN32) COMMENT "call quick start") add_custom_target(run-http - WORKING_DIRECTORY ${WORKING_DIRECTORY} - DEPENDS HttpServer HttpClient - COMMAND sh examples/scripts/run-http.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${WORKING_DIRECTORY} - COMMENT "call run http") + WORKING_DIRECTORY ${WORKING_DIRECTORY} + DEPENDS HttpServer HttpClient + COMMAND sh examples/scripts/run-http.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${WORKING_DIRECTORY} + COMMENT "call run http") + + add_custom_target(run-udp + WORKING_DIRECTORY ${WORKING_DIRECTORY} + DEPENDS UdpServer UdpClient + COMMAND sh examples/scripts/run-udp.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${WORKING_DIRECTORY} + COMMENT "call run udp") add_custom_target(run-auth WORKING_DIRECTORY ${WORKING_DIRECTORY} diff --git a/examples/UdpDemo/CMakeLists.txt b/examples/UdpDemo/CMakeLists.txt new file mode 100644 index 0000000..6345c28 --- /dev/null +++ b/examples/UdpDemo/CMakeLists.txt @@ -0,0 +1,5 @@ + +include_directories(Server) +add_subdirectory(Server) +add_subdirectory(Client) + diff --git a/examples/UdpDemo/Client/CMakeLists.txt b/examples/UdpDemo/Client/CMakeLists.txt new file mode 100644 index 0000000..53d3c5c --- /dev/null +++ b/examples/UdpDemo/Client/CMakeLists.txt @@ -0,0 +1 @@ +build_tars_server(UdpClient UdpServer) diff --git a/examples/UdpDemo/Client/config.conf b/examples/UdpDemo/Client/config.conf new file mode 100755 index 0000000..c2a9796 --- /dev/null +++ b/examples/UdpDemo/Client/config.conf @@ -0,0 +1,28 @@ + + + + + #tarsregistry locator + locator = tars.tarsregistry.QueryObj@tcp -h 127.0.0.1 -p 17890 + #max invoke timeout + sync-invoke-timeout = 5000 + #refresh endpoint interval + refresh-endpoint-interval = 10000 + #stat obj + stat = tars.tarsstat.StatObj + #max send queue length limit + sendqueuelimit = 100000 + #async queue length limit + asyncqueuecap = 100000 + #async callback thread num + asyncthread = 3 + #net thread + netthread = 1 + #merge net and sync thread + mergenetasync = 0 + #module name + modulename = TestApp.UdpClient + + + + diff --git a/examples/UdpDemo/Client/main.cpp b/examples/UdpDemo/Client/main.cpp new file mode 100644 index 0000000..d91b236 --- /dev/null +++ b/examples/UdpDemo/Client/main.cpp @@ -0,0 +1,243 @@ +/** + * 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. + */ + +#include +#include "servant/Communicator.h" +#include "Hello.h" +#include "util/tc_option.h" + +using namespace std; +using namespace tars; +using namespace TestApp; + +Communicator* _comm; + +static string helloObj = "TestApp.UdpServer.UdpObj@udp -h 127.0.0.1 -p 9016 -e 1"; +static string ipv6Obj = "TestApp.UdpServer.Ipv6Obj@udp -h ::1 -p 25460"; + +struct Param +{ + int count; + string call; + int thread; + int buffersize; + int netthread; + + HelloPrx pPrx; +}; + +Param param; +std::atomic request_count(0); +std::atomic callback_count(0); + +struct HelloCallback : public HelloPrxCallback +{ + HelloCallback(int64_t t, int i, int c) : start(t), cur(i), count(c) + { + + } + + //call back + virtual void callback_testHello(int ret, const string &r) + { + assert(ret == 0); + callback_count++; + + if(cur == count-1) + { + int64_t cost = TC_Common::now2us() - start; + cout << "callback_testHello count:" << count << ", " << cost << " us, avg:" << 1.*cost/count << "us" << endl; + } + } + + virtual void callback_testHello_exception(tars::Int32 ret) + { + cout << "callback exception:" << ret << endl; + } + + int64_t start; + int cur; + int count; +}; + + +void syncCall(int c) +{ + string buffer(param.buffersize, 'a'); + + int64_t t = TC_Common::now2us(); + //发起远程调用 + for (int i = 0; i < c; ++i) + { + string r; + + try + { + param.pPrx->testHello(buffer, r); + } + catch(exception& e) + { + cout << "exception:" << e.what() << endl; + } + ++callback_count; + } + + int64_t cost = TC_Common::now2us() - t; + cout << "syncCall total:" << cost << "us, avg:" << 1.*cost/c << "us" << endl; +} + +void asyncCall(int c) +{ + int64_t t = TC_Common::now2us(); + + string buffer(param.buffersize, 'a'); + + //发起远程调用 + for (int i = 0; i < c;) + { + if(request_count - callback_count < 100) { + i++; + request_count++; + HelloPrxCallbackPtr p = new HelloCallback(t, i, c); + try { + param.pPrx->async_testHello(p, buffer); + } + catch (exception & e) { + cout << "exception:" << e.what() << endl; + } + } + else + { + TC_Common::msleep(10); + } + } + + int64_t cost = TC_Common::now2us() - t; + cout << "asyncCall send:" << cost << "us, avg:" << 1.*cost/c << "us" << endl; +} + +int main(int argc, char *argv[]) +{ + try + { + if (argc < 6) + { + cout << "Usage:" << argv[0] << "--config=conf --count=1000 --call=[sync|async|syncv6|asyncv6] --thread=1 --buffersize=1000 --netthread=1" << endl; + + return 0; + } + + TC_Option option; + option.decode(argc, argv); + + param.count = TC_Common::strto(option.getValue("count")); + if(param.count <= 0) param.count = 1000; + param.buffersize = TC_Common::strto(option.getValue("buffersize")); + if(param.buffersize <= 0) param.buffersize = 1000; + param.call = option.getValue("call"); + if(param.call.empty()) param.call = "sync"; + param.thread = TC_Common::strto(option.getValue("thread")); + if(param.thread <= 0) param.thread = 1; + param.netthread = TC_Common::strto(option.getValue("netthread")); + if(param.netthread <= 0) param.netthread = 1; + + _comm = new Communicator(); + + TC_Config conf; + conf.parseFile(option.getValue("config")); + _comm->setProperty(conf); + +// TafRollLogger::getInstance()->logger()->setLogLevel(6); + + _comm->setProperty("sendqueuelimit", "1000000"); + _comm->setProperty("asyncqueuecap", "1000000"); + + _comm->setProperty("netthread", TC_Common::tostr(param.netthread)); + + + int64_t start = TC_Common::now2us(); + + std::function func; + + if (param.call == "sync") + { + func = syncCall; + param.pPrx = _comm->stringToProxy(helloObj); + + } + else if (param.call == "async") + { + func = asyncCall; + param.pPrx = _comm->stringToProxy(helloObj); + + } + else if (param.call == "syncv6") + { + func = syncCall; + param.pPrx = _comm->stringToProxy(ipv6Obj); + + } + else if (param.call == "asyncv6") + { + func = asyncCall; + param.pPrx = _comm->stringToProxy(ipv6Obj); + } + else + { + cout << "no func, exits" << endl; + exit(0); + } + + param.pPrx->tars_connect_timeout(5000); + param.pPrx->tars_async_timeout(60*1000); + param.pPrx->tars_ping(); + + vector vt; + for(int i = 0 ; i< param.thread; i++) + { + vt.push_back(new std::thread(func, param.count)); + } + + std::thread print([&]{while(callback_count != param.count * param.thread) { + cout << "Auth:" << param.call << " : ----------finish count:" << callback_count << endl; + std::this_thread::sleep_for(std::chrono::seconds(1)); + };}); + + for(size_t i = 0 ; i< vt.size(); i++) + { + vt[i]->join(); + delete vt[i]; + } + + cout << "(pid:" << std::this_thread::get_id() << ")" + << "(count:" << param.count << ")" + << "(use ms:" << (TC_Common::now2us() - start)/1000 << ")" + << endl; + + while(callback_count != param.count * param.thread) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + print.join(); + cout << "Auth:" << param.call << " ----------finish count:" << callback_count << endl; + } + catch(exception &ex) + { + cout << ex.what() << endl; + } + cout << "main return." << endl; + + return 0; +} diff --git a/examples/UdpDemo/Server/CMakeLists.txt b/examples/UdpDemo/Server/CMakeLists.txt new file mode 100644 index 0000000..b7a6673 --- /dev/null +++ b/examples/UdpDemo/Server/CMakeLists.txt @@ -0,0 +1,2 @@ +build_tars_server("UdpServer" "") + diff --git a/examples/UdpDemo/Server/Hello.h b/examples/UdpDemo/Server/Hello.h new file mode 100644 index 0000000..f85e089 --- /dev/null +++ b/examples/UdpDemo/Server/Hello.h @@ -0,0 +1,471 @@ +// ********************************************************************** +// This file was generated by a TARS parser! +// TARS version 2.0.0. +// ********************************************************************** + +#ifndef __HELLO_H_ +#define __HELLO_H_ + +#include +#include +#include +#include "tup/Tars.h" +#include "tup/TarsJson.h" +using namespace std; +#include "servant/ServantProxy.h" +#include "servant/Servant.h" + + +namespace TestApp +{ + + /* callback of async proxy for client */ + class HelloPrxCallback: public tars::ServantProxyCallback + { + public: + virtual ~HelloPrxCallback(){} + virtual void callback_test(tars::Int32 ret) + { throw std::runtime_error("callback_test() override incorrect."); } + virtual void callback_test_exception(tars::Int32 ret) + { throw std::runtime_error("callback_test_exception() override incorrect."); } + + virtual void callback_testHello(tars::Int32 ret, const std::string& sRsp) + { throw std::runtime_error("callback_testHello() override incorrect."); } + virtual void callback_testHello_exception(tars::Int32 ret) + { throw std::runtime_error("callback_testHello_exception() override incorrect."); } + + public: + virtual const map & getResponseContext() const + { + CallbackThreadData * pCbtd = CallbackThreadData::getData(); + assert(pCbtd != NULL); + + if(!pCbtd->getContextValid()) + { + throw TC_Exception("cann't get response context"); + } + return pCbtd->getResponseContext(); + } + + public: + virtual int onDispatch(tars::ReqMessagePtr msg) + { + static ::std::string __Hello_all[]= + { + "test", + "testHello" + }; + pair r = equal_range(__Hello_all, __Hello_all+2, string(msg->request.sFuncName)); + if(r.first == r.second) return tars::TARSSERVERNOFUNCERR; + switch(r.first - __Hello_all) + { + case 0: + { + if (msg->response->iRet != tars::TARSSERVERSUCCESS) + { + callback_test_exception(msg->response->iRet); + + return msg->response->iRet; + } + tars::TarsInputStream _is; + + _is.setBuffer(msg->response->sBuffer); + tars::Int32 _ret; + _is.read(_ret, 0, true); + + CallbackThreadData * pCbtd = CallbackThreadData::getData(); + assert(pCbtd != NULL); + + pCbtd->setResponseContext(msg->response->context); + + callback_test(_ret); + + pCbtd->delResponseContext(); + + return tars::TARSSERVERSUCCESS; + + } + case 1: + { + if (msg->response->iRet != tars::TARSSERVERSUCCESS) + { + callback_testHello_exception(msg->response->iRet); + + return msg->response->iRet; + } + tars::TarsInputStream _is; + + _is.setBuffer(msg->response->sBuffer); + tars::Int32 _ret; + _is.read(_ret, 0, true); + + std::string sRsp; + _is.read(sRsp, 2, true); + CallbackThreadData * pCbtd = CallbackThreadData::getData(); + assert(pCbtd != NULL); + + pCbtd->setResponseContext(msg->response->context); + + callback_testHello(_ret, sRsp); + + pCbtd->delResponseContext(); + + return tars::TARSSERVERSUCCESS; + + } + } + return tars::TARSSERVERNOFUNCERR; + } + + }; + typedef tars::TC_AutoPtr HelloPrxCallbackPtr; + + /* callback of coroutine async proxy for client */ + class HelloCoroPrxCallback: public HelloPrxCallback + { + public: + virtual ~HelloCoroPrxCallback(){} + public: + virtual const map & getResponseContext() const { return _mRspContext; } + + virtual void setResponseContext(const map &mContext) { _mRspContext = mContext; } + + public: + int onDispatch(tars::ReqMessagePtr msg) + { + static ::std::string __Hello_all[]= + { + "test", + "testHello" + }; + + pair r = equal_range(__Hello_all, __Hello_all+2, string(msg->request.sFuncName)); + if(r.first == r.second) return tars::TARSSERVERNOFUNCERR; + switch(r.first - __Hello_all) + { + case 0: + { + if (msg->response->iRet != tars::TARSSERVERSUCCESS) + { + callback_test_exception(msg->response->iRet); + + return msg->response->iRet; + } + tars::TarsInputStream _is; + + _is.setBuffer(msg->response->sBuffer); + try + { + tars::Int32 _ret; + _is.read(_ret, 0, true); + + setResponseContext(msg->response->context); + + callback_test(_ret); + + } + catch(std::exception &ex) + { + callback_test_exception(tars::TARSCLIENTDECODEERR); + + return tars::TARSCLIENTDECODEERR; + } + catch(...) + { + callback_test_exception(tars::TARSCLIENTDECODEERR); + + return tars::TARSCLIENTDECODEERR; + } + + return tars::TARSSERVERSUCCESS; + + } + case 1: + { + if (msg->response->iRet != tars::TARSSERVERSUCCESS) + { + callback_testHello_exception(msg->response->iRet); + + return msg->response->iRet; + } + tars::TarsInputStream _is; + + _is.setBuffer(msg->response->sBuffer); + try + { + tars::Int32 _ret; + _is.read(_ret, 0, true); + + std::string sRsp; + _is.read(sRsp, 2, true); + setResponseContext(msg->response->context); + + callback_testHello(_ret, sRsp); + + } + catch(std::exception &ex) + { + callback_testHello_exception(tars::TARSCLIENTDECODEERR); + + return tars::TARSCLIENTDECODEERR; + } + catch(...) + { + callback_testHello_exception(tars::TARSCLIENTDECODEERR); + + return tars::TARSCLIENTDECODEERR; + } + + return tars::TARSSERVERSUCCESS; + + } + } + return tars::TARSSERVERNOFUNCERR; + } + + protected: + map _mRspContext; + }; + typedef tars::TC_AutoPtr HelloCoroPrxCallbackPtr; + + /* proxy for client */ + class HelloProxy : public tars::ServantProxy + { + public: + typedef map TARS_CONTEXT; + tars::Int32 test(const map &context = TARS_CONTEXT(),map * pResponseContext = NULL) + { + tars::TarsOutputStream _os; + std::map _mStatus; + shared_ptr rep = tars_invoke(tars::TARSNORMAL,"test", _os, context, _mStatus); + if(pResponseContext) + { + pResponseContext->swap(rep->context); + } + + tars::TarsInputStream _is; + _is.setBuffer(rep->sBuffer); + tars::Int32 _ret; + _is.read(_ret, 0, true); + return _ret; + } + + void async_test(HelloPrxCallbackPtr callback,const map& context = TARS_CONTEXT()) + { + tars::TarsOutputStream _os; + std::map _mStatus; + tars_invoke_async(tars::TARSNORMAL,"test", _os, context, _mStatus, callback); + } + + void coro_test(HelloCoroPrxCallbackPtr callback,const map& context = TARS_CONTEXT()) + { + tars::TarsOutputStream _os; + std::map _mStatus; + tars_invoke_async(tars::TARSNORMAL,"test", _os, context, _mStatus, callback, true); + } + + tars::Int32 testHello(const std::string & sReq,std::string &sRsp,const map &context = TARS_CONTEXT(),map * pResponseContext = NULL) + { + tars::TarsOutputStream _os; + _os.write(sReq, 1); + _os.write(sRsp, 2); + std::map _mStatus; + shared_ptr rep = tars_invoke(tars::TARSNORMAL,"testHello", _os, context, _mStatus); + if(pResponseContext) + { + pResponseContext->swap(rep->context); + } + + tars::TarsInputStream _is; + _is.setBuffer(rep->sBuffer); + tars::Int32 _ret; + _is.read(_ret, 0, true); + _is.read(sRsp, 2, true); + return _ret; + } + + void async_testHello(HelloPrxCallbackPtr callback,const std::string &sReq,const map& context = TARS_CONTEXT()) + { + tars::TarsOutputStream _os; + _os.write(sReq, 1); + std::map _mStatus; + tars_invoke_async(tars::TARSNORMAL,"testHello", _os, context, _mStatus, callback); + } + + void coro_testHello(HelloCoroPrxCallbackPtr callback,const std::string &sReq,const map& context = TARS_CONTEXT()) + { + tars::TarsOutputStream _os; + _os.write(sReq, 1); + std::map _mStatus; + tars_invoke_async(tars::TARSNORMAL,"testHello", _os, context, _mStatus, callback, true); + } + + HelloProxy* tars_hash(int64_t key) + { + return (HelloProxy*)ServantProxy::tars_hash(key); + } + + HelloProxy* tars_consistent_hash(int64_t key) + { + return (HelloProxy*)ServantProxy::tars_consistent_hash(key); + } + + HelloProxy* tars_set_timeout(int msecond) + { + return (HelloProxy*)ServantProxy::tars_set_timeout(msecond); + } + + static const char* tars_prxname() { return "HelloProxy"; } + }; + typedef tars::TC_AutoPtr HelloPrx; + + /* servant for server */ + class Hello : public tars::Servant + { + public: + virtual ~Hello(){} + virtual tars::Int32 test(tars::TarsCurrentPtr current) = 0; + static void async_response_test(tars::TarsCurrentPtr current, tars::Int32 _ret) + { + if (current->getRequestVersion() == TUPVERSION ) + { + UniAttribute tarsAttr; + tarsAttr.setVersion(current->getRequestVersion()); + tarsAttr.put("", _ret); + + vector sTupResponseBuffer; + tarsAttr.encode(sTupResponseBuffer); + current->sendResponse(tars::TARSSERVERSUCCESS, sTupResponseBuffer); + } + else + { + tars::TarsOutputStream _os; + _os.write(_ret, 0); + + current->sendResponse(tars::TARSSERVERSUCCESS, _os.getByteBuffer()); + } + } + + virtual tars::Int32 testHello(const std::string & sReq,std::string &sRsp,tars::TarsCurrentPtr current) = 0; + static void async_response_testHello(tars::TarsCurrentPtr current, tars::Int32 _ret, const std::string &sRsp) + { + if (current->getRequestVersion() == TUPVERSION ) + { + UniAttribute tarsAttr; + tarsAttr.setVersion(current->getRequestVersion()); + tarsAttr.put("", _ret); + tarsAttr.put("sRsp", sRsp); + + vector sTupResponseBuffer; + tarsAttr.encode(sTupResponseBuffer); + current->sendResponse(tars::TARSSERVERSUCCESS, sTupResponseBuffer); + } + else + { + tars::TarsOutputStream _os; + _os.write(_ret, 0); + + _os.write(sRsp, 2); + + current->sendResponse(tars::TARSSERVERSUCCESS, _os.getByteBuffer()); + } + } + + public: + int onDispatch(tars::TarsCurrentPtr _current, vector &_sResponseBuffer) + { + static ::std::string __TestApp__Hello_all[]= + { + "test", + "testHello" + }; + + pair r = equal_range(__TestApp__Hello_all, __TestApp__Hello_all+2, _current->getFuncName()); + if(r.first == r.second) return tars::TARSSERVERNOFUNCERR; + switch(r.first - __TestApp__Hello_all) + { + case 0: + { + tars::TarsInputStream _is; + _is.setBuffer(_current->getRequestBuffer()); + if (_current->getRequestVersion() == TUPVERSION) + { + UniAttribute tarsAttr; + tarsAttr.setVersion(_current->getRequestVersion()); + tarsAttr.decode(_current->getRequestBuffer()); + } + else + { + } + tars::Int32 _ret = test(_current); + if(_current->isResponse()) + { + if (_current->getRequestVersion() == TUPVERSION ) + { + UniAttribute tarsAttr; + tarsAttr.setVersion(_current->getRequestVersion()); + tarsAttr.put("", _ret); + tarsAttr.encode(_sResponseBuffer); + } + else + { + tars::TarsOutputStream _os; + _os.write(_ret, 0); + _os.swap(_sResponseBuffer); + } + } + return tars::TARSSERVERSUCCESS; + + } + case 1: + { + tars::TarsInputStream _is; + _is.setBuffer(_current->getRequestBuffer()); + std::string sReq; + std::string sRsp; + if (_current->getRequestVersion() == TUPVERSION) + { + UniAttribute tarsAttr; + tarsAttr.setVersion(_current->getRequestVersion()); + tarsAttr.decode(_current->getRequestBuffer()); + tarsAttr.get("sReq", sReq); + tarsAttr.getByDefault("sRsp", sRsp, sRsp); + } + else + { + _is.read(sReq, 1, true); + _is.read(sRsp, 2, false); + } + tars::Int32 _ret = testHello(sReq,sRsp, _current); + if(_current->isResponse()) + { + if (_current->getRequestVersion() == TUPVERSION ) + { + UniAttribute tarsAttr; + tarsAttr.setVersion(_current->getRequestVersion()); + tarsAttr.put("", _ret); + tarsAttr.put("sRsp", sRsp); + tarsAttr.encode(_sResponseBuffer); + } + else + { + tars::TarsOutputStream _os; + _os.write(_ret, 0); + _os.write(sRsp, 2); + _os.swap(_sResponseBuffer); + } + } + return tars::TARSSERVERSUCCESS; + + } + } + return tars::TARSSERVERNOFUNCERR; + } + }; + + +} + + + +#endif diff --git a/examples/UdpDemo/Server/Hello.tars b/examples/UdpDemo/Server/Hello.tars new file mode 100644 index 0000000..174c4f3 --- /dev/null +++ b/examples/UdpDemo/Server/Hello.tars @@ -0,0 +1,26 @@ +/** + * 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. + */ + +module TestApp +{ + +interface Hello +{ + int test(); + int testHello(string sReq, out string sRsp); +}; + +}; diff --git a/examples/UdpDemo/Server/HelloImp.cpp b/examples/UdpDemo/Server/HelloImp.cpp new file mode 100644 index 0000000..b8cf947 --- /dev/null +++ b/examples/UdpDemo/Server/HelloImp.cpp @@ -0,0 +1,43 @@ +/** + * 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. + */ + +#include "HelloImp.h" +#include "servant/Application.h" + +using namespace std; + +////////////////////////////////////////////////////// +void HelloImp::initialize() +{ + //initialize servant here: + //... +} + +////////////////////////////////////////////////////// +void HelloImp::destroy() +{ + //destroy servant here: + //... +} + +int HelloImp::testHello(const std::string &sReq, std::string &sRsp, tars::TarsCurrentPtr current) +{ +// TLOGDEBUG("HelloImp::testHellosReq:"<(ServerConfig::Application + "." + ServerConfig::ServerName + ".UdpObj"); + addServant(ServerConfig::Application + "." + ServerConfig::ServerName + ".Ipv6Obj"); +} +///////////////////////////////////////////////////////////////// +void +HelloServer::destroyApp() +{ + //destroy application here: + //... +} +///////////////////////////////////////////////////////////////// +int +main(int argc, char* argv[]) +{ + try + { + g_app.main(argc, argv); + g_app.waitForShutdown(); + } + catch (std::exception& e) + { + cerr << "std::exception:" << e.what() << std::endl; + } + catch (...) + { + cerr << "unknown exception." << std::endl; + } + return -1; +} +///////////////////////////////////////////////////////////////// diff --git a/examples/UdpDemo/Server/HelloServer.h b/examples/UdpDemo/Server/HelloServer.h new file mode 100644 index 0000000..0fbc36b --- /dev/null +++ b/examples/UdpDemo/Server/HelloServer.h @@ -0,0 +1,50 @@ +/** + * 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 _HelloServer_H_ +#define _HelloServer_H_ + +#include +#include "servant/Application.h" + +using namespace tars; + +/** + * + **/ +class HelloServer : public Application +{ +public: + /** + * + **/ + virtual ~HelloServer() {}; + + /** + * + **/ + virtual void initialize(); + + /** + * + **/ + virtual void destroyApp(); +}; + +extern HelloServer g_app; + +//////////////////////////////////////////// +#endif diff --git a/examples/UdpDemo/Server/config.conf b/examples/UdpDemo/Server/config.conf new file mode 100755 index 0000000..8aa4f0d --- /dev/null +++ b/examples/UdpDemo/Server/config.conf @@ -0,0 +1,87 @@ + + + + + #tarsregistry locator + locator = tars.tarsregistry.QueryObj@tcp -h 127.0.0.1 -p 17890 + #max invoke timeout + sync-invoke-timeout = 5000 + #refresh endpoint interval + refresh-endpoint-interval = 10000 + #stat obj + stat = tars.tarsstat.StatObj + #max send queue length limit + sendqueuelimit = 100000 + #async queue length limit + asyncqueuecap = 100000 + #async callback thread num + asyncthread = 3 + #net thread + netthread = 1 + #merge net and sync thread + mergenetasync = 0 + #module name + modulename = TestApp.UdpServer + + + + + #not cout + closecout = 0 + #app name + app = TestApp + #server name + server = UdpServer + #path + basepath = ./ + datapath = ./ + #log path + logpath = ./ + #merge net and imp thread + mergenetimp = 0 + #local ip, for tarsnode +# local = tcp -h 127.0.0.1 -p 15001 -t 10000 + + #tarsnode +# node = ServerObj@tcp -h 127.0.0.1 -p 2345 -t 10000 + #config obj +# config = tars.tarsconfig.ConfigObj + #notify obj +# notify = tars.tarsconfig.NotifyObj + #log obj +# log = tars.tarslog.LogObj + + + #ip:port:timeout + endpoint = udp -h 127.0.0.1 -p 9016 -t 10000 -e 1 + #allow ip + allow = + #max connection num + maxconns = 4096 + #imp thread num + threads = 5 + #servant + servant = TestApp.UdpServer.UdpObj + #queue capacity + queuecap = 1000000 + #tars protocol + protocol = tars + + + + #ip:port:timeout + endpoint = udp -h ::1 -p 25460 -t 10000 + #允许的IP地址 + allow = + #最大连接数 + maxconns = 4096 + #当前线程个数 + threads = 5 + #处理对象 + servant = TestApp.UdpServer.Ipv6Obj + #队列最大包个数 + queuecap = 1000000 + + + + diff --git a/examples/scripts/run-udp.bat b/examples/scripts/run-udp.bat new file mode 100644 index 0000000..59d7eb8 --- /dev/null +++ b/examples/scripts/run-udp.bat @@ -0,0 +1,30 @@ + +echo "run-auth.bat" + +set EXE_PATH=%1 +set SRC_PATH=%2 + +echo %EXE_PATH% %SRC_PATH% + +taskkill /im UdpServer.exe /t /f + +timeout /T 1 + +echo "start server: %EXE_PATH%/UdpServer.exe --config=%SRC_PATH%/examples/UdpDemo/Server/config.conf" + +start /b %EXE_PATH%\\UdpServer.exe --config=%SRC_PATH%\\examples\\UdpDemo\\Server\\config.conf + +timeout /T 3 + +echo "client: ${EXE_PATH}/UdpClient.exe" + +%EXE_PATH%\\UdpClient.exe --count=10000 --thread=2 --call=sync --buffersize=1000 --netthread=1 +%EXE_PATH%\\UdpClient.exe --count=10000 --thread=2 --call=async --buffersize=1000 --netthread=1 + +timeout /T 1 + +taskkill /im UdpServer.exe /t /f + + + + diff --git a/examples/scripts/run-udp.sh b/examples/scripts/run-udp.sh new file mode 100644 index 0000000..5833b31 --- /dev/null +++ b/examples/scripts/run-udp.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "run-auth.sh" + +EXE_PATH=$1 +SRC_PATH=$2 + +echo ${EXE_PATH} ${SRC_PATH} + +killall -9 UdpServer + +sleep 1 +echo "start server: ${EXE_PATH}/UdpServer --config=${SRC_PATH}/examples/UdpDemo/Server/config.conf &" + +${EXE_PATH}/UdpServer --config=${SRC_PATH}/examples/UdpDemo/Server/config.conf & + +sleep 1 + +echo "client: ${EXE_PATH}/UdpClient" + +${EXE_PATH}/UdpClient --config=${SRC_PATH}/examples/UdpDemo/Client/config.conf --count=10000 --thread=2 --call=sync --buffersize=1000 --netthread=1 +${EXE_PATH}/UdpClient --config=${SRC_PATH}/examples/UdpDemo/Client/config.conf --count=10000 --thread=2 --call=async --buffersize=1000 --netthread=1 + +sleep 1 + +killall -9 UdpServer + + diff --git a/servant/libservant/AppProtocol.cpp b/servant/libservant/AppProtocol.cpp index d6af6c1..c6096fb 100644 --- a/servant/libservant/AppProtocol.cpp +++ b/servant/libservant/AppProtocol.cpp @@ -75,7 +75,7 @@ vector ProxyProtocol::http1Request(tars::RequestPacket& request, Transceiv struct Http1Context { - string buff; +// string buff; TC_HttpResponse httpRsp; }; @@ -90,10 +90,10 @@ TC_NetWorkBuffer::PACKET_TYPE ProxyProtocol::http1Response(TC_NetWorkBuffer &in, in.setContextData(context, [=]{ delete context; }); } - context->buff.append(in.getBuffersString()); - in.clearBuffers(); +// context->buff.append(in.getBuffersString()); +// in.clearBuffers(); - if(context->httpRsp.incrementDecode(context->buff)) + if(context->httpRsp.incrementDecode(in)) { rsp.iRequestId = ((Transceiver*)(in.getConnection()))->getAdapterProxy()->getId(); diff --git a/servant/libservant/Application.cpp b/servant/libservant/Application.cpp index c09408b..219f28f 100644 --- a/servant/libservant/Application.cpp +++ b/servant/libservant/Application.cpp @@ -84,6 +84,8 @@ bool ServerConfig::ManualListen = false; //手工启动监听端口 bool ServerConfig::MergeNetImp = false; //合并网络和处理线程 int ServerConfig::NetThread = 1; //servernet thread bool ServerConfig::CloseCout = true; +int ServerConfig::BackPacketLimit = 0; +int ServerConfig::BackPacketMin = 1024; #if TARS_SSL std::string ServerConfig::CA; @@ -92,8 +94,6 @@ std::string ServerConfig::Key; bool ServerConfig::VerifyClient = false; #endif -#define OUT_LINE (TC_Common::outfill("", '-', 80)) -#define OUT_LINE_LONG (TC_Common::outfill("", '=', 80)) /////////////////////////////////////////////////////////////////////////////////////////// TC_Config Application::_conf; @@ -157,14 +157,12 @@ void reportRspQueue(TC_EpollServer *epollServer) { iLastCheckTime = iNow; - vector vNetThread = epollServer->getNetThread(); - - unsigned int iNetThreadNum = epollServer->getNetThreadNum(); + const vector &adapters = epollServer->getBindAdapters(); size_t n = 0; - for (size_t i = 0; i < iNetThreadNum; ++i) + for (size_t i = 0; i < adapters.size(); ++i) { - n = n + vNetThread[i]->getSendRspSize(); + n = n + adapters[i]->getSendBufferSize(); } g_pReportRspQueue->report((int)n); @@ -419,14 +417,20 @@ bool Application::cmdConnections(const string& command, const string& params, st os << TC_Common::outfill("conn-uid", ' ', 15) << TC_Common::outfill("ip:port", ' ', 25) << TC_Common::outfill("last-time", ' ', 25) - << TC_Common::outfill("timeout", ' ', 10) << endl; + << TC_Common::outfill("timeout", ' ', 10) + << TC_Common::outfill("recvBufferSize", ' ', 30) + << TC_Common::outfill("sendBufferSize", ' ', 30) + << endl; for (size_t i = 0; i < v.size(); i++) { os << TC_Common::outfill(TC_Common::tostr(v[i].uid), ' ', 15) << TC_Common::outfill(v[i].ip + ":" + TC_Common::tostr(v[i].port), ' ', 25) << TC_Common::outfill(TC_Common::tm2str(v[i].iLastRefreshTime, "%Y-%m-%d %H:%M:%S"), ' ', 25) - << TC_Common::outfill(TC_Common::tostr(v[i].timeout), ' ', 10) << endl; + << TC_Common::outfill(TC_Common::tostr(v[i].timeout), ' ', 10) + << TC_Common::outfill(TC_Common::tostr(v[i].recvBufferSize), ' ', 30) + << TC_Common::outfill(TC_Common::tostr(v[i].sendBufferSize), ' ', 30) + << endl; } } os << OUT_LINE_LONG << endl; @@ -574,6 +578,31 @@ bool Application::cmdReloadLocator(const string& command, const string& params, return bSucc; } +bool Application::cmdViewResource(const string& command, const string& params, string& result) +{ + TLOGDEBUG("Application::cmdViewResource:" << command << " " << params << endl); + + ostringstream os; + + os << _communicator->getResouresInfo() << endl; + + os << OUT_LINE << endl; + + vector adapters = _epollServer->getBindAdapters(); + for(auto adapter : adapters) + { + outAdapter(os, ServantHelperManager::getInstance()->getAdapterServant(adapter->getName()), adapter); + os << TC_Common::outfill("recv-buffer-count") << adapter->getRecvBufferSize() << endl; + os << TC_Common::outfill("send-buffer-count") << adapter->getSendBufferSize() << endl; + } + + result += os.str(); + + TLOGDEBUG("Application::cmdViewResource result:" << result << endl); + + return true; +} + void Application::outAllAdapter(ostream &os) { auto m = _epollServer->getListenSocketInfo(); @@ -726,6 +755,12 @@ void Application::main(const TC_Option &option) //设置是否标准输出 TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_CLOSE_COUT, Application::cmdCloseCout); + //设置是否标准输出 + TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_RELOAD_LOCATOR, Application::cmdReloadLocator); + + //设置是否标准输出 + TARS_ADD_ADMIN_CMD_PREFIX(TARS_CMD_RESOURCE, Application::cmdViewResource); + //上报版本 TARS_REPORTVERSION(TARS_VERSION); @@ -921,12 +956,16 @@ void Application::outServer(ostream &os) os << TC_Common::outfill("NetThread(netthread)") << ServerConfig::NetThread << endl; os << TC_Common::outfill("ManualListen(manuallisten)") << ServerConfig::ManualListen << endl; os << TC_Common::outfill("MergeNetImp(mergenetimp)") << ServerConfig::MergeNetImp << endl; - os << TC_Common::outfill("ReportFlow") << ServerConfig::ReportFlow<< endl; -#if TARS_SSL - cout << TC_Common::outfill("Ca") << ServerConfig::CA << endl; - cout << TC_Common::outfill("Cert") << ServerConfig::Cert << endl; - cout << TC_Common::outfill("Key") << ServerConfig::Key << endl; - cout << TC_Common::outfill("VerifyClient") << ServerConfig::VerifyClient << endl; + os << TC_Common::outfill("ReportFlow(reportflow)") << ServerConfig::ReportFlow<< endl; + os << TC_Common::outfill("BackPacketLimit(backpacketlimit)") << ServerConfig::BackPacketLimit<< endl; + os << TC_Common::outfill("BackPacketMin(backpacketmin)") << ServerConfig::BackPacketMin<< endl; + +#if TAF_SSL + cout << TC_Common::outfill("Ca(ca)") << ServerConfig::CA << endl; + cout << TC_Common::outfill("Cert(cert)") << ServerConfig::Cert << endl; + cout << TC_Common::outfill("Key(key)") << ServerConfig::Key << endl; + cout << TC_Common::outfill("VerifyClient(verifyclient)") << ServerConfig::VerifyClient << endl; +// cout << TC_Common::outfill("Ciphers(ciphers)") << ServerConfig::Ciphers << endl; #endif } @@ -997,6 +1036,8 @@ void Application::initializeServer() ServerConfig::MergeNetImp = _conf.get("/tars/application/server", "0") == "0" ? false : true; ServerConfig::NetThread = TC_Common::strto(toDefault(_conf.get("/tars/application/server"), "1")); ServerConfig::CloseCout = _conf.get("/tars/application/server","1")=="0"?0:1; + ServerConfig::BackPacketLimit = TC_Common::strto(_conf.get("/tars/application/server", "100*1024*1024")); + ServerConfig::BackPacketMin = TC_Common::strto(_conf.get("/tars/application/server", "1024")); #if TARS_SSL ServerConfig::CA = _conf.get("/tars/application/server"); @@ -1243,7 +1284,10 @@ void Application::bindAdapter(vector& adapters) bindAdapter->setProtocolName(_conf.get(sLastPath + "", "tars")); - if (bindAdapter->isTarsProtocol()) + bindAdapter->setBackPacketBuffLimit(ServerConfig::BackPacketLimit); + bindAdapter->setBackPacketBuffMin(ServerConfig::BackPacketMin); + + if (bindAdapter->isTarsProtocol()) { bindAdapter->setProtocol(AppProtocol::parse); } diff --git a/servant/libservant/Communicator.cpp b/servant/libservant/Communicator.cpp index 7744a49..23b94d0 100644 --- a/servant/libservant/Communicator.cpp +++ b/servant/libservant/Communicator.cpp @@ -15,8 +15,8 @@ */ #include "util/tc_file.h" - #include "servant/Communicator.h" +#include "servant/Application.h" #include "servant/StatReport.h" #include "servant/TarsLogger.h" @@ -458,10 +458,21 @@ vector Communicator::getEndpoint(const string & objName) vector Communicator::getEndpoint4All(const string & objName) { - ServantProxy * pServantProxy = getServantProxy(objName); + ServantProxy *pServantProxy = getServantProxy(objName); return pServantProxy->getEndpoint4All(); } +string Communicator::getResouresInfo() +{ + ostringstream os; + for (size_t i = 0; i < _clientThreadNum; ++i) + { + os << OUT_LINE << endl; + os << _communicatorEpoll[i]->getResouresInfo(); + } + return os.str(); +} + void Communicator::terminate() { { diff --git a/servant/libservant/CommunicatorEpoll.cpp b/servant/libservant/CommunicatorEpoll.cpp index 35057d1..436a576 100755 --- a/servant/libservant/CommunicatorEpoll.cpp +++ b/servant/libservant/CommunicatorEpoll.cpp @@ -16,6 +16,7 @@ #include "servant/CommunicatorEpoll.h" #include "servant/Communicator.h" +#include "servant/Application.h" #include "servant/TarsLogger.h" #include "servant/StatReport.h" @@ -380,7 +381,60 @@ void CommunicatorEpoll::doStat() void CommunicatorEpoll::pushAsyncThreadQueue(ReqMessage * msg) { _communicator->pushAsyncThreadQueue(msg); +} +void CommunicatorEpoll::reConnect(int64_t ms, Transceiver*p) +{ + _reconnect[ms] = p; +} + +string CommunicatorEpoll::getResouresInfo() +{ + ostringstream desc; + desc << TC_Common::outfill("index") << _netThreadSeq << endl; + if(_communicator->_statReport) { + desc << TC_Common::outfill("stat size") << _communicator->_statReport->getQueueSize(_netThreadSeq) << endl; + } + desc << TC_Common::outfill("obj num") << _objectProxyFactory->getObjNum() << endl; + + const static string TAB = " "; + for(size_t i = 0; i < _objectProxyFactory->getObjNum(); ++i) + { + desc << TAB << OUT_LINE_TAB(1) << endl; + + desc << TAB << TC_Common::outfill("obj name") << _objectProxyFactory->getObjectProxy(i)->name() << endl; + const vector &adapters = _objectProxyFactory->getObjectProxy(i)->getAdapters(); + + for(auto adapter : adapters) + { + desc << TAB << TAB << OUT_LINE_TAB(2) << endl; + + desc << TAB << TAB << TC_Common::outfill("adapter") << adapter->endpoint().getEndpoint().toString() << endl; + desc << TAB << TAB << TC_Common::outfill("recv size") << adapter->trans()->getRecvBuffer()->getBufferLength() << endl; + desc << TAB << TAB << TC_Common::outfill("send size") << adapter->trans()->getSendBuffer()->getBufferLength() << endl; + } + } + + return desc.str(); +} + +void CommunicatorEpoll::reConnect() +{ + int64_t iNow = TNOWMS; + + while(!_reconnect.empty()) + { + auto it = _reconnect.begin(); + + if(it->first > iNow) + { + return; + } + + it->second->reconnect(); + + _reconnect.erase(it++); + } } void CommunicatorEpoll::run() @@ -419,6 +473,7 @@ void CommunicatorEpoll::run() //数据上报 doStat(); + reConnect(); } catch (exception& e) { diff --git a/servant/libservant/ObjectProxy.cpp b/servant/libservant/ObjectProxy.cpp index a436147..691e8d3 100755 --- a/servant/libservant/ObjectProxy.cpp +++ b/servant/libservant/ObjectProxy.cpp @@ -67,16 +67,11 @@ ObjectProxy::~ObjectProxy() void ObjectProxy::initialize() { } -// -//ServantProxy * ObjectProxy::getServantProxy() -//{ -// return _pServantProxy; -//} -// -//void ObjectProxy::setServantProxy(ServantProxy * pServantProxy) -//{ -// _pServantProxy = pServantProxy; -//} + +const vector & ObjectProxy::getAdapters() +{ + return _endpointManger->getAdapters(); +} int ObjectProxy::loadLocator() { diff --git a/servant/libservant/ServantProxy.cpp b/servant/libservant/ServantProxy.cpp index 2da75ac..ace42f6 100644 --- a/servant/libservant/ServantProxy.cpp +++ b/servant/libservant/ServantProxy.cpp @@ -163,7 +163,7 @@ ServantProxyCallback::ServantProxyCallback() int HttpServantProxyCallback::onDispatch(ReqMessagePtr msg) { - if (msg->response->iRet != tars::TARSSERVERSUCCESS) + if (msg->response->iRet != TARSSERVERSUCCESS) { return onDispatchException(msg->request, *msg->response); } @@ -288,6 +288,13 @@ string ServantProxy::tars_name() const return "NULL"; } +void ServantProxy::tars_reconnect(int second) +{ + if (_objectProxyNum >= 1 && (*_objectProxy != NULL)) + { + (*_objectProxy)->reconnect(second); + } +} TC_Endpoint ServantProxy::tars_invoke_endpoint() { @@ -406,9 +413,9 @@ void ServantProxy::tars_ping() map s; - tars::TarsOutputStream os; + TarsOutputStream os; - tars_invoke(tars::TARSNORMAL, "tars_ping", os, m, s); + tars_invoke(TARSNORMAL, "tars_ping", os, m, s); } @@ -417,9 +424,9 @@ void ServantProxy::tars_async_ping() map m; map s; - tars::TarsOutputStream os; + TarsOutputStream os; - tars_invoke_async(tars::TARSONEWAY, "tars_ping", os, m, s, NULL); + tars_invoke_async(TARSONEWAY, "tars_ping", os, m, s, NULL); } ServantProxy* ServantProxy::tars_hash(int64_t key) @@ -591,7 +598,7 @@ void ServantProxy::invoke(ReqMessage * msg, bool bCoroAsync) //如果是按set规则调用 if (pObjProxy && pObjProxy->isInvokeBySet()) { - SET_MSG_TYPE(msg->request.iMessageType, tars::TARSMESSAGETYPESETNAME); + SET_MSG_TYPE(msg->request.iMessageType, TARSMESSAGETYPESETNAME); msg->request.status[ServantProxy::STATUS_SETNAME_VALUE] = pObjProxy->getInvokeSetName(); TLOGTARS("[TARS][ServantProxy::invoke, " << msg->request.sServantName << ", invoke with set,"<getInvokeSetName()<<"]" << endl); @@ -742,7 +749,7 @@ void ServantProxy::invoke(ReqMessage * msg, bool bCoroAsync) ////////////////////////////////////////////////////////////////// void ServantProxy::tars_invoke_async(char cPacketType, const string &sFuncName, - tars::TarsOutputStream &buf, + TarsOutputStream &buf, const map& context, const map& status, const ServantProxyCallbackPtr& callback, @@ -777,7 +784,7 @@ void ServantProxy::tars_invoke_async(char cPacketType, shared_ptr ServantProxy::tars_invoke(char cPacketType, const string& sFuncName, - tars::TarsOutputStream& buf, + TarsOutputStream& buf, const map& context, const map& status) // ResponsePacket& rsp) @@ -964,7 +971,7 @@ void ServantProxy::checkDye(RequestPacket& req) assert(pSptd != NULL); if(pSptd && pSptd->_dyeing) { - SET_MSG_TYPE(req.iMessageType, tars::TARSMESSAGETYPEDYED); + SET_MSG_TYPE(req.iMessageType, TARSMESSAGETYPEDYED); req.status[ServantProxy::STATUS_DYED_KEY] = pSptd->_dyeingKey; } diff --git a/servant/libservant/StatReport.cpp b/servant/libservant/StatReport.cpp index e67ff40..a30a023 100755 --- a/servant/libservant/StatReport.cpp +++ b/servant/libservant/StatReport.cpp @@ -318,17 +318,19 @@ void StatReport::report(const string& strModuleName, } head.interfaceName = trimAndLimitStr(strInterfaceName, MAX_MASTER_NAME_LEN); + head.slavePort = iPort; + head.returnValue = iReturnValue; - + //包体信息. - if(eResult == STAT_SUCC) + if (eResult == STAT_SUCC) { body.count = 1; body.totalRspTime = body.minRspTime = body.maxRspTime = iSptime; } - else if(eResult == STAT_TIMEOUT) + else if (eResult == STAT_TIMEOUT) { body.timeoutCount = 1; } @@ -381,23 +383,24 @@ void StatReport::report(const string& strMasterName, submit(head, body, true); } - -string StatReport::sampleUnid() -{ - static atomic g_id(rand()); - - char s[14] = {0}; - time_t t = TNOW; - int ip = inet_addr(_ip.c_str()); - int thread = ++g_id; - static unsigned short n = 0; - ++n; - memcpy( s, &ip, 4 ); - memcpy( s + 4, &t, 4); - memcpy( s + 8, &thread, 4); - memcpy( s + 12, &n, 2 ); - return TC_Common::bin2str(string(s,14)); -} +// +//string StatReport::sampleUnid() +//{ +// +// static atomic g_id(rand()); +// +// char s[14] = { 0 }; +// time_t t = TNOW; +// int ip = inet_addr(_ip.c_str()); +// int thread = ++g_id; +// static unsigned short n = 0; +// ++n; +// memcpy(s, &ip, 4); +// memcpy(s + 4, &t, 4); +// memcpy(s + 8, &thread, 4); +// memcpy(s + 12, &n, 2); +// return TC_Common::bin2str(string(s, 14)); +//} void StatReport::submit( StatMicMsgHead& head, StatMicMsgBody& body,bool bFromClient ) { @@ -430,13 +433,23 @@ void StatReport::submit( StatMicMsgHead& head, StatMicMsgBody& body,bool bFromCl } } -void StatReport::doSample(const string& strSlaveName, - const string& strInterfaceName, - const string& strSlaveIp, - map &status) +size_t StatReport::getQueueSize(size_t epollIndex) { + if(epollIndex >= _statMsg.size()) + { + return 0; + } + + return _statMsg[epollIndex]->size(); } +//void StatReport::doSample(const string& strSlaveName, +// const string& strInterfaceName, +// const string& strSlaveIp, +// map& status) +//{ +//} + int StatReport::reportMicMsg(MapStatMicMsg& msg,bool bFromClient) { if (msg.empty()) return 0; diff --git a/servant/libservant/Transceiver.cpp b/servant/libservant/Transceiver.cpp index 9ce715a..9aafa40 100755 --- a/servant/libservant/Transceiver.cpp +++ b/servant/libservant/Transceiver.cpp @@ -70,8 +70,6 @@ bool Transceiver::isSSL() const void Transceiver::reconnect() { - close(); - connect(); } @@ -157,6 +155,11 @@ void Transceiver::setConnected() TLOGTARS("[TARS][tcp setConnected, " << _adapterProxy->getObjProxy()->name() << ",fd:" << _fd << "]" << endl); onConnect(); + + if(_adapterProxy->getObjProxy()->getPushCallback()) + { + _adapterProxy->getObjProxy()->getPushCallback()->onConnect(_ep.getEndpoint()); + } } void Transceiver::onConnect() @@ -401,11 +404,9 @@ bool Transceiver::sendAuthData(const BasicAuthInfo& info) void Transceiver::close() { if(!isValid()) return; -// if(_adapterProxy->getObjProxy()->getPushCallback()) -// { -// _adapterProxy->getObjProxy()->getPushCallback()->onClose(); -// } -#if TARS_SSL + + +#if TAF_SSL if (_openssl) { _openssl->release(); @@ -427,7 +428,21 @@ void Transceiver::close() _authState = AUTH_INIT; - TLOGTARS("[TARS][trans close:"<< _adapterProxy->getObjProxy()->name()<< "," << _ep.desc() << "]" << endl); + if(_adapterProxy->getObjProxy()->getPushCallback()) + { + _adapterProxy->getObjProxy()->getPushCallback()->onClose(); + } + + int second = _adapterProxy->getObjProxy()->reconnect(); + + if(second > 0) { + _adapterProxy->getObjProxy()->getCommunicatorEpoll()->reConnect(TNOWMS + second * 1000, this); + TLOGERROR("[TAF][trans close:" << _adapterProxy->getObjProxy()->name() << "," << _ep.desc() << ", reconnect:" << second << "]" << endl); + } +// else +// { +// TLOGERROR("[TAF][trans close:" << _adapterProxy->getObjProxy()->name() << "," << _ep.desc() << "]" << endl); +// } } int Transceiver::doRequest() @@ -998,7 +1013,8 @@ int UdpTransceiver::send(const void* buf, uint32_t len, uint32_t flag) { if(!isValid()) return -1; - int iRet=::sendto(_fd, (const char*)buf, len, flag, (struct sockaddr*) &(_ep.addr()), sizeof(sockaddr)); + socklen_t addrlen = _ep.isIPv6() ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); + int iRet=::sendto(_fd, (const char*)buf, len, flag, _ep.addrPtr(), addrlen); if (iRet<0) { diff --git a/servant/servant/Application.h b/servant/servant/Application.h index 00cf529..6f64f22 100644 --- a/servant/servant/Application.h +++ b/servant/servant/Application.h @@ -40,7 +40,12 @@ namespace tars { -////////////////////////////////////////////////////////////////////// +//#ifndef GEN_PYTHON_MASK + +#define OUT_LINE (TC_Common::outfill("", '-', 80)) +#define OUT_LINE_LONG (TC_Common::outfill("", '=', 80)) +#define OUT_LINE_TAB(x) (TC_Common::outfill("", '-', 80 - 4*x)) + /** * 以下定义配置框架支持的命令 */ @@ -56,7 +61,7 @@ namespace tars #define TARS_CMD_SET_DAYLOG_LEVEL "tars.enabledaylog" //设置按天日志是否输出: tars.enabledaylog [remote|local]|[logname]|[true|false] #define TARS_CMD_CLOSE_CORE "tars.closecore" //设置服务的core limit: tars.setlimit [yes|no] #define TARS_CMD_RELOAD_LOCATOR "tars.reloadlocator" //重新加载locator的配置信息 - +#define TARS_CMD_RESOURCE "tars.resource" //get resource ////////////////////////////////////////////////////////////////////// /** * 通知信息给notify服务, 展示在页面上 @@ -127,6 +132,8 @@ struct ServerConfig static int NetThread; //servernet thread static bool ManualListen; //是否启用手工端口监听 static bool MergeNetImp; //网络线程和IMP线程合并(以网络线程个数为准) + static int BackPacketLimit; //回包积压检查 + static int BackPacketMin; //回包速度检查 #if TARS_SSL static std::string CA; static std::string Cert; @@ -369,6 +376,14 @@ protected: */ bool cmdReloadLocator(const string& command, const string& params, string& result); + /* + * view server resource + * @param command + * @param params + * @param result + */ + bool cmdViewResource(const string& command, const string& params, string& result); + protected: /** diff --git a/servant/servant/Communicator.h b/servant/servant/Communicator.h index 026f148..efa0253 100644 --- a/servant/servant/Communicator.h +++ b/servant/servant/Communicator.h @@ -240,6 +240,12 @@ public: */ int64_t getMinTimeout() { return _minTimeout; } + /** + * get resource info + * @return + */ + string getResouresInfo(); + protected: /** * 初始化 diff --git a/servant/servant/CommunicatorEpoll.h b/servant/servant/CommunicatorEpoll.h index d79d94c..bfc5f7f 100644 --- a/servant/servant/CommunicatorEpoll.h +++ b/servant/servant/CommunicatorEpoll.h @@ -180,6 +180,18 @@ public: */ void pushAsyncThreadQueue(ReqMessage * msg); + /** + * set reconnect + * @param time + */ + void reConnect(int64_t ms, Transceiver*); + + /** + * communicator resource desc + * @return + */ + string getResouresInfo(); + protected: /** * 处理函数 @@ -213,6 +225,11 @@ protected: */ void doStat(); + /** + * reconnect + */ + void reConnect(); + protected: /* * 通信器 @@ -261,6 +278,12 @@ protected: * 超时的检查时间间隔 */ int64_t _timeoutCheckInterval; + + /** + * auto reconnect Transceiver + */ + unordered_map _reconnect; + }; ///////////////////////////////////////////////////////////////////////////////////// diff --git a/servant/servant/EndpointInfo.h b/servant/servant/EndpointInfo.h index e03380a..9649567 100755 --- a/servant/servant/EndpointInfo.h +++ b/servant/servant/EndpointInfo.h @@ -54,11 +54,16 @@ public: EndpointInfo(const string& host, uint16_t port, TC_Endpoint::EType type, int32_t grid, const string & setDivision, int qos, int weight = -1, unsigned int weighttype = 0, int authType = 0); /** - * 地址的字符串描述,不带set信息 - * - * @return string + * get endpoint + * @return */ - const string& descNoSetInfo() const; + const TC_Endpoint &getEndpoint() const { return _ep; } +// /** +// * 地址的字符串描述,不带set信息 +// * +// * @return string +// */ +// const string& descNoSetInfo() const; /** * 地址的字符串描述 @@ -70,15 +75,15 @@ public: return _desc; } - /** - * 比较的地址的字符串描述 - * - * @return string - */ - const string & compareDesc() const - { - return _cmpDesc; - } +// /** +// * 比较的地址的字符串描述 +// * +// * @return string +// */ +// const string & compareDesc() const +// { +// return _cmpDesc; +// } /** * 详细地址字符串描述 @@ -181,13 +186,13 @@ public: */ bool operator == (const EndpointInfo& r) const; - /** - *等于,set信息不参与比较 - *@param r - * - *@return bool - */ - bool equalNoSetInfo(const EndpointInfo& r) const; +// /** +// *等于,set信息不参与比较 +// *@param r +// * +// *@return bool +// */ +// bool equalNoSetInfo(const EndpointInfo& r) const; /** * 小于 diff --git a/servant/servant/ObjectProxy.h b/servant/servant/ObjectProxy.h index 5aa7738..0a9502e 100644 --- a/servant/servant/ObjectProxy.h +++ b/servant/servant/ObjectProxy.h @@ -132,14 +132,14 @@ public: */ void doTimeout(); - /** - * Obj的超时队列的长度 - */ - size_t timeoutQSize() - { - return _reqTimeoutQueue.size(); - } - +// /** +// * Obj的超时队列的长度 +// */ +// size_t timeoutQSize() +// { +// return _reqTimeoutQueue.size(); +// } +// /** * 获取CommunicatorEpoll* */ @@ -158,6 +158,24 @@ public: } /** + * reconnect + * @param second + */ + inline void reconnect(int second) + { + _reConnectSecond = second; + } + + /** + * reconnect + * @param second + */ + inline int reconnect() + { + return _reConnectSecond; + } + + /** * 判断此obj是否走按set规则调用流程,如果是直连方式,即使服务端是启用set的,也不认为是按set规则调用的 */ bool isInvokeBySet() const @@ -215,6 +233,12 @@ public: _servantProxy = pServantProxy; } + /** + * get all adapter proxy + * @return + */ + const vector & getAdapters(); + protected: /** @@ -259,6 +283,11 @@ private: */ int _conTimeout; + /** + * reconnect, 0: not reconnect + */ + int _reConnectSecond = 0; + /* * 超时控制策略信息 */ diff --git a/servant/servant/ServantProxy.h b/servant/servant/ServantProxy.h index 800c941..bb0d932 100644 --- a/servant/servant/ServantProxy.h +++ b/servant/servant/ServantProxy.h @@ -303,6 +303,16 @@ public: */ virtual int onDispatch(ReqMessagePtr ptr) = 0; + /** + * 连接关闭掉了(只对PUSH callback生效) + */ + virtual void onClose(){}; + + /** + * 连接已建立(只对PUSH callback生效) + */ + virtual void onConnect(const TC_Endpoint &ep){}; + protected: /** @@ -499,6 +509,12 @@ public: */ void tars_connect_timeout(int conTimeout); + /** + * set auto reconnect time + * @return int, second + */ + void tars_reconnect(int second); + /** * 获取所属的Object名称 * @return string diff --git a/servant/servant/StatReport.h b/servant/servant/StatReport.h index 9cdb5b7..171ebf3 100644 --- a/servant/servant/StatReport.h +++ b/servant/servant/StatReport.h @@ -219,17 +219,17 @@ public: */ StatFPrx getStatPrx() {return _statPrx; } - /* - * 采样 - */ - void doSample(const string& strSlaveName, - const string& strInterfaceName, - const string& strSlaveIp, - map &status); - /* - * 采样id - */ - string sampleUnid(); +// /* +// * 采样 +// */ +// void doSample(const string& strSlaveName, +// const string& strInterfaceName, +// const string& strSlaveIp, +// map &status); +// /* +// * 采样id +// */ +// string sampleUnid(); /** * 增加关注时间点. 调用方式addStatInterv(5) @@ -306,21 +306,27 @@ private: */ int reportPropMsg(); - /** - * 上报多维度属性信息 Prop = property - * @return int - */ - int reportPropPlusMsg(); +// /** +// * 上报多维度属性信息 Prop = property +// * @return int +// */ +// int reportPropPlusMsg(); /** * stat 采样 */ int reportSampleMsg(); - //合并两个MicMsg void addMicMsg(MapStatMicMsg & old,MapStatMicMsg & add); + /** + * get queue info + * @return + */ + size_t getQueueSize(size_t epollIndex); + + friend class CommunicatorEpoll; private: time_t _time; diff --git a/tools/tarsparse/tars.lex.cpp b/tools/tarsparse/tars.lex.cpp index 8e54b57..36dbbf3 100644 --- a/tools/tarsparse/tars.lex.cpp +++ b/tools/tarsparse/tars.lex.cpp @@ -9,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 +#define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -47,6 +47,7 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -54,6 +55,7 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -84,8 +86,6 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! C99 */ - #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -176,7 +176,7 @@ extern FILE *yyin, *yyout; */ #define YY_LESS_LINENO(n) \ do { \ - int yyl;\ + yy_size_t yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ @@ -369,7 +369,7 @@ static void yy_fatal_error (yyconst char msg[] ); */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; @@ -513,7 +513,7 @@ int yy_flex_debug = 0; #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 1 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" /** * Tencent is pleased to support the open source community by making Tars available. * @@ -529,7 +529,7 @@ char *yytext; * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ -#line 20 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 20 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" #include #include #include @@ -649,7 +649,7 @@ static int input (void ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -660,7 +660,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + yy_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -742,7 +742,7 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 67 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 67 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" #line 749 "tars.lex.cpp" @@ -840,12 +840,12 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 69 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 69 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { BEGIN(INCL); } YY_BREAK case 2: YY_RULE_SETUP -#line 71 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 71 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { if ( include_file_stack_ptr >= MAX_INCLUDE_DEPTH ) { @@ -878,7 +878,7 @@ YY_RULE_SETUP YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INCL): -#line 101 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 101 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { --include_file_stack_ptr; if ( include_file_stack_ptr < 0 ) @@ -897,14 +897,14 @@ case YY_STATE_EOF(INCL): YY_BREAK case 3: YY_RULE_SETUP -#line 117 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 117 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { return TARS_SCOPE_DELIMITER; } YY_BREAK case 4: YY_RULE_SETUP -#line 121 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 121 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { // C++ comment bool e = false; @@ -925,7 +925,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 139 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 139 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { // C comment bool e = false; @@ -976,7 +976,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 187 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 187 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { StringGrammarPtr ident = new StringGrammar; ident->v = yytext; @@ -987,7 +987,7 @@ YY_RULE_SETUP case 7: /* rule 7 can match eol */ YY_RULE_SETUP -#line 194 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 194 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { StringGrammarPtr ident = new StringGrammar; ident->v = yytext; @@ -1000,7 +1000,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 204 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 204 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { StringGrammarPtr str = new StringGrammar; bool e = false; @@ -1115,7 +1115,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 316 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 316 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { errno = 0; IntergerGrammarPtr ptr = new IntergerGrammar; @@ -1140,7 +1140,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 338 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 338 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { errno = 0; FloatGrammarPtr ptr = new FloatGrammar; @@ -1175,7 +1175,7 @@ YY_RULE_SETUP case 11: /* rule 11 can match eol */ YY_RULE_SETUP -#line 369 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 369 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { if(yytext[0] == '\n') { @@ -1185,7 +1185,7 @@ YY_RULE_SETUP YY_BREAK case 12: YY_RULE_SETUP -#line 376 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 376 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" { if(yytext[0] < 32 || yytext[0] > 126) { @@ -1204,7 +1204,7 @@ YY_RULE_SETUP YY_BREAK case 13: YY_RULE_SETUP -#line 392 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 392 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" ECHO; YY_BREAK #line 1211 "tars.lex.cpp" @@ -1398,7 +1398,7 @@ static int yy_get_next_buffer (void) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); @@ -1531,7 +1531,7 @@ static int yy_get_next_buffer (void) yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 51); - return yy_is_jam ? 0 : yy_current_state; + return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) @@ -1623,7 +1623,7 @@ static int yy_get_next_buffer (void) case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) - return EOF; + return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; @@ -1764,6 +1764,10 @@ static void yy_load_buffer_state (void) yyfree((void *) b ); } +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. @@ -1968,8 +1972,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ @@ -1977,8 +1981,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len { YY_BUFFER_STATE b; char *buf; - yy_size_t n; - yy_size_t i; + yy_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2211,7 +2214,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 392 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.l" +#line 392 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.l" diff --git a/tools/tarsparse/tars.tab.cpp b/tools/tarsparse/tars.tab.cpp index 6fe2376..64378e0 100644 --- a/tools/tarsparse/tars.tab.cpp +++ b/tools/tarsparse/tars.tab.cpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.2.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,11 +40,14 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.2.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -61,8 +64,8 @@ -/* Copy the first part of user declarations. */ -#line 17 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:339 */ +/* First part of user prologue. */ +#line 17 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:338 */ #include #include @@ -76,13 +79,16 @@ using namespace std; #define YYDEBUG 1 #define YYINITDEPTH 10000 -#line 80 "tars.tab.cpp" /* yacc.c:339 */ - +#line 83 "tars.tab.cpp" /* yacc.c:338 */ # ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif # else -# define YY_NULLPTR 0 +# define YY_NULLPTR ((void*)0) # endif # endif @@ -159,9 +165,7 @@ int yyparse (void); #endif /* !YY_YY_TARS_TAB_HPP_INCLUDED */ -/* Copy the second part of user declarations. */ -#line 165 "tars.tab.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -182,13 +186,13 @@ typedef signed char yytype_int8; #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif #ifndef YYSIZE_T @@ -200,7 +204,7 @@ typedef short int yytype_int16; # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else -# define YYSIZE_T unsigned int +# define YYSIZE_T unsigned # endif #endif @@ -236,15 +240,6 @@ typedef short int yytype_int16; # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -252,7 +247,7 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ @@ -420,7 +415,7 @@ union yyalloc #define YYMAXUTOK 288 #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ @@ -856,37 +851,37 @@ do { \ } while (0) -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { - FILE *yyo = yyoutput; - YYUSE (yyo); + FILE *yyoutput = yyo; + YYUSE (yyoutput); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); + YYPRINT (yyo, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep) { - YYFPRINTF (yyoutput, "%s %s (", + YYFPRINTF (yyo, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); + yy_symbol_value_print (yyo, yytype, yyvaluep); + YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. @@ -920,7 +915,7 @@ do { \ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { - unsigned long int yylno = yyrline[yyrule]; + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", @@ -1053,7 +1048,7 @@ yytnamerr (char *yyres, const char *yystr) if (! yyres) return yystrlen (yystr); - return yystpcpy (yyres, yystr) - yyres; + return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres); } # endif @@ -1146,6 +1141,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1294,12 +1290,12 @@ yyparse (void) yyssp++; yysetstate: - *yyssp = yystate; + *yyssp = (yytype_int16) yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1); #ifdef yyoverflow { @@ -1317,7 +1313,6 @@ yyparse (void) &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); - yyss = yyss1; yyvs = yyvs1; } @@ -1351,7 +1346,7 @@ yyparse (void) yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; @@ -1462,92 +1457,92 @@ yyreduce: switch (yyn) { case 3: -#line 75 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 75 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1469 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1464 "tars.tab.cpp" /* yacc.c:1660 */ break; case 5: -#line 79 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 79 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { yyerrok; } -#line 1477 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1472 "tars.tab.cpp" /* yacc.c:1660 */ break; case 7: -#line 84 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 84 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("`;' missing after definition"); } -#line 1485 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1480 "tars.tab.cpp" /* yacc.c:1660 */ break; case 8: -#line 88 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 88 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1492 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1487 "tars.tab.cpp" /* yacc.c:1660 */ break; case 9: -#line 96 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 96 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { assert((yyvsp[0]) == 0 || NamespacePtr::dynamicCast((yyvsp[0]))); } -#line 1500 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1495 "tars.tab.cpp" /* yacc.c:1660 */ break; case 10: -#line 100 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 100 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { assert((yyvsp[0]) == 0 || InterfacePtr::dynamicCast((yyvsp[0]))); } -#line 1508 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1503 "tars.tab.cpp" /* yacc.c:1660 */ break; case 11: -#line 104 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 104 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { assert((yyvsp[0]) == 0 || StructPtr::dynamicCast((yyvsp[0]))); } -#line 1516 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1511 "tars.tab.cpp" /* yacc.c:1660 */ break; case 12: -#line 108 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 108 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1523 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1518 "tars.tab.cpp" /* yacc.c:1660 */ break; case 13: -#line 111 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 111 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { assert((yyvsp[0]) == 0 || EnumPtr::dynamicCast((yyvsp[0]))); } -#line 1531 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1526 "tars.tab.cpp" /* yacc.c:1660 */ break; case 14: -#line 115 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 115 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { assert((yyvsp[0]) == 0 || ConstPtr::dynamicCast((yyvsp[0]))); } -#line 1539 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1534 "tars.tab.cpp" /* yacc.c:1660 */ break; case 15: -#line 124 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 124 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = (yyvsp[0]); } -#line 1547 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1542 "tars.tab.cpp" /* yacc.c:1660 */ break; case 16: -#line 128 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 128 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { if((yyvsp[-2])) { @@ -1561,11 +1556,11 @@ yyreduce: (yyval) = (yyvsp[-3]); } -#line 1565 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1560 "tars.tab.cpp" /* yacc.c:1660 */ break; case 17: -#line 147 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 147 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { NamespacePtr c = NamespacePtr::dynamicCast(g_parse->currentContainer()); if(!c) @@ -1578,36 +1573,36 @@ yyreduce: (yyval) = e; } -#line 1582 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1577 "tars.tab.cpp" /* yacc.c:1660 */ break; case 18: -#line 160 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 160 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); g_parse->error("keyword `" + ident->v + "' cannot be used as enumeration name"); (yyval) = (yyvsp[0]); } -#line 1592 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1587 "tars.tab.cpp" /* yacc.c:1660 */ break; case 19: -#line 171 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 171 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = (yyvsp[-1]); } -#line 1600 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1595 "tars.tab.cpp" /* yacc.c:1660 */ break; case 20: -#line 175 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 175 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1607 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1602 "tars.tab.cpp" /* yacc.c:1660 */ break; case 21: -#line 183 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 183 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = TypePtr::dynamicCast(g_parse->createBuiltin(Builtin::KindLong)); StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); @@ -1618,20 +1613,20 @@ yyreduce: e->addMember(tPtr); (yyval) = e; } -#line 1622 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1617 "tars.tab.cpp" /* yacc.c:1660 */ break; case 22: -#line 194 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 194 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); g_parse->error("keyword `" + ident->v + "' cannot be used as enumerator"); } -#line 1631 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1626 "tars.tab.cpp" /* yacc.c:1660 */ break; case 23: -#line 199 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 199 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = TypePtr::dynamicCast(g_parse->createBuiltin(Builtin::KindLong)); StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-2])); @@ -1644,18 +1639,18 @@ yyreduce: e->addMember(tPtr); (yyval) = e; } -#line 1648 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1643 "tars.tab.cpp" /* yacc.c:1660 */ break; case 24: -#line 212 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 212 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1655 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1650 "tars.tab.cpp" /* yacc.c:1660 */ break; case 25: -#line 220 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 220 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); ContainerPtr c = g_parse->currentContainer(); @@ -1670,11 +1665,11 @@ yyreduce: (yyval) = 0; } } -#line 1674 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1669 "tars.tab.cpp" /* yacc.c:1660 */ break; case 26: -#line 235 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 235 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { if((yyvsp[-3])) { @@ -1686,11 +1681,11 @@ yyreduce: (yyval) = 0; } } -#line 1690 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1685 "tars.tab.cpp" /* yacc.c:1660 */ break; case 27: -#line 253 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 253 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-1])); StructPtr sp = StructPtr::dynamicCast(g_parse->findUserType(ident->v)); @@ -1701,18 +1696,18 @@ yyreduce: g_parse->setKeyStruct(sp); } -#line 1705 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1700 "tars.tab.cpp" /* yacc.c:1660 */ break; case 28: -#line 264 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 264 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1712 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1707 "tars.tab.cpp" /* yacc.c:1660 */ break; case 29: -#line 272 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 272 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); StructPtr np = g_parse->getKeyStruct(); @@ -1725,11 +1720,11 @@ yyreduce: (yyval) = 0; } } -#line 1729 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1724 "tars.tab.cpp" /* yacc.c:1660 */ break; case 30: -#line 285 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 285 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); StructPtr np = g_parse->getKeyStruct(); @@ -1742,11 +1737,11 @@ yyreduce: (yyval) = 0; } } -#line 1746 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1741 "tars.tab.cpp" /* yacc.c:1660 */ break; case 31: -#line 304 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 304 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); @@ -1763,11 +1758,11 @@ yyreduce: (yyval) = 0; } } -#line 1767 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1762 "tars.tab.cpp" /* yacc.c:1660 */ break; case 32: -#line 321 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 321 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { if((yyvsp[-3])) { @@ -1779,58 +1774,58 @@ yyreduce: (yyval) = 0; } } -#line 1783 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1778 "tars.tab.cpp" /* yacc.c:1660 */ break; case 33: -#line 338 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 338 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = (yyvsp[0]); } -#line 1791 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1786 "tars.tab.cpp" /* yacc.c:1660 */ break; case 34: -#line 342 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 342 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); g_parse->error("keyword `" + ident->v + "' cannot be used as interface name"); (yyval) = (yyvsp[0]); } -#line 1801 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1796 "tars.tab.cpp" /* yacc.c:1660 */ break; case 35: -#line 353 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 353 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1808 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1803 "tars.tab.cpp" /* yacc.c:1660 */ break; case 36: -#line 356 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 356 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1815 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1810 "tars.tab.cpp" /* yacc.c:1660 */ break; case 37: -#line 359 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 359 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("`;' missing after definition"); } -#line 1823 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1818 "tars.tab.cpp" /* yacc.c:1660 */ break; case 38: -#line 363 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 363 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1830 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1825 "tars.tab.cpp" /* yacc.c:1660 */ break; case 40: -#line 377 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 377 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { if((yyvsp[-2])) { @@ -1842,11 +1837,11 @@ yyreduce: (yyval) = 0; } } -#line 1846 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1841 "tars.tab.cpp" /* yacc.c:1660 */ break; case 41: -#line 394 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 394 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr returnType = TypePtr::dynamicCast((yyvsp[-1])); StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); @@ -1870,26 +1865,26 @@ yyreduce: (yyval) = 0; } } -#line 1874 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1869 "tars.tab.cpp" /* yacc.c:1660 */ break; case 43: -#line 424 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 424 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = 0; } -#line 1882 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1877 "tars.tab.cpp" /* yacc.c:1660 */ break; case 44: -#line 434 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 434 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 1889 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1884 "tars.tab.cpp" /* yacc.c:1660 */ break; case 45: -#line 437 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 437 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); @@ -1900,11 +1895,11 @@ yyreduce: op->createParamDecl(tsp, false, false); } } -#line 1904 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1899 "tars.tab.cpp" /* yacc.c:1660 */ break; case 46: -#line 448 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 448 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); @@ -1915,11 +1910,11 @@ yyreduce: op->createParamDecl(tsp, false, false); } } -#line 1919 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1914 "tars.tab.cpp" /* yacc.c:1660 */ break; case 47: -#line 459 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 459 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { BoolGrammarPtr isOutParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); @@ -1931,11 +1926,11 @@ yyreduce: op->createParamDecl(tsp, isOutParam->v, false); } } -#line 1935 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1930 "tars.tab.cpp" /* yacc.c:1660 */ break; case 48: -#line 471 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 471 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { BoolGrammarPtr isOutParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); @@ -1947,11 +1942,11 @@ yyreduce: op->createParamDecl(tsp, isOutParam->v, false); } } -#line 1951 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1946 "tars.tab.cpp" /* yacc.c:1660 */ break; case 49: -#line 483 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 483 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { BoolGrammarPtr isRouteKeyParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); @@ -1963,11 +1958,11 @@ yyreduce: op->createParamDecl(tsp, false, isRouteKeyParam->v); } } -#line 1967 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1962 "tars.tab.cpp" /* yacc.c:1660 */ break; case 50: -#line 495 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 495 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { BoolGrammarPtr isRouteKeyParam = BoolGrammarPtr::dynamicCast((yyvsp[-1])); TypeIdPtr tsp = TypeIdPtr::dynamicCast((yyvsp[0])); @@ -1979,47 +1974,47 @@ yyreduce: op->createParamDecl(tsp, false, isRouteKeyParam->v); } } -#line 1983 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1978 "tars.tab.cpp" /* yacc.c:1660 */ break; case 51: -#line 507 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 507 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("'out' must be defined with a type"); } -#line 1991 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1986 "tars.tab.cpp" /* yacc.c:1660 */ break; case 52: -#line 511 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 511 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("'routekey' must be defined with a type"); } -#line 1999 "tars.tab.cpp" /* yacc.c:1646 */ +#line 1994 "tars.tab.cpp" /* yacc.c:1660 */ break; case 53: -#line 520 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 520 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { BoolGrammarPtr routekey = new BoolGrammar; routekey->v = true; (yyval) = GrammarBasePtr::dynamicCast(routekey); } -#line 2009 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2004 "tars.tab.cpp" /* yacc.c:1660 */ break; case 54: -#line 531 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 531 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { BoolGrammarPtr out = new BoolGrammar; out->v = true; (yyval) = GrammarBasePtr::dynamicCast(out); } -#line 2019 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2014 "tars.tab.cpp" /* yacc.c:1660 */ break; case 55: -#line 542 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 542 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); NamespacePtr np = NamespacePtr::dynamicCast(g_parse->currentContainer()); @@ -2041,11 +2036,11 @@ yyreduce: g_parse->error("struct '" + ident->v + "' must definition in namespace"); } } -#line 2045 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2040 "tars.tab.cpp" /* yacc.c:1660 */ break; case 56: -#line 564 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 564 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { if((yyvsp[-3])) { @@ -2060,68 +2055,68 @@ yyreduce: g_parse->error("struct `" + st->getSid() + "' must have at least one member"); } } -#line 2064 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2059 "tars.tab.cpp" /* yacc.c:1660 */ break; case 57: -#line 584 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 584 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = (yyvsp[0]); } -#line 2072 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2067 "tars.tab.cpp" /* yacc.c:1660 */ break; case 58: -#line 588 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 588 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); g_parse->error("keyword `" + ident->v + "' cannot be used as struct name"); } -#line 2082 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2077 "tars.tab.cpp" /* yacc.c:1660 */ break; case 59: -#line 594 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 594 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("abstract declarator '' used as declaration"); } -#line 2090 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2085 "tars.tab.cpp" /* yacc.c:1660 */ break; case 60: -#line 603 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 603 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2098 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2093 "tars.tab.cpp" /* yacc.c:1660 */ break; case 61: -#line 607 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 607 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("';' missing after definition"); } -#line 2106 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2101 "tars.tab.cpp" /* yacc.c:1660 */ break; case 62: -#line 611 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 611 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2113 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2108 "tars.tab.cpp" /* yacc.c:1660 */ break; case 63: -#line 621 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 621 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); } -#line 2121 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2116 "tars.tab.cpp" /* yacc.c:1660 */ break; case 64: -#line 630 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 630 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); if(np) @@ -2139,11 +2134,11 @@ yyreduce: (yyval) = 0; } } -#line 2143 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2138 "tars.tab.cpp" /* yacc.c:1660 */ break; case 65: -#line 648 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 648 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); if(np) @@ -2165,11 +2160,11 @@ yyreduce: (yyval) = 0; } } -#line 2169 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2164 "tars.tab.cpp" /* yacc.c:1660 */ break; case 66: -#line 670 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 670 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); if(np) @@ -2191,11 +2186,11 @@ yyreduce: (yyval) = 0; } } -#line 2195 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2190 "tars.tab.cpp" /* yacc.c:1660 */ break; case 67: -#line 692 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 692 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StructPtr np = StructPtr::dynamicCast(g_parse->currentContainer()); if(np) @@ -2212,43 +2207,43 @@ yyreduce: (yyval) = 0; } } -#line 2216 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2211 "tars.tab.cpp" /* yacc.c:1660 */ break; case 68: -#line 709 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 709 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("struct member need 'tag'"); } -#line 2224 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2219 "tars.tab.cpp" /* yacc.c:1660 */ break; case 69: -#line 713 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 713 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("struct member need 'tag'"); } -#line 2232 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2227 "tars.tab.cpp" /* yacc.c:1660 */ break; case 70: -#line 717 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 717 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("struct member need 'require' or 'optional'"); } -#line 2240 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2235 "tars.tab.cpp" /* yacc.c:1660 */ break; case 71: -#line 721 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 721 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("struct member need 'tag' or 'require' or 'optional'"); } -#line 2248 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2243 "tars.tab.cpp" /* yacc.c:1660 */ break; case 72: -#line 730 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 730 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { IntergerGrammarPtr intVal = IntergerGrammarPtr::dynamicCast((yyvsp[0])); ostringstream sstr; @@ -2258,11 +2253,11 @@ yyreduce: c->v = sstr.str(); (yyval) = c; } -#line 2262 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2257 "tars.tab.cpp" /* yacc.c:1660 */ break; case 73: -#line 740 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 740 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { FloatGrammarPtr floatVal = FloatGrammarPtr::dynamicCast((yyvsp[0])); ostringstream sstr; @@ -2272,11 +2267,11 @@ yyreduce: c->v = sstr.str(); (yyval) = c; } -#line 2276 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2271 "tars.tab.cpp" /* yacc.c:1660 */ break; case 74: -#line 750 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 750 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); ConstGrammarPtr c = new ConstGrammar(); @@ -2284,11 +2279,11 @@ yyreduce: c->v = ident->v; (yyval) = c; } -#line 2288 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2283 "tars.tab.cpp" /* yacc.c:1660 */ break; case 75: -#line 758 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 758 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); ConstGrammarPtr c = new ConstGrammar(); @@ -2296,11 +2291,11 @@ yyreduce: c->v = ident->v; (yyval) = c; } -#line 2300 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2295 "tars.tab.cpp" /* yacc.c:1660 */ break; case 76: -#line 766 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 766 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); ConstGrammarPtr c = new ConstGrammar(); @@ -2308,11 +2303,11 @@ yyreduce: c->v = ident->v; (yyval) = c; } -#line 2312 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2307 "tars.tab.cpp" /* yacc.c:1660 */ break; case 77: -#line 774 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 774 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); @@ -2325,11 +2320,11 @@ yyreduce: c->v = ident->v; (yyval) = c; } -#line 2329 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2324 "tars.tab.cpp" /* yacc.c:1660 */ break; case 78: -#line 787 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 787 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr scoped = StringGrammarPtr::dynamicCast((yyvsp[-2])); @@ -2344,11 +2339,11 @@ yyreduce: c->v = scoped->v + "::" + ident->v; (yyval) = c; } -#line 2348 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2343 "tars.tab.cpp" /* yacc.c:1660 */ break; case 79: -#line 807 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 807 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { NamespacePtr np = NamespacePtr::dynamicCast(g_parse->currentContainer()); if(!np) @@ -2361,11 +2356,11 @@ yyreduce: ConstPtr cPtr = np->createConst(t, c); (yyval) = cPtr; } -#line 2365 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2360 "tars.tab.cpp" /* yacc.c:1660 */ break; case 80: -#line 825 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 825 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = TypePtr::dynamicCast((yyvsp[-1])); StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); @@ -2374,11 +2369,11 @@ yyreduce: (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); } -#line 2378 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2373 "tars.tab.cpp" /* yacc.c:1660 */ break; case 81: -#line 834 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 834 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = g_parse->createVector(TypePtr::dynamicCast((yyvsp[-4]))); IntergerGrammarPtr iPtrSize = IntergerGrammarPtr::dynamicCast((yyvsp[-1])); @@ -2388,11 +2383,11 @@ yyreduce: TypeIdPtr typeIdPtr = new TypeId(type, ident->v); (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); } -#line 2392 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2387 "tars.tab.cpp" /* yacc.c:1660 */ break; case 82: -#line 844 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 844 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = g_parse->createVector(TypePtr::dynamicCast((yyvsp[-2]))); //IntergerGrammarPtr iPtrSize = IntergerGrammarPtr::dynamicCast($4); @@ -2402,11 +2397,11 @@ yyreduce: TypeIdPtr typeIdPtr = new TypeId(type, ident->v); (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); } -#line 2406 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2401 "tars.tab.cpp" /* yacc.c:1660 */ break; case 83: -#line 854 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 854 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = TypePtr::dynamicCast((yyvsp[-3])); StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[-2])); @@ -2415,36 +2410,36 @@ yyreduce: g_parse->checkArrayVaid(type,iPtrSize->v); (yyval) = GrammarBasePtr::dynamicCast(typeIdPtr); } -#line 2419 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2414 "tars.tab.cpp" /* yacc.c:1660 */ break; case 84: -#line 863 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 863 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); g_parse->error("keyword `" + ident->v + "' cannot be used as data member name"); } -#line 2428 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2423 "tars.tab.cpp" /* yacc.c:1660 */ break; case 85: -#line 868 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 868 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("missing data member name"); } -#line 2436 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2431 "tars.tab.cpp" /* yacc.c:1660 */ break; case 86: -#line 872 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 872 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("unkown type"); } -#line 2444 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2439 "tars.tab.cpp" /* yacc.c:1660 */ break; case 87: -#line 881 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 881 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { TypePtr type = TypePtr::dynamicCast((yyvsp[-2])); @@ -2453,131 +2448,131 @@ yyreduce: type->setArray(iPtrSize->v); (yyval) = type; } -#line 2457 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2452 "tars.tab.cpp" /* yacc.c:1660 */ break; case 88: -#line 890 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 890 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = (yyvsp[0]); } -#line 2465 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2460 "tars.tab.cpp" /* yacc.c:1660 */ break; case 89: -#line 894 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 894 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("array missing size"); } -#line 2473 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2468 "tars.tab.cpp" /* yacc.c:1660 */ break; case 90: -#line 903 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 903 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindBool); } -#line 2481 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2476 "tars.tab.cpp" /* yacc.c:1660 */ break; case 91: -#line 907 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 907 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindByte); } -#line 2489 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2484 "tars.tab.cpp" /* yacc.c:1660 */ break; case 92: -#line 911 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 911 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindShort,true); } -#line 2497 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2492 "tars.tab.cpp" /* yacc.c:1660 */ break; case 93: -#line 915 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 915 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindShort); } -#line 2505 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2500 "tars.tab.cpp" /* yacc.c:1660 */ break; case 94: -#line 919 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 919 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindInt,true); } -#line 2513 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2508 "tars.tab.cpp" /* yacc.c:1660 */ break; case 95: -#line 923 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 923 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindInt); } -#line 2521 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2516 "tars.tab.cpp" /* yacc.c:1660 */ break; case 96: -#line 927 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 927 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindLong,true); } -#line 2529 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2524 "tars.tab.cpp" /* yacc.c:1660 */ break; case 97: -#line 931 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 931 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindLong); } -#line 2537 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2532 "tars.tab.cpp" /* yacc.c:1660 */ break; case 98: -#line 935 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 935 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindFloat); } -#line 2545 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2540 "tars.tab.cpp" /* yacc.c:1660 */ break; case 99: -#line 939 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 939 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindDouble); } -#line 2553 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2548 "tars.tab.cpp" /* yacc.c:1660 */ break; case 100: -#line 943 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 943 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = g_parse->createBuiltin(Builtin::KindString); } -#line 2561 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2556 "tars.tab.cpp" /* yacc.c:1660 */ break; case 101: -#line 947 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 947 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); } -#line 2569 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2564 "tars.tab.cpp" /* yacc.c:1660 */ break; case 102: -#line 951 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 951 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = GrammarBasePtr::dynamicCast((yyvsp[0])); } -#line 2577 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2572 "tars.tab.cpp" /* yacc.c:1660 */ break; case 103: -#line 955 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 955 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); TypePtr sp = g_parse->findUserType(ident->v); @@ -2590,76 +2585,76 @@ yyreduce: g_parse->error("'" + ident->v + "' undefined!"); } } -#line 2594 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2589 "tars.tab.cpp" /* yacc.c:1660 */ break; case 104: -#line 973 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 973 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = GrammarBasePtr::dynamicCast(g_parse->createVector(TypePtr::dynamicCast((yyvsp[-1])))); } -#line 2602 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2597 "tars.tab.cpp" /* yacc.c:1660 */ break; case 105: -#line 977 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 977 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("vector error"); } -#line 2610 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2605 "tars.tab.cpp" /* yacc.c:1660 */ break; case 106: -#line 981 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 981 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("vector missing '>'"); } -#line 2618 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2613 "tars.tab.cpp" /* yacc.c:1660 */ break; case 107: -#line 985 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 985 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("vector missing type"); } -#line 2626 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2621 "tars.tab.cpp" /* yacc.c:1660 */ break; case 108: -#line 994 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 994 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { (yyval) = GrammarBasePtr::dynamicCast(g_parse->createMap(TypePtr::dynamicCast((yyvsp[-3])), TypePtr::dynamicCast((yyvsp[-1])))); } -#line 2634 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2629 "tars.tab.cpp" /* yacc.c:1660 */ break; case 109: -#line 998 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 998 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { g_parse->error("map error"); } -#line 2642 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2637 "tars.tab.cpp" /* yacc.c:1660 */ break; case 110: -#line 1007 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1007 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2649 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2644 "tars.tab.cpp" /* yacc.c:1660 */ break; case 111: -#line 1010 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1010 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); ident->v = "::" + ident->v; (yyval) = GrammarBasePtr::dynamicCast(ident); } -#line 2659 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2654 "tars.tab.cpp" /* yacc.c:1660 */ break; case 112: -#line 1016 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1016 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { StringGrammarPtr scoped = StringGrammarPtr::dynamicCast((yyvsp[-2])); StringGrammarPtr ident = StringGrammarPtr::dynamicCast((yyvsp[0])); @@ -2667,186 +2662,186 @@ yyreduce: scoped->v += ident->v; (yyval) = GrammarBasePtr::dynamicCast(scoped); } -#line 2671 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2666 "tars.tab.cpp" /* yacc.c:1660 */ break; case 113: -#line 1029 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1029 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2678 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2673 "tars.tab.cpp" /* yacc.c:1660 */ break; case 114: -#line 1032 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1032 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2685 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2680 "tars.tab.cpp" /* yacc.c:1660 */ break; case 115: -#line 1035 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1035 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2692 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2687 "tars.tab.cpp" /* yacc.c:1660 */ break; case 116: -#line 1038 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1038 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2699 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2694 "tars.tab.cpp" /* yacc.c:1660 */ break; case 117: -#line 1041 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1041 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2706 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2701 "tars.tab.cpp" /* yacc.c:1660 */ break; case 118: -#line 1044 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1044 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2713 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2708 "tars.tab.cpp" /* yacc.c:1660 */ break; case 119: -#line 1047 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1047 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2720 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2715 "tars.tab.cpp" /* yacc.c:1660 */ break; case 120: -#line 1050 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1050 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2727 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2722 "tars.tab.cpp" /* yacc.c:1660 */ break; case 121: -#line 1053 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1053 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2734 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2729 "tars.tab.cpp" /* yacc.c:1660 */ break; case 122: -#line 1056 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1056 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2741 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2736 "tars.tab.cpp" /* yacc.c:1660 */ break; case 123: -#line 1059 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1059 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2748 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2743 "tars.tab.cpp" /* yacc.c:1660 */ break; case 124: -#line 1062 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1062 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2755 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2750 "tars.tab.cpp" /* yacc.c:1660 */ break; case 125: -#line 1065 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1065 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2762 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2757 "tars.tab.cpp" /* yacc.c:1660 */ break; case 126: -#line 1068 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1068 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2769 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2764 "tars.tab.cpp" /* yacc.c:1660 */ break; case 127: -#line 1071 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1071 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2776 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2771 "tars.tab.cpp" /* yacc.c:1660 */ break; case 128: -#line 1074 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1074 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2783 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2778 "tars.tab.cpp" /* yacc.c:1660 */ break; case 129: -#line 1077 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1077 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2790 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2785 "tars.tab.cpp" /* yacc.c:1660 */ break; case 130: -#line 1080 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1080 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2797 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2792 "tars.tab.cpp" /* yacc.c:1660 */ break; case 131: -#line 1083 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1083 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2804 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2799 "tars.tab.cpp" /* yacc.c:1660 */ break; case 132: -#line 1086 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1086 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2811 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2806 "tars.tab.cpp" /* yacc.c:1660 */ break; case 133: -#line 1089 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1089 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2818 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2813 "tars.tab.cpp" /* yacc.c:1660 */ break; case 134: -#line 1092 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1092 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2825 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2820 "tars.tab.cpp" /* yacc.c:1660 */ break; case 135: -#line 1095 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1095 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2832 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2827 "tars.tab.cpp" /* yacc.c:1660 */ break; case 136: -#line 1098 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1098 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2839 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2834 "tars.tab.cpp" /* yacc.c:1660 */ break; case 137: -#line 1101 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1646 */ +#line 1101 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1660 */ { } -#line 2846 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2841 "tars.tab.cpp" /* yacc.c:1660 */ break; -#line 2850 "tars.tab.cpp" /* yacc.c:1646 */ +#line 2845 "tars.tab.cpp" /* yacc.c:1660 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2871,14 +2866,13 @@ yyreduce: /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } goto yynewstate; @@ -3074,7 +3068,7 @@ yyreturn: #endif return yyresult; } -#line 1105 "/home/tars/TarsFramework/tarscpp/tools/tarsgrammar/tars.y" /* yacc.c:1906 */ +#line 1105 "/Users/jarod/centos/TarsCpp/tools/tarsgrammar/tars.y" /* yacc.c:1903 */ diff --git a/tools/tarsparse/tars.tab.hpp b/tools/tarsparse/tars.tab.hpp index 547e017..f179ee1 100644 --- a/tools/tarsparse/tars.tab.hpp +++ b/tools/tarsparse/tars.tab.hpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.2.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +30,9 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +/* Undocumented macros, especially those whose name start with YY_, + are private implementation details. Do not rely on them. */ + #ifndef YY_YY_TARS_TAB_HPP_INCLUDED # define YY_YY_TARS_TAB_HPP_INCLUDED /* Debug traces. */ diff --git a/util/include/util/tc_epoll_server.h b/util/include/util/tc_epoll_server.h index 3a46cfd..30509ce 100644 --- a/util/include/util/tc_epoll_server.h +++ b/util/include/util/tc_epoll_server.h @@ -172,18 +172,20 @@ public: typedef TC_CasQueue> send_queue; typedef recv_queue::queue_type recv_queue_type; - //////////////////////////////////////////////////////////////////////////// - /** - * 链接状态 - */ - struct ConnStatus - { - string ip; - int32_t uid; - uint16_t port; - int timeout; - int iLastRefreshTime; - }; + //////////////////////////////////////////////////////////////////////////// + /** + * 链接状态 + */ + struct ConnStatus + { + string ip; + int32_t uid; + uint16_t port; + int timeout; + int iLastRefreshTime; + size_t recvBufferSize; + size_t sendBufferSize; + }; //////////////////////////////////////////////////////////////////////////// /** @@ -642,28 +644,28 @@ public: */ void decreaseNowConnection(); - /** - * 增加当前连接数 - */ - void increaseNowConnection(); + /** + * 增加当前连接数 + */ + void increaseNowConnection(); - /** - * 获取所有链接状态 - * @return ConnStatus - */ - vector getConnStatus(); + /** + * 获取所有链接状态 + * @return ConnStatus + */ + vector getConnStatus(); - /** - * 获取当前连接数 - * @return int - */ - int getNowConnection() const; + /** + * 获取当前连接数 + * @return int + */ + int getNowConnection() const; - /** - * 获取EpollServer - * @return TC_EpollServer* - */ - TC_EpollServer* getEpollServer() const { return _pEpollServer; } + /** + * 获取服务 + * @return TC_EpollServer* + */ + TC_EpollServer* getEpollServer() const { return _pEpollServer; }; /** * 获取对应的网络线程 @@ -678,17 +680,17 @@ public: */ void setProtocol(const TC_NetWorkBuffer::protocol_functor& pf, int iHeaderLen = 0, const header_filter_functor& hf = echo_header_filter); - /** - * 获取协议解析器 - * @return protocol_functor& - */ - TC_NetWorkBuffer::protocol_functor &getProtocol(); + /** + * 获取协议解析器 + * @return protocol_functor& + */ + TC_NetWorkBuffer::protocol_functor &getProtocol(); - /** - * 解析包头处理对象 - * @return protocol_functor& - */ - header_filter_functor &getHeaderFilterFunctor(); + /** + * 解析包头处理对象 + * @return protocol_functor& + */ + header_filter_functor &getHeaderFilterFunctor(); /** * 增加数据到队列中 @@ -704,11 +706,27 @@ public: */ bool waitForRecvQueue(uint32_t handleIndex, shared_ptr &recv); - /** - * 接收队列的大小 - * @return size_t - */ - size_t getRecvBufferSize() const; + /** + * 接收队列的大小 + * @return size_t + */ + size_t getRecvBufferSize() const; + + /** + * 发送队列的大小 + * @return size_t + */ + size_t getSendBufferSize() const; + + /** + * add send buffer size + */ + inline void increaseSendBufferSize() { ++_iSendBufferSize; } + + /** + * increase send buffer size + */ + inline void decreaseSendBufferSize(size_t s = 1) { _iSendBufferSize.fetch_sub(s); } /** * 默认的协议解析类, 直接echo @@ -783,16 +801,25 @@ public: return _handles[index]; } - // /** - // * 设置服务端回包缓存的大小限制 - // */ - // void setBackPacketBuffLimit(size_t iLimitSize); + /* + * 设置服务端积压缓存的大小限制(超过大小启用) + */ + void setBackPacketBuffLimit(size_t iLimitSize) { _iBackPacketBuffLimit = iLimitSize; } - // /** - // * 获取服务端回包缓存的大小限制 - // */ - // size_t getBackPacketBuffLimit(); + /** + * 获取服务端回包缓存的大小限制(超过大小启用) + */ + size_t getBackPacketBuffLimit() const { return _iBackPacketBuffLimit; } + /* + * 设置服务端5/s最低发送字节 + */ + void setBackPacketBuffMin(size_t iMinLimit) { _iBackPacketBuffMin = iMinLimit; } + + /** + * 获取服务端5/s最低发送字节 + */ + size_t getBackPacketBuffMin() const { return _iBackPacketBuffMin; } /** * 获取服务端接收队列(如果_rnbuffer有多个, 则根据调用者的线程id来hash获取) @@ -943,12 +970,17 @@ public: /** * 接收队列数据总个数 */ - atomic _iBufferSize{0}; + atomic _iRecvBufferSize{0}; - /** - * 队列最大容量 - */ - int _iQueueCapacity; + /** + * 发送队列数据总个数 + */ + atomic _iSendBufferSize{0}; + + /** + * 队列最大容量 + */ + int _iQueueCapacity; /** * 消息超时时间(从入队列到出队列间隔)(毫秒) @@ -970,8 +1002,15 @@ public: */ string _protocolName; - // 回包缓存限制大小 - // size_t _iBackPacketBuffLimit; + /** + * 回包缓存限制大小 + */ + size_t _iBackPacketBuffLimit = 0; + + /** + * 回包速度最低限制(5/s), 默认1K + */ + size_t _iBackPacketBuffMin = 1024; //队列模式 bool _queueMode = false; @@ -1121,6 +1160,16 @@ public: */ void tryInitAuthState(int initState); + /** + * 接收数据buffer + */ + TC_NetWorkBuffer &getRecvBuffer() { return _recvBuffer; } + + /** + * 发送数据buffer + */ + TC_NetWorkBuffer &getSendBuffer() { return _sendBuffer; } + friend class NetThread; protected: @@ -1131,15 +1180,15 @@ public: */ void close(); - /** - * 发送TCP - */ - int sendTcp(const shared_ptr &data); - - /** - * 发送Udp - */ - int sendUdp(const shared_ptr &data); +// /** +// * 发送TCP +// */ +// int sendTcp(const shared_ptr &data); +// +// /** +// * 发送Udp +// */ +// int sendUdp(const shared_ptr &data); /** * 添加发送buffer @@ -1248,10 +1297,25 @@ public: */ TC_NetWorkBuffer _sendBuffer; - /** - * 需要过滤的头部字节数 - */ - int _iHeaderLen; + /** + * 发送数据 + */ + size_t _sendBufferSize = 0; + + /** + * 检查时间 + */ + time_t _lastCheckTime = 0; + + /** + * 发送的检查<已经发送数据, 剩余buffer大小> + */ + vector> _checkSend; + + /** + * 需要过滤的头部字节数 + */ + int _iHeaderLen; /** * 发送完当前数据就关闭连接 @@ -1373,12 +1437,12 @@ public: /** * 无锁 */ - TC_SpinLock _mutex; + TC_ThreadMutex _mutex; - /** - * 服务 - */ - NetThread *_pEpollServer; + /** + * 服务 + */ + NetThread *_pEpollServer; /** * 总计连接数 @@ -1545,11 +1609,11 @@ public: */ void setUdpRecvBufferSize(size_t nSize=DEFAULT_RECV_BUFFERSIZE); - /** - * 发送队列的大小 - * @return size_t - */ - size_t getSendRspSize(); +// /** +// * 发送队列的大小 +// * @return size_t +// */ +// size_t getSendRspSize(); protected: diff --git a/util/include/util/tc_http.h b/util/include/util/tc_http.h index 5adb562..8334089 100755 --- a/util/include/util/tc_http.h +++ b/util/include/util/tc_http.h @@ -25,6 +25,7 @@ #include "util/tc_socket.h" #include "util/tc_epoller.h" #include "util/tc_timeout_queue.h" +#include "util/tc_network_buffer.h" #include #include #include @@ -60,6 +61,7 @@ namespace tars */ ///////////////////////////////////////////////// +class TC_NetWorkBuffer; /** * @brief http协议解析异常类 @@ -577,13 +579,13 @@ public: */ void reset(); - /** - * @brief 读取一行. - * - * @param ppChar 读取位置指针 - * @return string 读取的内容 - */ - static string getLine(const char** ppChar); +// /** +// * @brief 读取一行. +// * +// * @param ppChar 读取位置指针 +// * @return string 读取的内容 +// */ +// static string getLine(const char** ppChar); /** * @brief 读取一行. @@ -592,7 +594,7 @@ public: * @param iBufLen 长度 * @return string 读取的内容 */ - static string getLine(const char** ppChar, int iBufLen); +// static string getLine(const char** ppChar, int iBufLen); /** * @brief 生成头部字符串(不包含第一行). @@ -614,8 +616,45 @@ public: * @param szBuffer * @return const char*, 偏移的指针 */ - static const char* parseHeader(const char* szBuffer, http_header_type &sHeader); +// static const char* parseHeader(const char* szBuffer, http_header_type &sHeader); + template + static void parseHeader(const ForwardIterator1 &beginIt, const ForwardIterator2 &headerIt, http_header_type &sHeader) + { + sHeader.clear(); + string sep = "\r\n"; + string colon = ":"; + bool first = true; + auto lineStartIt= beginIt; + while (true) + { + auto it = std::search(lineStartIt, headerIt, sep.c_str(), sep.c_str() + sep.size()); + if(it == headerIt) + { + break; + } + if(!first) + { + auto itF = std::search(lineStartIt, it, colon.c_str(), colon.c_str() + colon.size()); + if (itF != it) + { + string name; + name.resize(itF - lineStartIt); + std::copy(lineStartIt, itF, name.begin()); + string value; + value.resize(it - (itF + 1)); + std::copy(itF + 1, it, value.begin()); + sHeader.insert(multimap::value_type(TC_Common::trim(name, " "), + TC_Common::trim(value, " "))); + } + } + else + { + first = false; + } + lineStartIt = it + sep.size(); + } + } protected: /** @@ -815,7 +854,7 @@ public: * false:还需要继续解析,如果服务器主动关闭连接的模式下 * , 也可能不需要再解析了 */ - bool incrementDecode(string &sBuffer); + bool incrementDecode(TC_NetWorkBuffer &buff); /** * @brief 解析http应答(采用string方式) , @@ -954,14 +993,42 @@ public: * @param szBuffer 应答头信息 * @return */ - void parseResponseHeader(const char* szBuffer); +// void parseResponseHeader(const char* szBuffer, const char* header); + template + void parseResponseHeader(const ForwardIterator1 &beginIt, const ForwardIterator2 &headerIt) + { + string line = "\r\n"; + auto it = std::search(beginIt, headerIt, line.c_str(), line.c_str() + line.size()); + assert(it != headerIt); + string sep = " "; + auto f1 = std::search(beginIt, headerIt, sep.c_str(), sep.c_str() + sep.size()); + if(f1 == headerIt) + { + throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse version format error : " + string(beginIt, it)); + } + auto f2 = std::search(f1 + 1, headerIt, sep.c_str(), sep.c_str() + sep.size()); + if(f1 == headerIt) + { + throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse status format error : " + string(beginIt, it)); + } + _headerLine = string(beginIt, it); + if(TC_Port::strncasecmp(_headerLine.c_str(), "HTTP/", 5) != 0) + { + throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response version is not start with 'HTTP/' : " + _headerLine); + } + _version = string(beginIt, f1); + _status = TC_Common::strto(string(f1 + 1, f2)); + _about = TC_Common::trim(string(f2 + 1, it)); + parseHeader(beginIt, headerIt, _headers); + } protected: /** * 添加内容, 增量解析用到 * @param sBuffer */ void addContent(const string &sBuffer); + void addContent(const char *buffer, size_t length); protected: @@ -1034,6 +1101,13 @@ public: static bool checkRequest(const char* sBuffer, size_t len); /** + * 检查http包是否收全 + * @param buff + * @return + */ + static bool checkRequest(TC_NetWorkBuffer &buff); + + /** * @brief 重置 */ void reset(); @@ -1095,6 +1169,12 @@ public: void encode(vector &buffer); /** + * encode buffer to TC_NetWorkBuffer + * @param buff + */ + void encode(TC_NetWorkBuffer &buff); + + /** * @brief 设置请求包. * * @param sUrl 例如:http://www.qq.com/query?a=b&c=d @@ -1265,7 +1345,7 @@ public: /** * @brief 获取完整的http请求. - * + * * @return http请求串 */ string getOriginRequest() const { return _httpURL.getURL(); } @@ -1281,7 +1361,7 @@ public: * @brief 获取http请求的url部分, 即?前面,不包括Host, * 例如http://www.qq.com/abc?a=b#def, 则为:/abc * @return http请求的url部分 - * */ + * */ string getRequestUrl() const { return _httpURL.getPath(); } /** @@ -1293,15 +1373,15 @@ public: /** * @brief 解析请求头部. - * + * * @param szBuffer 请求头部 - * @return size_t + * @return */ - size_t parseRequestHeader(const char* szBuffer); + void parseRequestHeader(const char* szBuffer, const char *header); /** * @brief 请求类型到字符串. - * + * * @param iRequestType 请求 * @return 解析后的字符串 */ @@ -1311,7 +1391,7 @@ protected: /** * @brief 对http请求编码. - * + * * @param sUrl 需要进行编码的http请求 * @param iRequestType 编码后的输出流 * @return void diff --git a/util/include/util/tc_http_async.h b/util/include/util/tc_http_async.h index d6b5ce0..c20c51f 100644 --- a/util/include/util/tc_http_async.h +++ b/util/include/util/tc_http_async.h @@ -20,6 +20,7 @@ #include #include "util/tc_platform.h" #include "util/tc_thread_pool.h" +#include "util/tc_network_buffer.h" #include "util/tc_http.h" #include "util/tc_autoptr.h" #include "util/tc_socket.h" @@ -42,17 +43,6 @@ namespace tars */ ///////////////////////////////////////////////// - -///** -//* @brief 线程异常 -//*/ -//struct TC_HttpAsync_Exception : public TC_Exception -//{ -// TC_HttpAsync_Exception(const string &buffer) : TC_Exception(buffer) {}; -// TC_HttpAsync_Exception(const string &buffer, int err) : TC_Exception(buffer, err) {}; -// ~TC_HttpAsync_Exception() throw() {}; -//}; - /** * @brief 异步线程处理类. */ @@ -128,6 +118,15 @@ protected: */ AsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallbackPtr &callbackPtr, bool bUseProxy); + /** + * @brief 构造. + * + * @param stHttpRequest + * @param callbackPtr + * @param addr + */ + AsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallbackPtr &callbackPtr, const string &addr); + /** * @brief 析构 */ @@ -140,11 +139,6 @@ protected: */ int getfd() const { return _fd.getfd(); } - /** - * 获取通知fd - */ - // int getNotifyfd() const { return _notify.getfd(); } - /** * @brief 发起建立连接. * @@ -155,7 +149,7 @@ protected: * @brief 获取系统错误提示 * @return */ - string getError(const char* sDefault) const; + string getError(const string &sDefault) const; /** * @brief 发生异常 @@ -266,8 +260,8 @@ protected: string _sHost; uint32_t _iPort; uint32_t _iUniqId; - string _sReq; - string _sRsp; + TC_NetWorkBuffer _sendBuffer; + TC_NetWorkBuffer _recvBuffer; RequestCallbackPtr _callbackPtr; bool _bindAddrSet; struct sockaddr _bindAddr; @@ -300,6 +294,15 @@ public: */ void doAsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallbackPtr &callbackPtr, bool bUseProxy = false); + /** + * @brief 异步发起请求. + * + * @param stHttpRequest + * @param httpCallbackPtr + * @param addr, 请求地址, ip:port + */ + void doAsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallbackPtr &callbackPtr, const string &addr); + /** * @brief 设置proxy地址 * @@ -373,11 +376,6 @@ protected: */ static void timeout(AsyncRequestPtr& ptr); - /** - * @brief 具体网络处理 - */ - // static void process(AsyncRequestPtr &p, int events); - /** * @brief 确保线程 * @param _threadId [description] diff --git a/util/include/util/tc_network_buffer.h b/util/include/util/tc_network_buffer.h index 474dfd8..f586423 100755 --- a/util/include/util/tc_network_buffer.h +++ b/util/include/util/tc_network_buffer.h @@ -29,6 +29,15 @@ namespace tars { +/** +* @brief +*/ +struct TC_NetWorkBuffer_Exception : public TC_Exception +{ + TC_NetWorkBuffer_Exception(const string &sBuffer) : TC_Exception(sBuffer){}; + ~TC_NetWorkBuffer_Exception() {}; +}; + class TC_NetWorkBuffer { public: @@ -109,7 +118,21 @@ public: size_t pos() const { return _pos; } - void add(uint32_t ret) + char &at(size_t offset) + { + if(_pos + offset >= _buffer.size() ) + throw TC_NetWorkBuffer_Exception("[TC_NetWorkBuffer::Buffer] at '" + TC_Common::tostr(offset) + "' offset overflow"); + return _buffer[_pos + offset]; + } + + char at(size_t offset) const + { + if(_pos + offset >= _buffer.size() ) + throw TC_NetWorkBuffer_Exception("[TC_NetWorkBuffer::Buffer] at '" + TC_Common::tostr(offset) + "' offset overflow"); + return _buffer[_pos + offset]; + } + + void add(uint32_t ret) { _pos += ret; assert(_pos <= _buffer.size()); @@ -121,6 +144,212 @@ public: }; + typedef std::list>::const_iterator buffer_list_iterator; + + class buffer_iterator : public std::iterator + { + public: + buffer_iterator(const TC_NetWorkBuffer *buffer, size_t offset) : _buffer(buffer) + { + parseOffset(offset); + } + + /** + * @brief copy + * @param it + */ + buffer_iterator(const buffer_iterator &it) + { + if(this != &it) + { + _buffer = it._buffer; + _pos = it._pos; + _offset = it._offset; + _it = it._it; + } + } + + /** + * + * @param mcmi + * + * @return bool + */ + bool operator==(const buffer_iterator& it) const + { + if (_buffer == it._buffer && _it == it._it && _offset == it._offset) + { + return true; + } + + return false; + } + + /** + * + * @param mv + * + * @return bool + */ + bool operator!=(const buffer_iterator& it) const + { + if (_buffer == it._buffer && _it == it._it && _offset == it._offset) + { + return false; + } + + return true; + } + + char & operator *() + { + return (*_it)->buffer()[_pos]; + } + + char * operator ->() + { + return &(*_it)->buffer()[_pos]; + } + + char& operator *() const + { + return (*_it)->buffer()[_pos]; + } + + const char* operator ->() const + { + return &(*_it)->buffer()[_pos]; + } + + buffer_iterator operator +(size_t n) const + { + return buffer_iterator(_buffer, _offset + n); + } + + buffer_iterator operator += (size_t n) + { + parseOffset(_offset + n); + return *this; + } + + difference_type operator -(const buffer_iterator &n) const + { + return _offset - n._offset; + } + + buffer_iterator operator -(size_t n) const + { + return buffer_iterator(_buffer, _offset - n); + } + + bool operator < (const buffer_iterator n) const + { + return _offset (const buffer_iterator n) const + { + return _offset>n._offset; + } + + bool operator >= (const buffer_iterator n) const + { + return _offset>=n._offset; + } + + //前置++ + buffer_iterator& operator ++() + { + if(_offset >= _buffer->getBufferLength()) + return *this; + + assert(_it != _buffer->_bufferList.end()); + + if(_pos < (*_it)->length() - 1) + { + ++_pos; + ++_offset; + } + else + { + ++_it; + ++_offset; + _pos = 0; + } + return *this; + } + + //后置++ + buffer_iterator operator ++(int) + { + buffer_iterator it(*this); + + if(_it != _buffer->_bufferList.end()) + { + if (_pos < (*_it)->length() - 1) + { + ++_pos; + ++_offset; + } + else + { + ++_it; + ++_offset; + _pos = 0; + } + } + else + { + _offset = _buffer->getBufferLength(); + _pos = 0; + } + return it; + } + + protected: + void parseOffset(size_t offset) + { + _offset = offset; + + bool flag = false; + for(auto it = _buffer->_bufferList.begin(); it != _buffer->_bufferList.end(); ++it) + { + if(offset >= (*it)->length()) + { + offset -= (*it)->length(); + } + else + { + _it = it; + _pos = offset; + flag = true; + + break; + } + } + + if(!flag) + { + _offset = _buffer->getBufferLength(); + _pos = 0; + _it = _buffer->_bufferList.end(); + } + } + + friend class TC_NetWorkBuffer; + + protected: + const TC_NetWorkBuffer* _buffer; + buffer_list_iterator _it; + size_t _offset = 0; + size_t _pos = 0; + }; + /** * 必须以connection来构造(不同服务模型中获取的对象不一样, 需要自己强制转换) * @param buff @@ -169,6 +398,12 @@ public: */ void addBuffer(const std::vector& buff); + /** + * 增加buffer + * @param buff + */ + void addBuffer(const std::string& buff); + /** * 增加buffer * @param buff @@ -177,6 +412,75 @@ public: void addBuffer(const char* buff, size_t length); /** + * begin + * @return + */ + buffer_iterator begin() const; + + /** + * end + * @return + */ + buffer_iterator end() const; + + /** + * 查找 + * @param str + * @param length + * @return + */ + buffer_iterator find(const char *str, size_t length); + + /** + * 获取从开头到迭代器(前一个, 不包括迭代器本身)所有buffer + * T: string or vector + * @param it + * @return + */ + template + T iteratorToIterator(const buffer_iterator &sit, const buffer_iterator &eit) + { + T buff; + + if(sit == end() || sit == eit) + { + return buff; + } + + if(sit > eit) + { + throw TC_NetWorkBuffer_Exception("[TC_NetWorkBuffer::iteratorToIterator] sit > eit error"); + } + + buff.resize(eit - sit); + + std::copy(sit, eit, buff.begin()); + + return buff; + } + + /** + * 匹配到对应buff, 获取之前的buffer + * T: string or vector + * @param sep + * @param length + * @return + */ + template + T getPrefixBuffer(const char *sep, size_t length) + { + T buff; + auto sit = std::search(begin(), end(), sep, sep + length); + + if(sit == end()) + { + return buff; + } + + return iteratorToIterator(begin(), sit); + } + + /** * 清空所有buffer */ void clearBuffers(); @@ -192,6 +496,12 @@ public: */ size_t getBufferLength() const; + /** + * buffer list length + * @return + */ + size_t size() const { return _bufferList.size(); } + /** * 获取第一块有效数据buffer的指针, 可以用来发送数据 * @return @@ -230,6 +540,34 @@ public: */ bool getHeader(size_t len, std::vector &buffer) const; + /** + * 读取len字节的buffer(避免len个字节被分割到多个buffer的情况)(注意: 不往后移动) + * getHeader(10), getHeader>(10); + * @param len + * @return 不够会抛异常TC_NetWorkBuffer_Exception + */ + template + T getHeader(size_t len) const + { + if(getBufferLength() < len) + { + throw TC_NetWorkBuffer_Exception("[TC_NetWorkBuffer::getHeader] no enough buff(" + TC_Common::tostr(getBufferLength()) + ") to get(" + TC_Common::tostr(len) + ")"); + } + + T buffer; + + if(len == 0) + { + return buffer; + } + + buffer.resize(len); + + getBuffers(&buffer[0], len); + + return buffer; + } + /** * 往后移动len个字节 * @param len diff --git a/util/src/tc_epoll_server.cpp b/util/src/tc_epoll_server.cpp index 451f2b5..093a25f 100644 --- a/util/src/tc_epoll_server.cpp +++ b/util/src/tc_epoll_server.cpp @@ -426,7 +426,7 @@ void TC_EpollServer::BindAdapter::notifyHandle(uint32_t handleIndex) void TC_EpollServer::BindAdapter::insertRecvQueue(const shared_ptr &recv) { - _iBufferSize++; + _iRecvBufferSize++; size_t idx = 0; @@ -451,14 +451,19 @@ bool TC_EpollServer::BindAdapter::waitForRecvQueue(uint32_t handleIndex, shared_ return bRet; } - --_iBufferSize; + --_iRecvBufferSize; return bRet; } size_t TC_EpollServer::BindAdapter::getRecvBufferSize() const { - return _iBufferSize; + return _iRecvBufferSize; +} + +size_t TC_EpollServer::BindAdapter::getSendBufferSize() const +{ + return _iSendBufferSize; } TC_NetWorkBuffer::PACKET_TYPE TC_EpollServer::BindAdapter::echo_protocol(TC_NetWorkBuffer &r, vector &o) @@ -504,14 +509,14 @@ void TC_EpollServer::BindAdapter::setQueueCapacity(int n) int TC_EpollServer::BindAdapter::isOverloadorDiscard() { - int iRecvBufferSize = _iBufferSize; + int iRecvBufferSize = _iRecvBufferSize; if(iRecvBufferSize > (int)(_iQueueCapacity / 5.*4) && (iRecvBufferSize < _iQueueCapacity) && (_iQueueCapacity > 0)) //overload { //超过队列4/5开始认为过载 return -1; } - else if(iRecvBufferSize > (int)(_iQueueCapacity) && _iQueueCapacity > 0)//队列满需要丢弃接受的数据包 + else if(iRecvBufferSize > (int)(_iQueueCapacity) && _iQueueCapacity > 0 ) //队列满需要丢弃接受的数据包 { return -2; } @@ -748,6 +753,8 @@ void TC_EpollServer::Connection::close() if (isTcp() && _sock.isValid()) { + _pBindAdapter->decreaseSendBufferSize(_sendBuffer.size()); + _sock.close(); } } @@ -823,7 +830,7 @@ int TC_EpollServer::Connection::parseProtocol(TC_NetWorkBuffer &rbuf) recv->buffer().swap(ro); - if (_pBindAdapter->_authWrapper && _pBindAdapter->_authWrapper(this, recv)) + if (_pBindAdapter->getEndpoint().isTcp() && _pBindAdapter->_authWrapper && _pBindAdapter->_authWrapper(this, recv)) continue; //收到完整的包才算 @@ -1003,13 +1010,23 @@ int TC_EpollServer::Connection::recv() int TC_EpollServer::Connection::sendBuffer() { + size_t nowSendBufferSize = 0; + size_t nowLeftBufferSize = _sendBuffer.getBufferLength(); + while(!_sendBuffer.empty()) { pair data = _sendBuffer.getBufferPointer(); - assert(data.first != NULL); + int iBytesSent = 0; - int iBytesSent = _sock.send((const void *)data.first, data.second); + if(this->isTcp()) + { + iBytesSent = _sock.send((const void *) data.first, data.second); + } + else + { + iBytesSent = _sock.sendto((const void *) data.first, data.second, _ip, _port, 0); + } if (iBytesSent < 0) { @@ -1026,7 +1043,24 @@ int TC_EpollServer::Connection::sendBuffer() if(iBytesSent > 0) { - _sendBuffer.moveHeader(iBytesSent); + nowSendBufferSize += iBytesSent; + + if(isTcp()) + { + _sendBuffer.moveHeader(iBytesSent); + + if (iBytesSent == data.second) + { + _pBindAdapter->decreaseSendBufferSize(); + } + } + else + { + _sendBuffer.moveHeader(data.second); + + _pBindAdapter->decreaseSendBufferSize(); + + } } //发送的数据小于需要发送的,break, 内核会再通知你的 @@ -1043,52 +1077,171 @@ int TC_EpollServer::Connection::sendBuffer() return -2; } +// 当出现队列积压的前提下, 且积压超过一定大小 +// 每5秒检查一下积压情况, 连续12次(一分钟), 都是积压 +// 且每个检查点, 积压长度都增加或者连续3次发送buffer字节小于1k, 就关闭连接, 主要避免极端情况 + + size_t iBackPacketBuffLimit = _pBindAdapter->getBackPacketBuffLimit(); + if(_sendBuffer.getBufferLength() > iBackPacketBuffLimit) + { + if(_sendBufferSize == 0) + { + //开始积压 + _lastCheckTime = TNOW; + } + _sendBufferSize += nowSendBufferSize; + + if (TNOW - _lastCheckTime >= 5) + { + //如果持续有积压, 则每5秒检查一次 + _lastCheckTime = TNOW; + + _checkSend.push_back(make_pair(_sendBufferSize, nowLeftBufferSize)); + + _sendBufferSize = 0; + + size_t iBackPacketBuffMin = _pBindAdapter->getBackPacketBuffMin(); + + //连续3个5秒, 发送速度都极慢, 每5秒发送 < iBackPacketBuffMin, 认为连接有问题, 关闭之 + int left = 3; + if (_checkSend.size() >= left) + { + bool slow = true; + for (int i = (int)_checkSend.size() - 1; i >= (int)(_checkSend.size() - left); i--) + { + //发送速度 + if (_checkSend[i].first > iBackPacketBuffMin) + { + slow = false; + continue; + } + } + + if (slow) + { + ostringstream os; + os << "send [" << _ip << ":" << _port << "] buffer queue send to slow, send size:"; + + for (int i = (int)_checkSend.size() - 1; i >= (int)(_checkSend.size() - left); i--) + { + os << ", " << _checkSend[i].first; + } + + _pBindAdapter->getEpollServer()->error(os.str()); + _sendBuffer.clearBuffers(); + return -5; + } + } + + //连续12个5秒, 都有积压现象, 检查 + if (_checkSend.size() >= 12) + { + bool accumulate = true; + for (size_t i = _checkSend.size() - 1; i >= 1; i--) { + //发送buffer 持续增加 + if (_checkSend[i].second < _checkSend[i - 1].second) { + accumulate = false; + break; + } + } + + //持续积压 + if (accumulate) + { + ostringstream os; + os << "send [" << _ip << ":" << _port << "] buffer queue continues to accumulate data, queue size:"; + + for (size_t i = 0; i < _checkSend.size(); i++) + { + os << ", " << _checkSend[i].second; + } + + _pBindAdapter->getEpollServer()->error(os.str()); + _sendBuffer.clearBuffers(); + return -4; + } + + _checkSend.erase(_checkSend.begin()); + } + } + } + else + { + //无积压 + _sendBufferSize = 0; + _lastCheckTime = TNOW; + _checkSend.clear(); + } + return 0; } +// +//int TC_EpollServer::Connection::sendTcp(const shared_ptr &sc) +//{ +//#if TAF_SSL +// if (getBindAdapter()->getEndpoint().isSSL()) +// { +// assert(_openssl->isHandshaked()); +// +// int ret = _openssl->write(sc->buffer()->buffer(), sc->buffer()->length(), _sendBuffer); +// if (ret != 0) { +// _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] sendTcp [" + _ip + ":" + TC_Common::tostr(_port) + "] error:" + _openssl->getErrMsg()); +// +// return -1; // should not happen +// } +// } +// else +//#endif +// { +// _sendBuffer.addBuffer(sc->buffer()); +// } +// +// return sendBuffer(); +//} +// +//int TC_EpollServer::Connection::sendUdp(const shared_ptr &sc) +//{ +// _sendBuffer.addBuffer(sc->buffer()); +// +// return sendBuffer(); +//// +//// //udp的直接发送即可 +//// int iRet = _sock.sendto((const void *) sc->buffer()->buffer(), sc->buffer()->length(), sc->ip(), sc->port(), 0); +//// if (iRet < 0) +//// { +//// _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] send [" + _ip + ":" + TC_Common::tostr(_port) + "] error"); +//// return -1; +//// } +//// +//// return 0; +//} -int TC_EpollServer::Connection::sendTcp(const shared_ptr &sc) +int TC_EpollServer::Connection::send(const shared_ptr &sc) { - if(!sc->buffer()->empty()) - { -#if TARS_SSL - if (getBindAdapter()->getEndpoint().isSSL()) - { - assert(_openssl->isHandshaked()); + assert(sc); - int ret = _openssl->write(sc->buffer()->buffer(), sc->buffer()->length(), _sendBuffer); - if (ret != 0) { - _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] sendTcp [" + _ip + ":" + TC_Common::tostr(_port) + "] error:" + _openssl->getErrMsg()); + _pBindAdapter->increaseSendBufferSize(); + +#if TAF_SSL + if (getBindAdapter()->getEndpoint().isSSL()) + { + assert(_openssl->isHandshaked()); + + int ret = _openssl->write(sc->buffer()->buffer(), sc->buffer()->length(), _sendBuffer); + if (ret != 0) { + _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] send [" + _ip + ":" + TC_Common::tostr(_port) + "] error:" + _openssl->getErrMsg()); return -1; // should not happen } } else #endif - { - _sendBuffer.addBuffer(sc->buffer()); - } + { + _sendBuffer.addBuffer(sc->buffer()); } - return sendBuffer(); -} - -int TC_EpollServer::Connection::sendUdp(const shared_ptr &sc) -{ - //udp的直接发送即可 - int iRet = _sock.sendto((const void *) sc->buffer()->buffer(), sc->buffer()->length(), sc->ip(), sc->port(), 0); - if (iRet < 0) - { - _pBindAdapter->getEpollServer()->error("[TC_EpollServer::Connection] send [" + _ip + ":" + TC_Common::tostr(_port) + "] error"); - return -1; - } - - return 0; -} - -int TC_EpollServer::Connection::send(const shared_ptr &sc) -{ - return isTcp() ? sendTcp(sc) : sendUdp(sc); + return sendBuffer(); } bool TC_EpollServer::Connection::setRecvBuffer(size_t nSize) @@ -1157,7 +1310,7 @@ void TC_EpollServer::ConnectionList::init(uint32_t size, uint32_t iIndex) uint32_t TC_EpollServer::ConnectionList::getUniqId() { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); uint32_t uid = _free.front(); @@ -1182,7 +1335,7 @@ TC_EpollServer::Connection* TC_EpollServer::ConnectionList::get(uint32_t uid) void TC_EpollServer::ConnectionList::add(Connection *cPtr, time_t iTimeOutStamp) { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); uint32_t muid = cPtr->getId(); uint32_t magi = muid & (0xFFFFFFFF << 22); @@ -1195,7 +1348,7 @@ void TC_EpollServer::ConnectionList::add(Connection *cPtr, time_t iTimeOutStamp) void TC_EpollServer::ConnectionList::refresh(uint32_t uid, time_t iTimeOutStamp) { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); uint32_t magi = uid & (0xFFFFFFFF << 22); uid = uid & (0x7FFFFFFF >> 9); @@ -1224,7 +1377,7 @@ void TC_EpollServer::ConnectionList::checkTimeout(time_t iCurTime) _lastTimeoutTime = iCurTime; - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); multimap::iterator it = _tl.begin(); @@ -1295,7 +1448,7 @@ vector TC_EpollServer::ConnectionList::getConnStatus { vector v; - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); for(size_t i = 1; i <= _total; i++) { @@ -1309,6 +1462,8 @@ vector TC_EpollServer::ConnectionList::getConnStatus cs.port = _vConn[i].first->getPort(); cs.timeout = _vConn[i].first->getTimeout(); cs.uid = _vConn[i].first->getId(); + cs.recvBufferSize = _vConn[i].first->getRecvBuffer().getBufferLength(); + cs.sendBufferSize = _vConn[i].first->getSendBuffer().getBufferLength(); v.push_back(cs); } @@ -1319,7 +1474,7 @@ vector TC_EpollServer::ConnectionList::getConnStatus void TC_EpollServer::ConnectionList::del(uint32_t uid) { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); uint32_t magi = uid & (0xFFFFFFFF << 22); uid = uid & (0x7FFFFFFF >> 9); @@ -1346,7 +1501,7 @@ void TC_EpollServer::ConnectionList::_del(uint32_t uid) size_t TC_EpollServer::ConnectionList::size() { - TC_LockT lock(_mutex); + TC_LockT lock(_mutex); return _total - _free_size; } @@ -1751,10 +1906,10 @@ void TC_EpollServer::NetThread::run() } } -size_t TC_EpollServer::NetThread::getSendRspSize() -{ - return _sbuffer.size(); -} +//size_t TC_EpollServer::NetThread::getSendRspSize() +//{ +// return _sbuffer.size(); +//} ////////////////////////////////////////////////////////////// TC_EpollServer::TC_EpollServer(unsigned int iNetThreadNum) : _netThreadNum(iNetThreadNum) diff --git a/util/src/tc_http.cpp b/util/src/tc_http.cpp index c59a61e..f9e22d1 100755 --- a/util/src/tc_http.cpp +++ b/util/src/tc_http.cpp @@ -18,6 +18,7 @@ #include "util/tc_port.h" #include "util/tc_common.h" #include "util/tc_clientsocket.h" +#include "util/tc_network_buffer.h" namespace tars { @@ -350,17 +351,6 @@ string TC_URL::getRef() const return _sRef; } -//string TC_URL::getFragment(const string& frag) const -//{ -// map::const_iterator it = _fragment.find(frag); -// if(it == _fragment.end()) -// { -// return ""; -// } -// -// return it->second; -//} - string TC_URL::getRelativePath() const { string sURL = getPath(); @@ -608,123 +598,170 @@ vector TC_Http::getHeaderMulti(const string &sHeadName) const return v; } +// +//string TC_Http::getLine(const char** ppChar) +//{ +// string sTmp; +// +// sTmp.reserve(512); +// +// while ((**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') +// { +// sTmp.append(1, (**ppChar)); +// (*ppChar)++; +// } +// +// if ((**ppChar) == '\r') +// { +// (*ppChar)++; /* pass the char '\n' */ +// } +// +// (*ppChar)++; +// +// return sTmp; +//} +// +// +//string TC_Http::getLine(const char** ppChar, int iBufLen) +//{ +// string sTmp; +// +// sTmp.reserve(512); +// +// int iCurIndex = 0; +// while ( (**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') +// { +// if ( iCurIndex < iBufLen ) +// { +// sTmp.append(1, (**ppChar)); +// (*ppChar)++; +// iCurIndex++; +// } +// else +// { +// //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 1 " << endl; +// break; +// } +// } +// +// if ( (**ppChar) == '\r') +// { +// if ( iCurIndex < iBufLen ) +// { +// (*ppChar)++; /* pass the char '\n' */ +// iCurIndex++; +// } +// else +// { +// //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 2 " << endl; +// } +// } +// +// if ( iCurIndex < iBufLen ) +// { +// (*ppChar)++; +// iCurIndex++; +// } +// else +// { +// //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 3 " << endl; +// } +// +// return sTmp; +//} -string TC_Http::getLine(const char** ppChar) -{ - string sTmp; +// +//void TC_Http::parseHeader(const TC_NetWorkBuffer::buffer_iterator &beginIt, const TC_NetWorkBuffer::buffer_iterator &headerIt, http_header_type &sHeader) +//{ +// sHeader.clear(); +// +// string sep = "\r\n"; +// string colon = ":"; +// +// bool first = true; +// auto lineStartIt= beginIt; +// +// while (true) +// { +// auto it = std::search(lineStartIt, headerIt, sep.c_str(), sep.c_str() + sep.size()); +// if(it == headerIt) +// { +// break; +// } +// +// //first line ignore +// if(!first) +// { +// auto itF = std::search(lineStartIt, it, colon.c_str(), colon.c_str() + colon.size()); +// if (itF != it) +// { +// string name; +// name.resize(itF - lineStartIt); +// std::copy(lineStartIt, itF, name.begin()); +// +// string value; +// value.resize(it - (itF + 1)); +// std::copy(itF + 1, it, value.begin()); +// +// sHeader.insert(multimap::value_type(TC_Common::trim(name, " "), +// TC_Common::trim(value, " "))); +// +// } +// } +// else +// { +// first = false; +// } +// +// lineStartIt = it + sep.size(); +// } +//} +// +//const char* TC_Http::parseHeader(const char* szBuffer, http_header_type &sHeader) +//{ +// sHeader.clear(); +// +// const char **ppChar = &szBuffer; +// +// size_t length = strlen(szBuffer); +// size_t srcPtr = (size_t)(*ppChar); +// +// while (true) +// { +// string sLine = getLine(ppChar); +// +// if (sLine.empty()) break; +// +// //如果是第一行, 则忽略掉 +// if(TC_Port::strncasecmp(sLine.c_str(), "GET ", 4) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "POST ", 5) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "PUT ", 4) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "PATCH ", 6) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "OPTIONS ", 8) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "HEAD ", 5) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "DELETE ", 7) ==0 +// || TC_Port::strncasecmp(sLine.c_str(), "HTTP/", 5) ==0) +// { +// continue; +// } +// +// string::size_type index = sLine.find(":"); +// if (index != string::npos) +// { +// sHeader.insert(multimap::value_type(TC_Common::trim(sLine.substr(0, index), " "), TC_Common::trim(sLine.substr(index + 1), " "))); +// } +// +// size_t offset = (size_t)(*ppChar - srcPtr); +// +// if (offset >= length) +// { +// break; +// } +// } +// +// return *ppChar; +//} - sTmp.reserve(512); - - while ((**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') - { - sTmp.append(1, (**ppChar)); - (*ppChar)++; - } - - if ((**ppChar) == '\r') - { - (*ppChar)++; /* pass the char '\n' */ - } - - (*ppChar)++; - - return sTmp; -} - - -string TC_Http::getLine(const char** ppChar, int iBufLen) -{ - string sTmp; - - sTmp.reserve(512); - - int iCurIndex = 0; - while ( (**ppChar) != '\r' && (**ppChar) != '\n' && (**ppChar) != '\0') - { - if ( iCurIndex < iBufLen ) - { - sTmp.append(1, (**ppChar)); - (*ppChar)++; - iCurIndex++; - } - else - { - //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 1 " << endl; - break; - } - } - - if ( (**ppChar) == '\r') - { - if ( iCurIndex < iBufLen ) - { - (*ppChar)++; /* pass the char '\n' */ - iCurIndex++; - } - else - { - //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 2 " << endl; - } - } - - if ( iCurIndex < iBufLen ) - { - (*ppChar)++; - iCurIndex++; - } - else - { - //MTT_ERRDAY << "parseHttp WARN: iCurIndex < iBufLen 3 " << endl; - } - - return sTmp; -} - - -const char* TC_Http::parseHeader(const char* szBuffer, http_header_type &sHeader) -{ - sHeader.clear(); - - const char **ppChar = &szBuffer; - - size_t length = strlen(szBuffer); - size_t srcPtr = (size_t)(*ppChar); - - while (true) - { - string sLine = getLine(ppChar); - - if (sLine.empty()) break; - - //如果是第一行, 则忽略掉 - if(TC_Port::strncasecmp(sLine.c_str(), "GET ", 4) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "POST ", 5) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "PUT ", 4) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "PATCH ", 6) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "OPTIONS ", 8) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "HEAD ", 5) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "DELETE ", 7) ==0 - || TC_Port::strncasecmp(sLine.c_str(), "HTTP/", 5) ==0) - { - continue; - } - - string::size_type index = sLine.find(":"); - if(index != string::npos) - { - sHeader.insert(multimap::value_type(TC_Common::trim(sLine.substr(0, index), " "), TC_Common::trim(sLine.substr(index + 1), " "))); - } - - size_t offset = (size_t)(*ppChar - srcPtr); - - if(offset >= length) - { - break; - } - } - - return *ppChar; -} void TC_Http::reset() { @@ -1010,7 +1047,7 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook } //URL在Path范围内,Cookie 有效 - if(!matchPath(cookie._path, sRspURLPath)) + if (!matchPath(cookie._path, sRspURLPath)) continue; //添加Cookie @@ -1021,7 +1058,7 @@ void TC_HttpCookie::addCookie(const string &sRspURL, const vector &vCook bool TC_HttpCookie::isCookieExpires(const Cookie &cookie) const { //过期了 - if(cookie._expires !=0 && cookie._expires < time(NULL)) + if (cookie._expires != 0 && cookie._expires < time(NULL)) return true; return false; @@ -1030,16 +1067,16 @@ bool TC_HttpCookie::isCookieExpires(const Cookie &cookie) const size_t TC_HttpCookie::isCookieMatch(const Cookie &cookie, const TC_URL &tURL) const { //域名没有匹配 - if(!matchDomain(cookie._domain, tURL.getDomain())) + if (!matchDomain(cookie._domain, tURL.getDomain())) return 0; //路径没有匹配 size_t len = matchPath(cookie._path, tURL.getPath()); - if(len == 0) + if (len == 0) return 0; //安全的cookie,不安全的URL - if(cookie._isSecure && (tURL.getType() != TC_URL::HTTPS)) + if (cookie._isSecure && (tURL.getType() != TC_URL::HTTPS)) return 0; return len; @@ -1163,48 +1200,80 @@ void TC_HttpCookie::deleteExpires(time_t t, bool bErase) } /********************* TC_HttpResponse ***********************/ - -void TC_HttpResponse::parseResponseHeader(const char* szBuffer) -{ - const char **ppChar = &szBuffer; - - _headerLine = TC_Common::trim(getLine(ppChar)); - - string::size_type pos = _headerLine.find(' '); - - if(pos != string::npos) - { - _version = _headerLine.substr(0, pos); - - string left = TC_Common::trim(_headerLine.substr(pos)); - - string::size_type pos1 = left.find(' '); - - if(pos1 != string::npos) - { - _status = TC_Common::strto(left.substr(0, pos)); - - _about = TC_Common::trim(left.substr(pos1 + 1)); - } - else - { - _status = TC_Common::strto(left); - - _about = ""; - } - - parseHeader(*ppChar, _headers); - return; - } - else - { - _version = _headerLine; - _status = 0; - _about = ""; - } - -// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response format error : " + _headerLine); -} +// +//void TC_HttpResponse::parseResponseHeader(const char* szBuffer, const char* header) +//{ +// auto it = strstr(szBuffer, "\r\n"); +// +// assert(it != NULL); +// +// string sep = " "; +// +// auto f1 = std::search(szBuffer, it, sep.c_str(), sep.c_str() + sep.size()); +// if(f1 == it) +// { +// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse version format error : " + string(szBuffer, it-szBuffer)); +// } +// +// auto f2 = std::search(f1 + 1, it, sep.c_str(), sep.c_str() + sep.size()); +// if(f1 == it) +// { +// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse status format error : " + string(szBuffer, it-szBuffer)); +// } +// +// _headerLine = string(szBuffer, it-szBuffer); +// +// if(TC_Port::strncasecmp(_headerLine.c_str(), "HTTP/", 5) != 0) +// { +// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response version is not start with 'HTTP/' : " + _headerLine); +// } +// +// _version = string(szBuffer, f1); +// +// _status = TC_Common::strto(string(f1 + 1, f2)); +// +// _about = TC_Common::trim(string(f2 + 1, it)); +// +// parseHeader(szBuffer, header, _headers); +//} +// +//void TC_HttpResponse::parseResponseHeader(TC_NetWorkBuffer &buff, TC_NetWorkBuffer::buffer_iterator &headerIt) +//{ +// string line = "\r\n"; +// auto it = buff.find(line.c_str(), line.size()); +// +// assert(it != buff.end()); +// +// string sep = " "; +// +// auto f1 = std::search(buff.begin(), it, sep.c_str(), sep.c_str() + sep.size()); +// if(f1 == it) +// { +// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse version format error : " + buff.iteratorToIterator(buff.begin(), it)); +// } +// +// auto f2 = std::search(f1 + 1, it, sep.c_str(), sep.c_str() + sep.size()); +// if(f1 == it) +// { +// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response parse status format error : " + buff.iteratorToIterator(buff.begin(), it)); +// } +// +// _headerLine = buff.iteratorToIterator(buff.begin(), it); +// +// if(TC_Port::strncasecmp(_headerLine.c_str(), "HTTP/", 5) != 0) +// { +// throw TC_HttpResponse_Exception("[TC_HttpResponse_Exception::parseResponeHeader] http response version is not start with 'HTTP/' : " + _headerLine); +// } +// +// _version = buff.iteratorToIterator(buff.begin(), f1); +// +// _status = TC_Common::strto(buff.iteratorToIterator(f1 + 1, f2)); +// +// _about = TC_Common::trim(buff.iteratorToIterator(f2 + 1, it)); +// +// parseHeader(buff.begin(), headerIt, _headers); +// +//} void TC_HttpResponse::reset() { @@ -1228,19 +1297,28 @@ void TC_HttpResponse::addContent(const string &sBuffer) _iRecvContentLength += sBuffer.length(); } -bool TC_HttpResponse::incrementDecode(string &sBuffer) +void TC_HttpResponse::addContent(const char *buffer, size_t length) { - //解析头部 - if(_headLength == 0) - { - string::size_type pos = sBuffer.find("\r\n\r\n"); + _content.append(buffer, length); - if(pos == string::npos) - { - return false; - } + _iRecvContentLength += length; +} - parseResponseHeader(sBuffer.c_str()); +bool TC_HttpResponse::incrementDecode(TC_NetWorkBuffer &buff) +{ + //解析头部 + if (_headLength == 0) + { + const static string sep = "\r\n\r\n"; + + auto sit = std::search(buff.begin(), buff.end(), sep.c_str(), sep.c_str() + sep.size()); + + if (sit == buff.end()) + { + return false; + } + + parseResponseHeader(buff.begin(), sit + 2); if ( (204 == _status) || (304 == _status) ) { @@ -1258,9 +1336,9 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) _iTmpContentLength = -1; } - _headLength = pos + 4; + _headLength = sit - buff.begin() + 4; - sBuffer = sBuffer.substr(_headLength); + buff.moveHeader(_headLength); //重定向就认为成功了 if((_status == 301 || _status == 302) && !getHeader("Location").empty()) @@ -1275,35 +1353,346 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) eraseHeader("Transfer-Encoding"); } - if(_bIsChunked) + if (_bIsChunked) + { + while (true) + { + const static string sep = "\r\n"; + + auto sit = std::search(buff.begin(), buff.end(), sep.c_str(), sep.c_str() + sep.size()); + + if (sit == buff.end()) + { + return false; + } + + string header = buff.iteratorToIterator(buff.begin(), sit); + + int iChunkSize = strtol(header.c_str(), NULL, 16); + + if (iChunkSize <= 0) + { + break; //所有chunk都接收完毕 + } + + if (buff.getBufferLength() < header.size() + 2 + (size_t)iChunkSize + 2) + { + //没有接收完整的chunk + return false; + } + + //接收到一个完整的chunk了 + buff.moveHeader(header.size() + 2); + addContent(buff.getHeader(iChunkSize)); + + //删除一个chunk + buff.moveHeader(iChunkSize + 2); + } + + buff.clearBuffers(); + + //接收到buffer长度设置好 + setContentLength(_iRecvContentLength); + + return true; + } + else + { + if (_iTmpContentLength == 0) + { + //header长度为0, 但是有body数据 + addContent(buff.getBuffersString()); + + buff.clearBuffers(); + + setContentLength(_iRecvContentLength); + + return true; + } + else if (_iTmpContentLength == (size_t) - 1) + { + //304的返回码中头没有Content-Length,不会有数据体 + if (_status == 304 || _status == 302) + { + return true; + } + + //header中没长度, 但是有body数据 + addContent(buff.getBuffersString()); + + buff.clearBuffers(); + + setContentLength(_iRecvContentLength); + + return true; + } + else + { + //头部有长度, 接收到长度大于头部为止 + addContent(buff.getBuffersString()); + + buff.clearBuffers(); + + //头部的长度小于接收的内容, 还需要继续增加解析后续的buffer + if (_iTmpContentLength > _iRecvContentLength) + return false; + + return true; + } + } + + return true; +} +// +//bool TC_HttpResponse::incrementDecode(string &sBuffer) +//{ +// //解析头部 +// if (_headLength == 0) +// { +// string::size_type pos = sBuffer.find("\r\n\r\n"); +// +// if (pos == string::npos) +// { +// return false; +// } +// +// parseResponseHeader(sBuffer.c_str()); +// +// //304的返回码中头里本来就没有Content-Length,也不会有数据体,头收全了就是真正的收全了 +// if ( (204 == _status) || (304 == _status) ) +// { +// return true; +// } +// +// http_header_type::const_iterator it = _headers.find("Content-Length"); +// if (it != _headers.end()) +// { +// _iTmpContentLength = getContentLength(); +// } +// else +// { +// //没有指明ContentLength, 接收到服务器关闭连接 +// _iTmpContentLength = -1; +// } +// +// _headLength = pos + 4; +// +// sBuffer = sBuffer.substr(_headLength); +// +// //重定向就认为成功了 +// if ((_status == 301 || _status == 302) && !getHeader("Location").empty()) +// { +// return true; +// } +// +// //是否是chunk编码 +// _bIsChunked = (getHeader("Transfer-Encoding") == "chunked"); +// +// //删除头部里面 +// eraseHeader("Transfer-Encoding"); +// } +// +// if (_bIsChunked) +// { +// while (true) +// { +// string::size_type pos = sBuffer.find("\r\n"); +// if (pos == string::npos) +// return false; +// +// //查找当前chunk的大小 +// string sChunkSize = sBuffer.substr(0, pos); +// int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16); +// +// if (iChunkSize <= 0) break; //所有chunk都接收完毕 +// +// if (sBuffer.length() < pos + 2 + (size_t)iChunkSize + 2) +// { +// //没有接收完整的chunk +// return false; +// } +// +// //接收到一个完整的chunk了 +// addContent(sBuffer.substr(pos + 2, iChunkSize)); +// +// //删除一个chunk +// sBuffer = sBuffer.substr(pos + 2 + iChunkSize + 2); +// +// // _content += sBuffer.substr(pos + 2, iChunkSize); +// // //删除一个chunk +// // sBuffer = sBuffer.substr(pos + 2 + iChunkSize + 2); +// // setContentLength(getContent().length()); +// } +// +// sBuffer = ""; +// +// //接收到buffer长度设置好 +// setContentLength(_iRecvContentLength); +// +// return true; +// } +// else +// { +// if (_iTmpContentLength == 0) +// { +// //header长度为0, 但是有body数据 +// addContent(sBuffer); +// +// sBuffer = ""; +// +// setContentLength(_iRecvContentLength); +// +// // _content += sBuffer; +// // sBuffer = ""; +// +// // //自动填写content-length +// // setContentLength(getContent().length()); +// +// return true; +// } +// else if (_iTmpContentLength == (size_t) - 1) +// { +// //304的返回码中头没有Content-Length,不会有数据体 +// if (_status == 304 || _status == 302) +// { +// return true; +// } +// +// //header中没长度, 但是有body数据 +// addContent(sBuffer); +// +// sBuffer = ""; +// +// setContentLength(_iRecvContentLength); +// +// // _content += sBuffer; +// // sBuffer = ""; +// +// // //自动填写content-length +// // setContentLength(getContent().length()); +// +// return false; +// } +// else +// { +// //头部有长度, 接收到长度大于头部为止 +// addContent(sBuffer); +// sBuffer = ""; +// +// // _content += sBuffer; +// // sBuffer = ""; +// +// // size_t iNowLength = getContent().length(); +// +// //头部的长度小于接收的内容, 还需要继续增加解析后续的buffer +// if (_iTmpContentLength > _iRecvContentLength) +// return false; +// +// return true; +// } +// } +// +// return true; + +//} + +bool TC_HttpResponse::decode(const string &sBuffer) +{ + return decode(sBuffer.c_str(), sBuffer.length()); +// +// string::size_type pos = sBuffer.find("\r\n\r\n"); +// +// if (pos == string::npos) +// { +// return false; +// } +// +// string tmp = sBuffer; +// +// incrementDecode(tmp); +// +// //body内容长度为0或者没有content-length 且 非chunk模式, 则认为包收全了, 直接返回 +// if ((_iTmpContentLength == 0 || _iTmpContentLength == (size_t) - 1) && !_bIsChunked) +// return true; +// +// return getContentLength() + getHeadLength() <= sBuffer.length(); +} + +bool TC_HttpResponse::decode(const char *sBuffer, size_t iLength) +{ + assert(sBuffer != NULL); + + const char *p = strstr(sBuffer, "\r\n\r\n"); + if ( p == NULL) { - while(true) + return false; + } + + //解析头部 + parseResponseHeader(sBuffer, p + 2); + + //304的返回码中头里本来就没有Content-Length,也不会有数据体,头收全了就是真正的收全了 + if ( (204 == _status) || (304 == _status) ) + { + return true; + } + + http_header_type::const_iterator it = _headers.find("Content-Length"); + if (it != _headers.end()) + { + _iTmpContentLength = getContentLength(); + } + else + { + //没有指明ContentLength, 接收到服务器关闭连接 + _iTmpContentLength = -1; + } + + _headLength = p - sBuffer + 4; + + sBuffer += _headLength; + + //重定向就认为成功了 + if ((_status == 301 || _status == 302) && !getHeader("Location").empty()) + { + return true; + } + + //是否是chunk编码 + _bIsChunked = (getHeader("Transfer-Encoding") == "chunked"); + + //删除头部里面 + eraseHeader("Transfer-Encoding"); + + if (_bIsChunked) + { + while (true) { - string::size_type pos = sBuffer.find("\r\n"); - if(pos == string::npos) + p = strstr(sBuffer, "\r\n"); + if (p == NULL) return false; + size_t pos = p - sBuffer; + //查找当前chunk的大小 - string sChunkSize = sBuffer.substr(0, pos); - int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16); + string sChunkSize; + sChunkSize.insert(sChunkSize.end(), sBuffer, p); + int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16); if(iChunkSize <= 0) break; //所有chunk都接收完毕 - if (sBuffer.length() < pos + 2 + (size_t)iChunkSize + 2) + if (strlen(sBuffer) < pos + 2 + (size_t)iChunkSize + 2) { - //获取一个chunk的内容 - - //删除一个chunk //没有接收完整的chunk return false; } - addContent(sBuffer.substr(pos + 2, iChunkSize)); - sBuffer = sBuffer.substr(pos + 2 + iChunkSize + 2); - // setContentLength(getContent().length()); - } + //接收到一个完整的chunk了 + addContent(p + 2, iChunkSize); - sBuffer = ""; + //删除一个chunk + sBuffer += pos + 2 + iChunkSize + 2; + } //接收到buffer长度设置好 setContentLength(_iRecvContentLength); @@ -1316,11 +1705,8 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) { //header长度为0, 但是有body数据 addContent(sBuffer); - sBuffer = ""; setContentLength(_iRecvContentLength); - //自动填写content-length - // setContentLength(getContent().length()); return true; } @@ -1334,69 +1720,22 @@ bool TC_HttpResponse::incrementDecode(string &sBuffer) //header中没长度, 但是有body数据 addContent(sBuffer); - sBuffer = ""; setContentLength(_iRecvContentLength); - //自动填写content-length - // setContentLength(getContent().length()); - - return false; } else { //头部有长度, 接收到长度大于头部为止 addContent(sBuffer); - sBuffer = ""; - - // size_t iNowLength = getContent().length(); //头部的长度小于接收的内容, 还需要继续增加解析后续的buffer - if (_iTmpContentLength > _iRecvContentLength) - return false; - - return true; + if (_iTmpContentLength <= _iRecvContentLength) + return true; } } - return true; -} - -bool TC_HttpResponse::decode(const string &sBuffer) -{ - string::size_type pos = sBuffer.find("\r\n\r\n"); - - if(pos == string::npos) - { - return false; - } - - string tmp = sBuffer; - - incrementDecode(tmp); - //body内容长度为0或者没有content-length 且 非chunk模式, 则认为包收全了, 直接返回 - if((_iTmpContentLength == 0 || _iTmpContentLength == (size_t)-1) && !_bIsChunked) - return true; - - return getContentLength() + getHeadLength() <= sBuffer.length(); -} - -bool TC_HttpResponse::decode(const char *sBuffer, size_t iLength) -{ - assert(sBuffer != NULL); - - const char *p = strstr(sBuffer, "\r\n\r\n"); - if( p == NULL) - { - return false; - } - - string tmp(sBuffer, iLength); - - incrementDecode(tmp); - - //body内容长度为0或者没有content-length 且 非chunk模式, 则认为包收全了, 直接返回 - if((_iTmpContentLength == 0 || _iTmpContentLength == (size_t)-1) && !_bIsChunked) + if ((_iTmpContentLength == 0 || _iTmpContentLength == (size_t) - 1) && !_bIsChunked) return true; return (getContentLength() + getHeadLength() <= iLength); @@ -1404,25 +1743,25 @@ bool TC_HttpResponse::decode(const char *sBuffer, size_t iLength) string TC_HttpResponse::encode() const { - string sRet; - sRet += _version; - sRet += " "; - sRet += TC_Common::tostr(_status); - sRet += " "; - sRet += _about; - sRet += "\r\n"; - sRet += genHeader(); - sRet += "\r\n"; - sRet += _content; + stringstream sRet; + sRet << _version; + sRet << " "; + sRet << TC_Common::tostr(_status); + sRet << " "; + sRet << _about; + sRet << "\r\n"; + sRet << genHeader(); + sRet << "\r\n"; + sRet << _content; - return sRet; + return sRet.str(); } void TC_HttpResponse::encode(vector &buffer) const { buffer.clear(); - string s = encode(); + string s = encode(); buffer.resize(s.length()); memcpy(buffer.data(), s.c_str(), s.length()); @@ -1714,98 +2053,75 @@ void TC_HttpRequest::setDeleteRequest(const string &sUrl, const string &sPostBod string TC_HttpRequest::encode() { -// assert(_requestType == REQUEST_GET || _requestType == REQUEST_POST || !_originRequest.empty()); - - /*ostringstream os; + stringstream sRet; if(_requestType == REQUEST_GET) { - encode(REQUEST_GET, os); + sRet << requestType2str(_requestType); + sRet << " "; + sRet << _httpURL.getRequest(); + sRet << " HTTP/1.1\r\n"; + sRet << genHeader(); + sRet << "\r\n"; } else if(_requestType == REQUEST_POST) { setContentLength(_content.length()); - encode(REQUEST_POST, os); - os << _content; + sRet << requestType2str(_requestType); + sRet << " "; + sRet << _httpURL.getRequest(); + sRet << " HTTP/1.1\r\n"; + sRet << genHeader(); + sRet << "\r\n"; + sRet << _content; } else if(_requestType == REQUEST_OPTIONS) { - encode(REQUEST_OPTIONS, os); - } - - return os.str();*/ - string sRet; - - if(_requestType == REQUEST_GET) - { - //encode(REQUEST_GET, os); - sRet += requestType2str(_requestType); - sRet += " "; - sRet += _httpURL.getRequest(); - sRet += " HTTP/1.1\r\n"; - sRet += genHeader(); - sRet += "\r\n"; - } - else if(_requestType == REQUEST_POST) - { - setContentLength(_content.length()); - //encode(REQUEST_POST, os); - sRet += requestType2str(_requestType); - sRet += " "; - sRet += _httpURL.getRequest(); - sRet += " HTTP/1.1\r\n"; - sRet += genHeader(); - sRet += "\r\n"; - sRet += _content; - } - else if(_requestType == REQUEST_OPTIONS) - { - //encode(REQUEST_OPTIONS, os); - sRet += requestType2str(_requestType); - sRet += " "; - sRet += _httpURL.getRequest(); - sRet += " HTTP/1.1\r\n"; - sRet += genHeader(); - sRet += "\r\n"; + sRet << requestType2str(_requestType); + sRet << " "; + sRet << _httpURL.getRequest(); + sRet << " HTTP/1.1\r\n"; + sRet << genHeader(); + sRet << "\r\n"; } else if(_requestType == REQUEST_HEAD) { - sRet += requestType2str(_requestType); - sRet += " "; - sRet += _httpURL.getRequest(); - sRet += " HTTP/1.1\r\n"; - sRet += genHeader(); - sRet += "\r\n"; + sRet << requestType2str(_requestType); + sRet << " "; + sRet << _httpURL.getRequest(); + sRet << " HTTP/1.1\r\n"; + sRet << genHeader(); + sRet << "\r\n"; } else if(_requestType == REQUEST_PUT || _requestType == REQUEST_PATCH) { setContentLength(_content.length()); - sRet += requestType2str(_requestType); - sRet += " "; - sRet += _httpURL.getRequest(); - sRet += " HTTP/1.1\r\n"; - sRet += genHeader(); - sRet += "\r\n"; - sRet += _content; + sRet << requestType2str(_requestType); + sRet << " "; + sRet << _httpURL.getRequest(); + sRet << " HTTP/1.1\r\n"; + sRet << genHeader(); + sRet << "\r\n"; + sRet << _content; } else if(_requestType == REQUEST_DELETE) { setContentLength(_content.length()); - //encode(REQUEST_GET, os); - sRet += requestType2str(_requestType); - sRet += " "; - sRet += _httpURL.getRequest(); - sRet += " HTTP/1.1\r\n"; - sRet += genHeader(); - sRet += "\r\n"; - sRet += _content; + sRet << requestType2str(_requestType); + sRet << " "; + sRet << _httpURL.getRequest(); + sRet << " HTTP/1.1\r\n"; + sRet << genHeader(); + sRet << "\r\n"; + sRet << _content; } - - return sRet; + return sRet.str(); } void TC_HttpRequest::encode(vector &buffer) { +// assert(_requestType == REQUEST_GET || _requestType == REQUEST_POST || !_originRequest.empty()); + buffer.clear(); string s = encode(); @@ -1813,6 +2129,11 @@ void TC_HttpRequest::encode(vector &buffer) memcpy(buffer.data(), s.c_str(), s.length()); } +void TC_HttpRequest::encode(TC_NetWorkBuffer &buff) +{ + buff.addBuffer(std::move(encode())); +} + bool TC_HttpRequest::decode(const string &sBuffer) { return decode(sBuffer.c_str(), sBuffer.length()); @@ -1831,18 +2152,21 @@ bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength) TC_Port::strncasecmp(sBuffer, "DELETE " , 7) !=0 && TC_Port::strncasecmp(sBuffer, "HEAD " ,5)) { - throw runtime_error("[TC_HttpRequest::checkRequest] protocol not support, only support GET HEAD POST and OPTIONS "); + throw runtime_error("[TC_HttpRequest::decode] protocol not support, only support GET HEAD POST and OPTIONS "); } - - if(strstr(sBuffer, "\r\n\r\n") == NULL) + const char *p = strstr(sBuffer, "\r\n\r\n"); + if (p == NULL) { return false; } - _headLength = parseRequestHeader(sBuffer); + parseRequestHeader(sBuffer, p); + + _headLength = p - sBuffer + 4; + + bool bChunk = (getHeader("Transfer-Encoding") == "chunked"); - bool bChunk = (getHeader("Transfer-Encoding") == "chunked"); int iChunkSuffixLen = 0; if(bChunk) @@ -1891,9 +2215,161 @@ bool TC_HttpRequest::decode(const char *sBuffer, size_t iLength) return (getContentLength() + getHeadLength() + iChunkSuffixLen == iLength); } +bool TC_HttpRequest::checkRequest(TC_NetWorkBuffer &buff) +{ + if(buff.getBufferLength() < 10) + return false; + + auto data = buff.getBufferPointer(); + if(TC_Port::strncasecmp(data.first, "GET " ,4) !=0 && + TC_Port::strncasecmp(data.first, "POST " ,5) !=0 && + TC_Port::strncasecmp(data.first, "PUT " ,4) !=0 && + TC_Port::strncasecmp(data.first, "PATCH " ,6) !=0 && + TC_Port::strncasecmp(data.first, "OPTIONS " ,8) !=0 && + TC_Port::strncasecmp(data.first, "PRI " , 4) !=0 && + TC_Port::strncasecmp(data.first, "DELETE " , 7) !=0 && + TC_Port::strncasecmp(data.first, "HEAD " ,5)) + { + throw runtime_error("[TC_HttpRequest::decode] protocol not support, only support GET HEAD POST PUT PATCH DELETE and OPTIONS "); + } + + string sep = "\r\n\r\n"; + + auto sit = buff.find(sep.c_str(), sep.size()); + if ( sit == buff.end()) + { + return false; + } + + size_t pos = sit - buff.begin(); + + size_t iHeadLen = pos + 4; + + bool bChunk = false; + + sep = "\r\n"; + + auto it = std::search(buff.begin(), buff.end(), sep.c_str(), sep.c_str() + sep.size()); + if(it == buff.end()) + { + //first line + return false; + } + + it = it + sep.size(); + +// cout << buff.iteratorToIterator(buff.begin(), it) << endl; + size_t len = 0; + + //找到\r\n\r\n之前的长度表示 + while (true) + { + size_t iMoveLen = it - buff.begin(); + if (iMoveLen >= iHeadLen) + { + break; + } + + + auto lineItStart = it; + + auto lineItEnd = std::search(lineItStart, buff.end(), sep.c_str(), sep.c_str() + sep.size()); + + if (lineItEnd != buff.end()) + { + it = lineItEnd + sep.size(); + + std::function cmp = [](char i, char j) + { + + return toupper(i) == toupper(j); + }; + + const char *TE = "Transfer-Encoding:"; + + auto itTE = std::search(lineItStart, lineItEnd, TE, TE + strlen(TE), cmp); + + if (itTE != lineItEnd) + { + const char *CH = "chunked"; + + auto itCH = std::search(lineItStart + strlen(TE), lineItEnd, CH, CH + strlen(CH), cmp); + + if (itCH != lineItEnd) + { + bChunk = true; + break; + } + } + + const char *CL = "Content-Length:"; + + auto itCL = std::search(lineItStart, lineItEnd, CL, CL + strlen(CL), cmp); + if (itCL == lineItEnd) + { + continue; + } + + string contentLength; + contentLength.resize(lineItEnd - lineItStart - strlen(CL)); + std::copy(lineItStart + strlen(CL), lineItEnd, contentLength.begin()); + + len = TC_Common::strto(TC_Common::trim(contentLength, " ")); + } + + } + + if (bChunk) + { + int remain_len = buff.getBufferLength() - iHeadLen; + int move_len = 0; + + auto it = sit + 4; + while (true) + { + auto lineIt = std::search(it, buff.end(), sep.c_str(), sep.c_str() + sep.size()); + if ( lineIt == buff.end() ) + { + return false; + } + + //查找当前chunk的大小 + string contentLength; + contentLength.resize(lineIt - it); + std::copy(it, lineIt, contentLength.begin()); + + int iChunkSize = strtol(contentLength.c_str(), NULL, 16); + if (iChunkSize <= 0) + { + return true; //所有chunk都接收完毕 + } + + move_len = (lineIt - it) + 2 + iChunkSize + 2; + if ( remain_len >= move_len ) //接收到一个完整的chunk了 + { + //移动到下一个chunk + remain_len -= move_len; + it = lineIt + 2 + iChunkSize + 2; + } + else + { + return false; + } + } + } + else if (len + pos + 4 <= buff.getBufferLength()) + { + return true; + } + + return false; +} bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen) { + if(iLen < 10) + return false; + if(TC_Port::strncasecmp(sBuffer, "GET " ,4) !=0 && TC_Port::strncasecmp(sBuffer, "POST " ,5) !=0 && TC_Port::strncasecmp(sBuffer, "PUT " ,4) !=0 && @@ -1903,102 +2379,70 @@ bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen) TC_Port::strncasecmp(sBuffer, "DELETE " , 7) !=0 && TC_Port::strncasecmp(sBuffer, "HEAD " ,5)) { - throw runtime_error("[TC_HttpRequest::checkRequest] protocol not support, only support GET HEAD POST PUT PATCH DELETE and OPTIONS "); + throw runtime_error("[TC_HttpRequest::decode] protocol not support:" + string(sBuffer, 8)); } - const char *p = strstr(sBuffer, "\r\n\r\n"); - if( p == NULL) - { - return false; - } - - size_t pos = p - sBuffer; - - size_t iHeadLen= pos + 4; - - const char **ppChar = &sBuffer; - - bool bChunk = false; - - //找到\r\n\r\n之前的长度表示 - while(true) - { - size_t iMoveLen= (*ppChar) - sBuffer; - if ( iMoveLen >= iHeadLen ) - { - //MTT_ERRDAY << "parseHttp WARN: iMoveLen >= iLen" << "|" << iMoveLen << "|" <(TC_Common::trim(sLine.substr(15), " ")); - } - - if(len + pos + 4 <= iLen) - { - return true; - } - else - { - break; - - } - } - -/* - if(bChunk) + const char *header = strstr(sBuffer, "\r\n\r\n"); + if ( header == NULL) { - string sTmp = string(p + 4, iLen - iHeadLen); - while(true) + return false; + } + + size_t pos = header - sBuffer; + + size_t iHeadLen = pos + 4; + + const char *p = strstr(sBuffer, "\r\n"); + if(p == NULL) + { + //first line + return false; + } + + p += 2; + + bool bChunk = false; + + size_t len = 0; + + //找到\r\n\r\n之前的长度表示 + while (true) + { + size_t iMoveLen = p - sBuffer; + if ( iMoveLen >= iHeadLen ) { - string::size_type pos = sTmp.find("\r\n"); - if(pos == string::npos) - { - return false; - } + break; + } - //查找当前chunk的大小 - string sChunkSize = sTmp.substr(0, pos); - int iChunkSize = strtol(sChunkSize.c_str(), NULL, 16); + const char *line = p; + const char *lineEnd = strstr(line, "\r\n"); + if (lineEnd != NULL) + { + p = lineEnd + 2; - if(iChunkSize <= 0) + if (TC_Port::strncasecmp(line, "Transfer-Encoding:", 18) == 0) + { + string chunked = TC_Common::trim(string(line + 18, lineEnd)); + bChunk = (chunked == "chunked"); + if (bChunk) break; + } + else if (TC_Port::strncasecmp(line, "Content-Length:", 15) != 0) + { + continue; + } + else { - return true; //所有chunk都接收完毕 - } - if(sTmp.length() >= pos + 2 + (size_t)iChunkSize + 2) //接收到一个完整的chunk了 - { - //删除一个chunk - sTmp = sTmp.substr(pos + 2 + iChunkSize + 2); - } - else - { - return false; - } + len = TC_Common::strto(TC_Common::trim(string(line + 15, lineEnd), " ")); + } } } -*/ - if(bChunk) + + if (bChunk) { int remain_len = iLen - iHeadLen; int move_len = 0; - const char * pCur = p + 4; - while(true) + const char * pCur = header + 4; + while (true) { p = strstr(pCur , "\r\n"); if( p == NULL ) @@ -2026,75 +2470,83 @@ bool TC_HttpRequest::checkRequest(const char* sBuffer, size_t iLen) } } } + else if (len + pos + 4 <= iLen) + { + return true; + } return false; -// throw TC_HttpRequest_Exception("[TC_HttpRequest::checkRequest] Content-Length not exists."); - -// return true; } - -size_t TC_HttpRequest::parseRequestHeader(const char* szBuffer) +void TC_HttpRequest::parseRequestHeader(const char* szBuffer, const char *header) { - const char *szBuffer_copy = szBuffer; - const char **ppChar = &szBuffer; +// const char *szBuffer_copy = szBuffer; +// const char **ppChar = &szBuffer; - /* parse the first line and get status */ - string sLine = getLine(ppChar); + const char *p = strstr(szBuffer, "\r\n"); - string::size_type pos = sLine.find(" "); - if(pos == string::npos) - { - throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + sLine); - } + assert(p != NULL); - string sMethod = TC_Common::trim(sLine.substr(0, pos)); + + const char * sMethod = szBuffer; //解析请求类型 - if(TC_Port::strncasecmp(sMethod.c_str(), "GET", 3) ==0) //if(sMethod == "GET") + if(TC_Port::strncasecmp(sMethod, "GET ", 4) ==0) //if(sMethod == "GET") { _requestType = REQUEST_GET; } - else if(TC_Port::strncasecmp(sMethod.c_str(), "POST", 4) ==0) //else if(sMethod == "POST") + else if(TC_Port::strncasecmp(sMethod, "POST ", 5) ==0) //else if(sMethod == "POST") { _requestType = REQUEST_POST; } - else if(TC_Port::strncasecmp(sMethod.c_str(), "PUT", 3) ==0) + else if(TC_Port::strncasecmp(sMethod, "PUT ", 4) ==0) { _requestType = REQUEST_PUT; } - else if(TC_Port::strncasecmp(sMethod.c_str(), "PATCH", 5) ==0) + else if(TC_Port::strncasecmp(sMethod, "PATCH ", 6) ==0) { _requestType = REQUEST_PATCH; } - else if(TC_Port::strncasecmp(sMethod.c_str(), "OPTIONS", 7) ==0) //else if(sMethod == "OPTIONS") + else if(TC_Port::strncasecmp(sMethod, "OPTIONS ", 8) ==0) //else if(sMethod == "OPTIONS") { _requestType = REQUEST_OPTIONS; } - else if(TC_Port::strncasecmp(sMethod.c_str(), "HEAD", 4) == 0) + else if(TC_Port::strncasecmp(sMethod, "HEAD ", 5) == 0) { _requestType = REQUEST_HEAD; } - else if(TC_Port::strncasecmp(sMethod.c_str(), "DELETE", 6) == 0) + else if(TC_Port::strncasecmp(sMethod, "DELETE ", 7) == 0) { _requestType = REQUEST_DELETE; } else { - throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request command error: " + sMethod); + throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request error: " + string(szBuffer, p - szBuffer)); } - string::size_type pos1 = sLine.rfind(" "); - if(pos1 == string::npos || pos1 <= pos) - { - throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + sLine); - } + string sep = " "; + auto f1 = std::search(szBuffer, p, sep.c_str(), sep.c_str() + sep.size()); + if (f1 == p) + { + throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + string(szBuffer, p - szBuffer)); + } + + auto f2 = std::search(f1 + 1, p, sep.c_str(), sep.c_str() + sep.size()); + if (f2 == p || f1 >= f2) + { + throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + string(szBuffer, p - szBuffer)); + } +// string::size_type pos1 = sLine.rfind(" "); +// if (pos1 == string::npos || pos1 <= pos) +// { +// throw TC_HttpRequest_Exception("[TC_HttpRequest::parseRequestHeader] http request format error: " + sLine); +// } //URL地址 - string sURL = TC_Common::trim(sLine.substr(pos+1, pos1 - pos)); + string sURL = string(f1 + 1, f2 - f1 -1 ); //TC_Common::trim(sLine.substr(pos + 1, pos1 - pos)); //HTTP协议版本 - string sVersion = TC_Common::trim(sLine.substr(pos1 + 1)); + string sVersion = string(f2 + 1, p); //TC_Common::trim(sLine.substr(pos1 + 1)); // if (sVersion != "HTTP/1.1" || sVersion != "HTTP/1.0") if (TC_Port::strncasecmp(sVersion.c_str(), "HTTP/1.1", 8) != 0 || TC_Port::strncasecmp(sVersion.c_str(), "HTTP/1.0", 8) != 0) @@ -2102,7 +2554,8 @@ size_t TC_HttpRequest::parseRequestHeader(const char* szBuffer) sVersion = "HTTP/1.1"; } - size_t n = parseHeader(*ppChar, _headers) - szBuffer_copy; + parseHeader(szBuffer, header, _headers); +// size_t n = parseHeader(*ppChar, _headers) - szBuffer_copy; if(TC_Port::strncasecmp(sURL.c_str(), "https://", 8) !=0 ) { @@ -2114,7 +2567,7 @@ size_t TC_HttpRequest::parseRequestHeader(const char* szBuffer) parseURL(sURL); - return n; +// return header - szBuffer; } void TC_HttpRequest::getHostPort(string &sDomain, uint32_t &iPort) @@ -2191,35 +2644,32 @@ int TC_HttpRequest::doRequest(TC_TCPClient& tcpClient, TC_HttpResponse& stHttpRs stHttpRsp.reset(); - string sBuffer; - - char* sTmpBuffer = new char[10240]; - size_t iRecvLen = 10240; + TC_NetWorkBuffer recvBuffer(NULL); while (true) { - iRecvLen = 10240; + char buffer[8*1024]; + size_t iRecvLen = sizeof(buffer); - iRet = tcpClient.recv(sTmpBuffer, iRecvLen); + iRet = tcpClient.recv(buffer, iRecvLen); if (iRet == TC_ClientSocket::EM_SUCCESS) - sBuffer.append(sTmpBuffer, iRecvLen); + { + recvBuffer.addBuffer(buffer, iRecvLen); + } switch (iRet) { case TC_ClientSocket::EM_SUCCESS: - if (stHttpRsp.incrementDecode(sBuffer)) + if (stHttpRsp.incrementDecode(recvBuffer)) { - delete[]sTmpBuffer; return TC_ClientSocket::EM_SUCCESS; } continue; case TC_ClientSocket::EM_CLOSE: - delete[]sTmpBuffer; - stHttpRsp.incrementDecode(sBuffer); + stHttpRsp.incrementDecode(recvBuffer); return TC_ClientSocket::EM_SUCCESS; default: - delete[]sTmpBuffer; return iRet; } } @@ -2242,10 +2692,6 @@ int TC_HttpRequest::doRequest(TC_HttpResponse &stHttpRsp, int iTimeout) getHostPort(sHost, iPort); TC_TCPClient tcpClient; -// if (_client == NULL) - // { - // _client = new TC_TCPClient(); - // } tcpClient.init(sHost, iPort, iTimeout); int iRet = tcpClient.send(sSendBuffer.c_str(), sSendBuffer.length()); @@ -2256,35 +2702,32 @@ int TC_HttpRequest::doRequest(TC_HttpResponse &stHttpRsp, int iTimeout) stHttpRsp.reset(); - string sBuffer; - - char *sTmpBuffer = new char[10240]; - size_t iRecvLen = 10240; + TC_NetWorkBuffer recvBuffer(NULL); while(true) { - iRecvLen = 10240; + char buffer[8*1024]; + size_t iRecvLen = sizeof(buffer); - iRet = tcpClient.recv(sTmpBuffer, iRecvLen); + iRet = tcpClient.recv(buffer, iRecvLen); - if(iRet == TC_ClientSocket::EM_SUCCESS) - sBuffer.append(sTmpBuffer, iRecvLen); + if (iRet == TC_ClientSocket::EM_SUCCESS) + { + recvBuffer.addBuffer(buffer, iRecvLen); + } - switch(iRet) + switch (iRet) { case TC_ClientSocket::EM_SUCCESS: - if(stHttpRsp.incrementDecode(sBuffer)) + if (stHttpRsp.incrementDecode(recvBuffer)) { - delete []sTmpBuffer; return TC_ClientSocket::EM_SUCCESS; } continue; case TC_ClientSocket::EM_CLOSE: - delete []sTmpBuffer; - stHttpRsp.incrementDecode(sBuffer); + stHttpRsp.incrementDecode(recvBuffer); return TC_ClientSocket::EM_SUCCESS; default: - delete []sTmpBuffer; return iRet; } } diff --git a/util/src/tc_http_async.cpp b/util/src/tc_http_async.cpp index 0d13874..ee4ad7b 100644 --- a/util/src/tc_http_async.cpp +++ b/util/src/tc_http_async.cpp @@ -22,26 +22,56 @@ namespace tars { TC_HttpAsync::AsyncRequest::AsyncRequest(TC_HttpRequest &stHttpRequest, TC_HttpAsync::RequestCallbackPtr &callbackPtr, bool bUseProxy) - : _pHttpAsync(NULL), _iUniqId(0), _callbackPtr(callbackPtr), _bUseProxy(bUseProxy), _isConnected(false) +: _pHttpAsync(NULL) +, _iUniqId(0) +, _sendBuffer(this) +, _recvBuffer(this) +, _callbackPtr(callbackPtr) +, _bUseProxy(bUseProxy) +, _isConnected(false) { memset(&_bindAddr, 0, sizeof(struct sockaddr)); _bindAddrSet = false; - _sReq = stHttpRequest.encode(); + vector buff; + stHttpRequest.encode(buff); + + _sendBuffer.addBuffer(std::move(buff)); stHttpRequest.getHostPort(_sHost, _iPort); +} - // _notify.createSocket(); +TC_HttpAsync::AsyncRequest::AsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallbackPtr &callbackPtr, const string &addr) +: _pHttpAsync(NULL) +, _iUniqId(0) +, _sendBuffer(this) +, _recvBuffer(this) +, _callbackPtr(callbackPtr) +, _bUseProxy(false) +, _isConnected(false) +{ + memset(&_bindAddr, 0, sizeof(struct sockaddr)); + + _bindAddrSet = false; + + stHttpRequest.encode(_sendBuffer); + + vector v = TC_Common::sepstr(addr, ":"); + + if (v.size() < 2) + { + stHttpRequest.getHostPort(_sHost, _iPort); + } + else + { + _sHost = v[0]; + _iPort = TC_Common::strto(v[1]); + } } TC_HttpAsync::AsyncRequest::~AsyncRequest() { doClose(); - - // if (_pHttpAsync) - // _pHttpAsync->delConnection(_notify.getfd()); - - // _notify.close(); } void TC_HttpAsync::AsyncRequest::doClose() @@ -154,41 +184,16 @@ void TC_HttpAsync::AsyncRequest::timeout() } -string TC_HttpAsync::AsyncRequest::getError(const char* sDefault) const +string TC_HttpAsync::AsyncRequest::getError(const string &sDefault) const { int ret = TC_Exception::getSystemCode(); if(ret!= 0) { - return TC_Exception::parseError(ret); + return sDefault + ", ret:" + TC_Common::tostr(ret) + ", msg:" + TC_Exception::parseError(ret); } - return sDefault; + return sDefault + ", ret:" + TC_Common::tostr(ret); } -// string TC_HttpAsync::AsyncRequest::getError(const string &sDefault) const -// { -// string err; - -// if (_fd.isValid()) -// { -// int error; -// SOCKET_LEN_TYPE len = sizeof(error); -// _fd.getSockOpt(SO_ERROR, (void*)&error, len, SOL_SOCKET); -// if (error != 0) -// { -// err = strerror(error); -// } -// } - -// if (err.empty() && errno != 0) -// { -// err = strerror(errno); -// } - -// if (err.empty()) -// err = sDefault; - -// return err; -// } void TC_HttpAsync::AsyncRequest::doException(RequestCallback::FAILED_CODE ret, const string &e) { @@ -210,14 +215,15 @@ void TC_HttpAsync::AsyncRequest::doRequest() { ret = -1; - if (!_sReq.empty()) + if (!_sendBuffer.empty()) { - if ((ret = this->send(_sReq.c_str(), _sReq.length(), 0)) > 0) + auto data = _sendBuffer.getBufferPointer(); + if ((ret = this->send(data.first, data.second, 0)) > 0) { - _sReq = _sReq.substr(ret); + _sendBuffer.moveHeader(ret); } } - } while (ret > 0); + } while (ret > 0 && !_sendBuffer.empty()); //网络异常 if (ret == -2) @@ -239,19 +245,19 @@ void TC_HttpAsync::AsyncRequest::doReceive() { if ((recv = this->recv(buff, sizeof(buff), 0)) > 0) { - _sRsp.append(buff, recv); + _recvBuffer.addBuffer(buff, recv); } } while (recv > 0); if (recv == -2) { - doException(RequestCallback::Failed_Net, getError("recv error.")); + doException(RequestCallback::Failed_Net, getError("recv error")); } else { //增量decode - bool ret = _stHttpResp.incrementDecode(_sRsp); + bool ret = _stHttpResp.incrementDecode(_recvBuffer); //有头部数据了 if (_callbackPtr && !_stHttpResp.getHeaders().empty()) @@ -259,7 +265,7 @@ void TC_HttpAsync::AsyncRequest::doReceive() bool bContinue = _callbackPtr->onContinue(_stHttpResp); if (!bContinue) { - doException(RequestCallback::Failed_Interrupt, getError("receive interrupt.")); + doException(RequestCallback::Failed_Interrupt, getError("receive interrupt")); return; } } @@ -282,8 +288,6 @@ void TC_HttpAsync::AsyncRequest::doReceive() doClose(); try { if (_callbackPtr) _callbackPtr->onSucc(_stHttpResp); } catch (...) { } - - // doException(RequestCallback::Failed_Close, getError("close by server.")); } } } @@ -291,15 +295,19 @@ void TC_HttpAsync::AsyncRequest::doReceive() void TC_HttpAsync::AsyncRequest::processNet(const epoll_event &ev) { - if (TC_Epoller::readEvent(ev))//events & EPOLLIN) + if (TC_Epoller::errorEvent(ev)) + { + doException(RequestCallback::Failed_Net, getError("net error")); + return; + } + + if (TC_Epoller::readEvent(ev)) { - // cout << "readEvent" << endl; doReceive(); } if (TC_Epoller::writeEvent(ev)) { - // cout << "writeEvent" << endl; doRequest(); } } @@ -331,7 +339,7 @@ TC_HttpAsync::TC_HttpAsync() : _terminate(false) _data = new http_queue_type(10000); - _epoller.create(1024); + _epoller.create(20480); // _notify.createSocket(); _notify.init(&_epoller); @@ -348,7 +356,6 @@ TC_HttpAsync::~TC_HttpAsync() delete _data; - // _notify.close(); _notify.release(); _epoller.close(); @@ -359,9 +366,6 @@ void TC_HttpAsync::start() _tpool.init(1); _tpool.start(); - // TC_Functor cmd(this, &TC_HttpAsync::run); - // TC_Functor::wrapper_type wt(cmd); - _tpool.exec(std::bind(&TC_HttpAsync::run, this)); } @@ -435,7 +439,30 @@ void TC_HttpAsync::doAsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallback _events.push_back(H64(_notify.notifyFd()) | uniqId); } _notify.notify(); - // addConnection(req->getNotifyfd(), uniqId, EPOLLIN); +} + +void TC_HttpAsync::doAsyncRequest(TC_HttpRequest &stHttpRequest, RequestCallbackPtr &callbackPtr, const string &addr) +{ + AsyncRequest * req = new AsyncRequest(stHttpRequest, callbackPtr, addr); + + if (_bindAddrSet) + { + req->setBindAddr(&_bindAddr); + } + + uint32_t uniqId = _data->generateId(); + + req->setUniqId(uniqId); + + req->setHttpAsync(this); + + _data->push(req, uniqId); + + { + std::lock_guard lock(_mutex); + _events.push_back(H64(_notify.notifyFd()) | uniqId); + } + _notify.notify(); } void TC_HttpAsync::addConnection(int fd, uint32_t uniqId, uint32_t events) @@ -541,7 +568,6 @@ void TC_HttpAsync::run() if ((int)fd == _notify.notifyFd()) { - // cout << "notify" << endl; deque events; { @@ -554,7 +580,6 @@ void TC_HttpAsync::run() { uint32_t uniqId = (uint32_t)data; - // cout << "socket uniqId:" << uniqId << endl; AsyncRequestPtr ptr = _data->getAndRefresh(uniqId); if (!ptr) continue; @@ -568,13 +593,10 @@ void TC_HttpAsync::run() uint32_t uniqId = TC_Epoller::getU32(ev, false); - // cout << "http socket uniqId:" << uniqId << endl; - AsyncRequestPtr ptr = _data->getAndRefresh(uniqId); if (!ptr) continue; - // assert(fd == ptr->getfd()); ptr->processNet(ev); } } diff --git a/util/src/tc_network_buffer.cpp b/util/src/tc_network_buffer.cpp index 6b9006a..c20b872 100755 --- a/util/src/tc_network_buffer.cpp +++ b/util/src/tc_network_buffer.cpp @@ -12,20 +12,50 @@ namespace tars void TC_NetWorkBuffer::addBuffer(const shared_ptr & buff) { + if(buff->empty()) return; + _bufferList.push_back(buff); _length += buff->length(); } void TC_NetWorkBuffer::addBuffer(const vector& buff) { + if(buff.empty()) return; + _bufferList.push_back(std::make_shared(buff)); _length += buff.size(); } +void TC_NetWorkBuffer::addBuffer(const std::string& buff) +{ + if(buff.empty()) return; + + _bufferList.push_back(std::make_shared(buff.c_str(), buff.size())); + + _length += buff.size(); +} + void TC_NetWorkBuffer::addBuffer(const char* buff, size_t length) { - addBuffer(vector(buff, buff + length)); + if(buff == NULL || length == 0) return; + + addBuffer(vector(buff, buff + length)); +} + +TC_NetWorkBuffer::buffer_iterator TC_NetWorkBuffer::begin() const +{ + return buffer_iterator(this, 0); +} + +TC_NetWorkBuffer::buffer_iterator TC_NetWorkBuffer::end() const +{ + return buffer_iterator(this, this->getBufferLength()); +} + +TC_NetWorkBuffer::buffer_iterator TC_NetWorkBuffer::find(const char *str, size_t length) +{ + return std::search(begin(), end(), str, str + length); } void TC_NetWorkBuffer::clearBuffers() @@ -230,16 +260,7 @@ TC_NetWorkBuffer::PACKET_TYPE TC_NetWorkBuffer::checkHttp() { try { - mergeBuffers(); - - pair buffer = getBufferPointer(); - - if(buffer.first == NULL || buffer.second == 0) - { - return PACKET_LESS; - } - - bool b = TC_HttpRequest::checkRequest(buffer.first, buffer.second); + bool b = TC_HttpRequest::checkRequest(*this); return b ? PACKET_FULL : PACKET_LESS; }