mirror of
https://github.com/drogonframework/drogon.git
synced 2025-09-16 00:00:48 -04:00
Remove config.h
Modify the CMakeLists.txt Remove the USE_ORM macro Update trantor Remove some std::dynamic_pointer_cast calls
This commit is contained in:
parent
4599abf2f5
commit
40087fba9c
@ -15,6 +15,7 @@ addons:
|
||||
sources:
|
||||
- xenial
|
||||
- sourceline: 'deb http://archive.ubuntu.com/ubuntu xenial main'
|
||||
- sourceline: 'ppa:mhier/libboost-latest'
|
||||
packages:
|
||||
- gcc
|
||||
- g++
|
||||
@ -27,6 +28,7 @@ addons:
|
||||
- libsqlite3-dev
|
||||
- build-essential
|
||||
- cmake
|
||||
- boost1.67
|
||||
homebrew:
|
||||
packages:
|
||||
- jsoncpp
|
||||
|
483
CMakeLists.txt
483
CMakeLists.txt
@ -1,127 +1,158 @@
|
||||
cmake_minimum_required (VERSION 3.2)
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 3.2)
|
||||
|
||||
project (DROGON CXX)
|
||||
message (STATUS "os:" ${CMAKE_SYSTEM_NAME})
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
#Clang, use c++17
|
||||
set(CMAKE_CXX_STD_FLAGS c++17)
|
||||
set(CXX_STD 17)
|
||||
else()
|
||||
EXEC_PROGRAM (gcc ARGS "--version | grep '^gcc'|awk '{print $3}' | sed s'/)//g' | sed s'/-.*//g'" OUTPUT_VARIABLE version)
|
||||
MESSAGE(STATUS "This is gcc version:: " ${version})
|
||||
if(version LESS 5.4.0)
|
||||
MESSAGE(STATUS "gcc is too old")
|
||||
stop()
|
||||
elseif(version LESS 7.1.0)
|
||||
set(CMAKE_CXX_STD_FLAGS c++14)
|
||||
set(CXX_STD 14)
|
||||
MESSAGE(STATUS "c++14")
|
||||
else()
|
||||
set(CMAKE_CXX_STD_FLAGS c++17)
|
||||
set(CXX_STD 17)
|
||||
MESSAGE(STATUS "c++17")
|
||||
endif()
|
||||
endif()
|
||||
PROJECT (DROGON CXX)
|
||||
MESSAGE (STATUS "os:" ${CMAKE_SYSTEM_NAME})
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/trantor ${PROJECT_SOURCE_DIR}/lib/inc ${PROJECT_SOURCE_DIR}/orm_lib/inc)
|
||||
include(CheckIncludeFileCXX)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules/)
|
||||
CHECK_INCLUDE_FILE_CXX(any HAS_ANY)
|
||||
CHECK_INCLUDE_FILE_CXX(string_view HAS_STRING_VIEW)
|
||||
IF(HAS_ANY AND HAS_STRING_VIEW)
|
||||
SET(DROGON_CXX_STANDARD 17)
|
||||
ELSE()
|
||||
SET(DROGON_CXX_STANDARD 14)
|
||||
ENDIF()
|
||||
|
||||
IF(DROGON_CXX_STANDARD LESS 17)
|
||||
#With C++14, use boost to support any and string_view
|
||||
MESSAGE(STATUS "use c++14")
|
||||
FIND_PACKAGE(Boost 1.61.0 REQUIRED)
|
||||
IF(Boost_FOUND)
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "use c++17")
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/trantor
|
||||
${PROJECT_SOURCE_DIR}/lib/inc
|
||||
${PROJECT_SOURCE_DIR}/orm_lib/inc)
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules/)
|
||||
|
||||
#jsoncpp
|
||||
find_package (Jsoncpp REQUIRED)
|
||||
include_directories(${JSONCPP_INCLUDE_DIRS})
|
||||
link_libraries(${JSONCPP_LIBRARIES})
|
||||
FIND_PACKAGE (Jsoncpp REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${JSONCPP_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${JSONCPP_LIBRARIES})
|
||||
|
||||
message(STATUS "jsoncpp inc path:" ${JSONCPP_INCLUDE_DIRS})
|
||||
MESSAGE(STATUS "jsoncpp inc path:" ${JSONCPP_INCLUDE_DIRS})
|
||||
|
||||
#MESSAGE(STATUS ${JSONCPP_LIBRARIES})
|
||||
IF(NOT EXISTS ${JSONCPP_INCLUDE_DIRS}/json/version.h)
|
||||
MESSAGE(FATAL_ERROR "Error: jsoncpp lib is too old.....stop")
|
||||
ENDIF()
|
||||
|
||||
#message(STATUS ${JSONCPP_LIBRARIES})
|
||||
if(NOT EXISTS ${JSONCPP_INCLUDE_DIRS}/json/version.h)
|
||||
message(STATUS "jsoncpp lib is too old.....stop")
|
||||
stop()
|
||||
endif()
|
||||
EXEC_PROGRAM(cat ARGS "${JSONCPP_INCLUDE_DIRS}/json/version.h |grep JSONCPP_VERSION_STRING|sed s'/.*define/define/'|awk '{printf $3}'|sed s'/\"//g'" OUTPUT_VARIABLE jsoncpp_ver)
|
||||
message(STATUS "jsoncpp verson:" ${jsoncpp_ver})
|
||||
if(jsoncpp_ver LESS 1.7)
|
||||
MESSAGE(STATUS "jsoncpp lib is too old,please get new version from https://github.com/open-source-parsers/jsoncpp")
|
||||
stop()
|
||||
endif()
|
||||
MESSAGE(STATUS "jsoncpp verson:" ${jsoncpp_ver})
|
||||
IF(jsoncpp_ver LESS 1.7)
|
||||
MESSAGE(FATAL_ERROR "jsoncpp lib is too old,please get new version from https://github.com/open-source-parsers/jsoncpp")
|
||||
ENDIF()
|
||||
|
||||
find_package (UUID REQUIRED)
|
||||
include_directories(${UUID_INCLUDE_DIR})
|
||||
link_libraries(${UUID_LIBRARIES})
|
||||
FIND_PACKAGE (UUID REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${UUID_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${UUID_LIBRARIES})
|
||||
|
||||
find_package (OpenSSL)
|
||||
if(OpenSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
link_libraries(${OPENSSL_LIBRARIES})
|
||||
message(STATUS "openssl inc path:" ${OPENSSL_INCLUDE_DIR})
|
||||
else()
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/lib/src/ssl_funcs DIR_SRCS)
|
||||
endif()
|
||||
FIND_PACKAGE(ZLIB REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${ZLIB_LIBRARIES})
|
||||
|
||||
SET(drogon_sources lib/src/AOPAdvice.cc
|
||||
lib/src/CacheFile.cc
|
||||
lib/src/ConfigLoader.cc
|
||||
lib/src/Cookie.cc
|
||||
lib/src/DrClassMap.cc
|
||||
lib/src/DrTemplateBase.cc
|
||||
lib/src/FiltersFunction.cc
|
||||
lib/src/HttpAppFrameworkImpl.cc
|
||||
lib/src/HttpClientImpl.cc
|
||||
lib/src/HttpControllersRouter.cc
|
||||
lib/src/HttpFileUploadRequest.cc
|
||||
lib/src/HttpRequestImpl.cc
|
||||
lib/src/HttpRequestParser.cc
|
||||
lib/src/HttpResponseImpl.cc
|
||||
lib/src/HttpResponseParser.cc
|
||||
lib/src/HttpServer.cc
|
||||
lib/src/HttpSimpleControllersRouter.cc
|
||||
lib/src/HttpUtils.cc
|
||||
lib/src/HttpViewBase.cc
|
||||
lib/src/HttpViewData.cc
|
||||
lib/src/IntranetIpFilter.cc
|
||||
lib/src/ListenerManager.cc
|
||||
lib/src/LocalHostFilter.cc
|
||||
lib/src/MultiPart.cc
|
||||
lib/src/NotFound.cc
|
||||
lib/src/PluginsManager.cc
|
||||
lib/src/SessionManager.cc
|
||||
lib/src/SharedLibManager.cc
|
||||
lib/src/StaticFileRouter.cc
|
||||
lib/src/Utilities.cc
|
||||
lib/src/WebSocketClientImpl.cc
|
||||
lib/src/WebSocketConnectionImpl.cc
|
||||
lib/src/WebsocketControllersRouter.cc)
|
||||
|
||||
FIND_PACKAGE (OpenSSL)
|
||||
IF(OpenSSL_FOUND)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${OPENSSL_LIBRARIES})
|
||||
MESSAGE(STATUS "openssl inc path:" ${OPENSSL_INCLUDE_DIR})
|
||||
ELSE()
|
||||
SET(drogon_sources ${drogon_sources} lib/src/ssl_funcs/Md5.cc
|
||||
lib/src/ssl_funcs/Sha1.cc)
|
||||
ENDIF()
|
||||
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
link_libraries(${ZLIB_LIBRARIES})
|
||||
|
||||
message(STATUS "zlib inc path:" ${ZLIB_INCLUDE_DIR})
|
||||
|
||||
if(NOT BUILD_ORM)
|
||||
set(BUILD_ORM TRUE CACHE BOOL INTERNAL)
|
||||
endif()
|
||||
|
||||
|
||||
if(BUILD_ORM)
|
||||
IF(NOT BUILD_ORM)
|
||||
SET(BUILD_ORM TRUE CACHE BOOL INTERNAL)
|
||||
ENDIF()
|
||||
|
||||
|
||||
IF(BUILD_ORM)
|
||||
|
||||
#find postgres
|
||||
find_package(PostgreSQL)
|
||||
if(PostgreSQL_FOUND)
|
||||
include_directories(${PostgreSQL_INCLUDE_DIR})
|
||||
message(STATUS "libpq inc path:" ${PostgreSQL_INCLUDE_DIR})
|
||||
link_libraries(${PostgreSQL_LIBRARIES})
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/orm_lib/src/postgresql_impl DIR_SRCS)
|
||||
set(USE_ORM TRUE)
|
||||
endif()
|
||||
FIND_PACKAGE(PostgreSQL)
|
||||
IF(PostgreSQL_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PostgreSQL_INCLUDE_DIR})
|
||||
MESSAGE(STATUS "libpq inc path:" ${PostgreSQL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${PostgreSQL_LIBRARIES})
|
||||
SET(drogon_sources ${drogon_sources}
|
||||
orm_lib/src/postgresql_impl/PgConnection.cc
|
||||
orm_lib/src/postgresql_impl/PostgreSQLResultImpl.cc)
|
||||
ENDIF()
|
||||
|
||||
#Find mysql, only mariadb client liberary is supported
|
||||
find_package(MySQL)
|
||||
if(MYSQL_FOUND)
|
||||
message(STATUS "inc:" ${MYSQL_INCLUDE_DIR})
|
||||
message(STATUS "libs:" ${MYSQL_CLIENT_LIBS})
|
||||
message(STATUS "version:" ${MYSQL_VERSION_STRING})
|
||||
if(MYSQL_VERSION_STRING STREQUAL "")
|
||||
set(MYSQL_FOUND false)
|
||||
message(STATUS "The mysql in your system is not the mariadb, so we can't use it in drogon")
|
||||
else()
|
||||
message(STATUS "Ok! We find the mariadb!")
|
||||
include_directories(${MYSQL_INCLUDE_DIR})
|
||||
link_libraries(${MYSQL_CLIENT_LIBS})
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/orm_lib/src/mysql_impl DIR_SRCS)
|
||||
set(USE_ORM TRUE)
|
||||
endif()
|
||||
endif()
|
||||
FIND_PACKAGE(MySQL)
|
||||
IF(MYSQL_FOUND)
|
||||
MESSAGE(STATUS "inc:" ${MYSQL_INCLUDE_DIR})
|
||||
MESSAGE(STATUS "libs:" ${MYSQL_CLIENT_LIBS})
|
||||
MESSAGE(STATUS "version:" ${MYSQL_VERSION_STRING})
|
||||
IF(MYSQL_VERSION_STRING STREQUAL "")
|
||||
SET(MYSQL_FOUND false)
|
||||
MESSAGE(STATUS "The mysql in your system is not the mariadb, so we can't use it in drogon")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Ok! We find the mariadb!")
|
||||
INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${MYSQL_CLIENT_LIBS})
|
||||
SET(drogon_sources ${drogon_sources}
|
||||
orm_lib/src/mysql_impl/MysqlConnection.cc
|
||||
orm_lib/src/mysql_impl/MysqlResultImpl.cc)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
#Find sqlite3.
|
||||
find_package (SQLite3)
|
||||
FIND_PACKAGE (SQLite3)
|
||||
if (SQLITE3_FOUND)
|
||||
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||
link_libraries(${SQLITE3_LIBRARIES})
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/orm_lib/src/sqlite3_impl DIR_SRCS)
|
||||
set(USE_ORM TRUE)
|
||||
endif()
|
||||
MESSAGE(STATUS "SQLite3 inc:" ${SQLITE3_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${SQLITE3_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${SQLITE3_LIBRARIES})
|
||||
SET(drogon_sources ${drogon_sources}
|
||||
orm_lib/src/sqlite3_impl/Sqlite3Connection.cc
|
||||
orm_lib/src/sqlite3_impl/Sqlite3ResultImpl.cc)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
endif()
|
||||
|
||||
#message(STATUS ${DIR_SRCS})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -std=${CMAKE_CXX_STD_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -std=${CMAKE_CXX_STD_FLAGS}")
|
||||
|
||||
add_subdirectory(trantor)
|
||||
ADD_SUBDIRECTORY(trantor)
|
||||
|
||||
add_custom_target(makeVersion)
|
||||
add_custom_command(TARGET makeVersion
|
||||
@ -130,117 +161,179 @@ add_custom_command(TARGET makeVersion
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
VERBATIM )
|
||||
|
||||
if(NOT BUILD_EXAMPLES)
|
||||
set(BUILD_EXAMPLES TRUE CACHE BOOL INTERNAL)
|
||||
endif()
|
||||
IF(NOT BUILD_EXAMPLES)
|
||||
SET(BUILD_EXAMPLES TRUE CACHE BOOL INTERNAL)
|
||||
ENDIF()
|
||||
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
IF(BUILD_EXAMPLES)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
ENDIF()
|
||||
|
||||
if(NOT BUILD_CTL)
|
||||
set(BUILD_CTL TRUE CACHE BOOL INTERNAL)
|
||||
endif()
|
||||
IF(NOT BUILD_CTL)
|
||||
SET(BUILD_CTL TRUE CACHE BOOL INTERNAL)
|
||||
ENDIF()
|
||||
|
||||
if(BUILD_CTL)
|
||||
add_subdirectory(drogon_ctl)
|
||||
endif()
|
||||
IF(BUILD_CTL)
|
||||
ADD_SUBDIRECTORY(drogon_ctl)
|
||||
ENDIF()
|
||||
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/lib/src DIR_SRCS)
|
||||
IF(PostgreSQL_FOUND OR MYSQL_FOUND OR SQLITE3_FOUND)
|
||||
SET(drogon_sources ${drogon_sources}
|
||||
orm_lib/src/ArrayParser.cc
|
||||
orm_lib/src/Criteria.cc
|
||||
orm_lib/src/DbClient.cc
|
||||
orm_lib/src/DbClientImpl.cc
|
||||
orm_lib/src/DbClientLockFree.cc
|
||||
orm_lib/src/DbClientManager.cc
|
||||
orm_lib/src/Exception.cc
|
||||
orm_lib/src/Field.cc
|
||||
orm_lib/src/Result.cc
|
||||
orm_lib/src/Row.cc
|
||||
orm_lib/src/SqlBinder.cc
|
||||
orm_lib/src/TransactionImpl.cc)
|
||||
ELSE()
|
||||
SET(drogon_sources ${drogon_sources} lib/src/DbClientManagerSkipped.cc)
|
||||
ENDIF()
|
||||
|
||||
if(BUILD_ORM)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/orm_lib/src DIR_SRCS)
|
||||
endif()
|
||||
ADD_LIBRARY(drogon ${drogon_sources})
|
||||
|
||||
ADD_LIBRARY(drogon ${DIR_SRCS})
|
||||
SET_PROPERTY(TARGET drogon PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET drogon PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET drogon PROPERTY CXX_EXTENSIONS OFF)
|
||||
|
||||
add_dependencies(drogon trantor makeVersion)
|
||||
ADD_DEPENDENCIES(drogon trantor makeVersion)
|
||||
|
||||
IF(PostgreSQL_FOUND OR MYSQL_FOUND OR SQLITE3_FOUND)
|
||||
IF(PostgreSQL_FOUND)
|
||||
OPTION(USE_POSTGRESQL "Enable PostgreSQL" ON)
|
||||
ELSE()
|
||||
OPTION(USE_POSTGRESQL "Disable PostgreSQL" OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(MYSQL_FOUND)
|
||||
OPTION(USE_MYSQL "Enable Mysql" ON)
|
||||
ELSE()
|
||||
OPTION(USE_MYSQL "DisableMysql" OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(SQLITE3_FOUND)
|
||||
OPTION(USE_SQLITE3 "Enable Sqlite3" ON)
|
||||
ELSE()
|
||||
OPTION(USE_SQLITE3 "Disable Sqlite3" OFF)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(COMPILER_COMMAND ${CMAKE_CXX_COMPILER})
|
||||
SET(COMPILER_ID ${CMAKE_CXX_COMPILER_ID})
|
||||
|
||||
|
||||
SET(CONFIG_HEADER "${PROJECT_SOURCE_DIR}/config.h")
|
||||
file(WRITE "${CONFIG_HEADER}" "#pragma once\n")
|
||||
IF(CMAKE_BUILD_TYPE)
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} _type)
|
||||
IF(_type STREQUAL release)
|
||||
SET(COMPILATION_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} -std=c++")
|
||||
ELSEIF(_type STREQUAL debug)
|
||||
SET(COMPILATION_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -std=c++")
|
||||
ELSE()
|
||||
SET(COMPILATION_FLAGS "-std=c++")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(COMPILATION_FLAGS "-std=c++")
|
||||
ENDIF()
|
||||
|
||||
file(APPEND "${CONFIG_HEADER}" "#include <trantor/utils/config.h>\n")
|
||||
file(APPEND "${CONFIG_HEADER}" "#define CXX_STD " ${CXX_STD} "\n")
|
||||
if(USE_ORM)
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_ORM 1\n")
|
||||
if(PostgreSQL_FOUND)
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_POSTGRESQL 1\n")
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_POSTGRESQL 0\n")
|
||||
endif()
|
||||
GET_TARGET_PROPERTY(INS drogon INCLUDE_DIRECTORIES)
|
||||
SET(TMP_INS "")
|
||||
SET(INS_STRING "")
|
||||
FOREACH(loop_var ${INS})
|
||||
IF(TMP_INS MATCHES ";${loop_var};")
|
||||
ELSE()
|
||||
SET(TMP_INS ";${loop_var};${TMP_INS}")
|
||||
SET(INS_STRING "${INS_STRING} -I${loop_var}")
|
||||
ENDIF()
|
||||
ENDFOREACH(loop_var)
|
||||
|
||||
if(MYSQL_FOUND)
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_MYSQL 1\n")
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_MYSQL 0\n")
|
||||
endif()
|
||||
SET(INCLUDING_DIRS ${INS_STRING})
|
||||
|
||||
if(SQLITE3_FOUND)
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_SQLITE3 1\n")
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_SQLITE3 0\n")
|
||||
endif()
|
||||
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "#define USE_ORM 0\n")
|
||||
endif()
|
||||
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||
if(CMAKE_BUILD_TYPE_LOWER STREQUAL release)
|
||||
file(APPEND "${CONFIG_HEADER}" "\n" "const char compileFlags[] = \"" ${CMAKE_CXX_FLAGS_RELEASE} "\";\n")
|
||||
else()
|
||||
file(APPEND "${CONFIG_HEADER}" "\n" "const char compileFlags[] = \"" ${CMAKE_CXX_FLAGS_DEBUG} "\";\n")
|
||||
endif()
|
||||
|
||||
file(APPEND "${CONFIG_HEADER}" "const char compilerCommand[] = \"${CMAKE_CXX_COMPILER}\";\n")
|
||||
file(APPEND "${CONFIG_HEADER}" "const char compilerId[] = \"${CMAKE_CXX_COMPILER_ID}\";\n")
|
||||
|
||||
get_target_property(INS drogon INCLUDE_DIRECTORIES)
|
||||
|
||||
file(APPEND "${CONFIG_HEADER}" "\nconst char includeDirs[]=\"")
|
||||
set(TMP_INS,"")
|
||||
foreach(loop_var ${INS})
|
||||
if(TMP_INS MATCHES ";${loop_var};")
|
||||
else()
|
||||
set(TMP_INS ";${loop_var};${TMP_INS}")
|
||||
file(APPEND "${CONFIG_HEADER}" "-I" ${loop_var} " ")
|
||||
endif()
|
||||
endforeach(loop_var)
|
||||
|
||||
file(APPEND "${CONFIG_HEADER}" "\";\n")
|
||||
EXEC_PROGRAM(${PROJECT_SOURCE_DIR}/update_config.sh ARGS "${CONFIG_HEADER} ${PROJECT_SOURCE_DIR}/lib/inc/drogon/config.h")
|
||||
configure_file(${PROJECT_SOURCE_DIR}/lib/inc/drogon/config.h.in
|
||||
${PROJECT_SOURCE_DIR}/lib/inc/drogon/config.h @ONLY)
|
||||
|
||||
if (MAKETEST STREQUAL YES)
|
||||
ADD_SUBDIRECTORY(lib/tests)
|
||||
if(PostgreSQL_FOUND)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/src/postgresql_impl/test)
|
||||
endif()
|
||||
if(MYSQL_FOUND)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/src/mysql_impl/test)
|
||||
endif()
|
||||
if(SQLITE3_FOUND)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/src/sqlite3_impl/test)
|
||||
endif()
|
||||
if(USE_ORM)
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/tests)
|
||||
endif()
|
||||
IF(PostgreSQL_FOUND)
|
||||
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/orm_lib/src/postgresql_impl/test)
|
||||
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/orm_lib/tests)
|
||||
ENDIF()
|
||||
IF(MYSQL_FOUND)
|
||||
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/orm_lib/src/mysql_impl/test)
|
||||
ENDIF()
|
||||
IF(SQLITE3_FOUND)
|
||||
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/orm_lib/src/sqlite3_impl/test)
|
||||
ENDIF()
|
||||
endif ()
|
||||
|
||||
#Installation
|
||||
install(TARGETS drogon DESTINATION lib)
|
||||
INSTALL(TARGETS drogon DESTINATION lib)
|
||||
|
||||
file(GLOB drogon_headers "${CMAKE_CURRENT_SOURCE_DIR}/lib/inc/drogon/*.h")
|
||||
install(FILES ${drogon_headers} DESTINATION include/drogon)
|
||||
if(USE_ORM)
|
||||
file(GLOB orm_headers "${CMAKE_CURRENT_SOURCE_DIR}/orm_lib/inc/drogon/orm/*.h")
|
||||
install(FILES ${orm_headers} DESTINATION include/drogon/orm)
|
||||
endif()
|
||||
file(GLOB drogon_util_headers "${CMAKE_CURRENT_SOURCE_DIR}/lib/inc/drogon/utils/*.h")
|
||||
install(FILES ${drogon_util_headers}
|
||||
SET(drogon_headers
|
||||
lib/inc/drogon/CacheMap.h
|
||||
lib/inc/drogon/Cookie.h
|
||||
lib/inc/drogon/DrClassMap.h
|
||||
lib/inc/drogon/DrObject.h
|
||||
lib/inc/drogon/DrTemplate.h
|
||||
lib/inc/drogon/DrTemplateBase.h
|
||||
lib/inc/drogon/HttpAppFramework.h
|
||||
lib/inc/drogon/HttpBinder.h
|
||||
lib/inc/drogon/HttpClient.h
|
||||
lib/inc/drogon/HttpController.h
|
||||
lib/inc/drogon/HttpFilter.h
|
||||
lib/inc/drogon/HttpRequest.h
|
||||
lib/inc/drogon/HttpResponse.h
|
||||
lib/inc/drogon/HttpSimpleController.h
|
||||
lib/inc/drogon/HttpTypes.h
|
||||
lib/inc/drogon/HttpViewBase.h
|
||||
lib/inc/drogon/HttpViewData.h
|
||||
lib/inc/drogon/IntranetIpFilter.h
|
||||
lib/inc/drogon/LocalHostFilter.h
|
||||
lib/inc/drogon/MultiPart.h
|
||||
lib/inc/drogon/NotFound.h
|
||||
lib/inc/drogon/Session.h
|
||||
lib/inc/drogon/UploadFile.h
|
||||
lib/inc/drogon/WebSocketClient.h
|
||||
lib/inc/drogon/WebSocketConnection.h
|
||||
lib/inc/drogon/WebSocketController.h
|
||||
lib/inc/drogon/drogon.h
|
||||
lib/inc/drogon/version.h)
|
||||
INSTALL(FILES ${drogon_headers} DESTINATION include/drogon)
|
||||
|
||||
SET(orm_headers
|
||||
orm_lib/inc/drogon/orm/ArrayParser.h
|
||||
orm_lib/inc/drogon/orm/Criteria.h
|
||||
orm_lib/inc/drogon/orm/DbClient.h
|
||||
orm_lib/inc/drogon/orm/Exception.h
|
||||
orm_lib/inc/drogon/orm/Field.h
|
||||
orm_lib/inc/drogon/orm/FunctionTraits.h
|
||||
orm_lib/inc/drogon/orm/Mapper.h
|
||||
orm_lib/inc/drogon/orm/Result.h
|
||||
orm_lib/inc/drogon/orm/ResultIterator.h
|
||||
orm_lib/inc/drogon/orm/Row.h
|
||||
orm_lib/inc/drogon/orm/RowIterator.h
|
||||
orm_lib/inc/drogon/orm/SqlBinder.h)
|
||||
INSTALL(FILES ${orm_headers} DESTINATION include/drogon/orm)
|
||||
|
||||
SET(drogon_util_headers
|
||||
lib/inc/drogon/utils/ClassTraits.h
|
||||
lib/inc/drogon/utils/FunctionTraits.h
|
||||
lib/inc/drogon/utils/Utilities.h
|
||||
lib/inc/drogon/utils/any.h
|
||||
lib/inc/drogon/utils/string_view.h
|
||||
lib/inc/drogon/utils/HttpConstraint.h)
|
||||
INSTALL(FILES ${drogon_util_headers}
|
||||
DESTINATION include/drogon/utils)
|
||||
file(GLOB drogon_plugin_headers "${CMAKE_CURRENT_SOURCE_DIR}/lib/inc/drogon/plugins/*.h")
|
||||
install(FILES ${drogon_plugin_headers}
|
||||
|
||||
SET(drogon_plugin_headers lib/inc/drogon/plugins/Plugin.h)
|
||||
INSTALL(FILES ${drogon_plugin_headers}
|
||||
DESTINATION include/drogon/plugins)
|
||||
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/lib/inc/drogon/version.h"
|
||||
DESTINATION include/drogon)
|
||||
|
||||
SOURCE_GROUP( "Public API" FILES ${drogon_headers}
|
||||
${orm_headers}
|
||||
${drogon_util_headers}
|
||||
${drogon_plugin_headers})
|
||||
|
@ -1,21 +1,37 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
AUX_SOURCE_DIRECTORY(. SRC_DIR)
|
||||
add_executable(_drogon_ctl main.cc cmd.cc create.cc create_view.cc)
|
||||
SET(ctl_sources cmd.cc
|
||||
create.cc
|
||||
create_controller.cc
|
||||
create_filter.cc
|
||||
create_model.cc
|
||||
create_plugin.cc
|
||||
create_project.cc
|
||||
create_view.cc
|
||||
help.cc
|
||||
main.cc
|
||||
press.cc
|
||||
version.cc)
|
||||
ADD_EXECUTABLE(_drogon_ctl main.cc cmd.cc create.cc create_view.cc)
|
||||
FILE(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/templates/*.csp)
|
||||
foreach(cspFile ${SCP_LIST})
|
||||
message(STATUS "cspFile:" ${cspFile})
|
||||
FOREACH(cspFile ${SCP_LIST})
|
||||
MESSAGE(STATUS "cspFile:" ${cspFile})
|
||||
EXEC_PROGRAM(basename ARGS "${cspFile} .csp" OUTPUT_VARIABLE classname)
|
||||
message(STATUS "view classname:" ${classname})
|
||||
add_custom_command(OUTPUT ${classname}.h ${classname}.cc
|
||||
MESSAGE(STATUS "view classname:" ${classname})
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${classname}.h ${classname}.cc
|
||||
COMMAND _drogon_ctl
|
||||
ARGS create view ${cspFile}
|
||||
DEPENDS ${cspFile}
|
||||
VERBATIM )
|
||||
set(TEMPL_SRC ${TEMPL_SRC} ${classname}.cc)
|
||||
endforeach()
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_executable(drogon_ctl ${SRC_DIR} ${TEMPL_SRC})
|
||||
add_dependencies(drogon_ctl trantor makeVersion _drogon_ctl)
|
||||
install(TARGETS drogon_ctl DESTINATION bin)
|
||||
install(PROGRAMS $<TARGET_FILE_DIR:drogon_ctl>/drogon_ctl DESTINATION bin RENAME dg_ctl)
|
||||
SET(TEMPL_SRC ${TEMPL_SRC} ${classname}.cc)
|
||||
ENDFOREACH()
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
ADD_EXECUTABLE(drogon_ctl ${ctl_sources} ${TEMPL_SRC})
|
||||
ADD_DEPENDENCIES(drogon_ctl trantor makeVersion _drogon_ctl)
|
||||
INSTALL(TARGETS drogon_ctl DESTINATION bin)
|
||||
INSTALL(PROGRAMS $<TARGET_FILE_DIR:drogon_ctl>/drogon_ctl DESTINATION bin RENAME dg_ctl)
|
||||
SET(ctl_targets _drogon_ctl drogon_ctl)
|
||||
SET_PROPERTY(TARGET ${ctl_targets} PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET ${ctl_targets} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET ${ctl_targets} PROPERTY CXX_EXTENSIONS OFF)
|
||||
|
||||
|
@ -341,7 +341,7 @@ void create_controller::createController(const std::string &className,
|
||||
if (!oHeadFile || !oSourceFile)
|
||||
{
|
||||
perror("");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
if (type == Http)
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ void create_filter::handleCommand(std::vector<std::string> ¶meters)
|
||||
if (!oHeadFile || !oSourceFile)
|
||||
{
|
||||
perror("");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::cout << "create a http filter:" << className << std::endl;
|
||||
|
@ -768,6 +768,10 @@ void create_model::createModel(const std::string &path,
|
||||
createModelClassFromSqlite3(path, client, tableName);
|
||||
}
|
||||
}
|
||||
#else
|
||||
std::cerr << "Drogon does not support Sqlite3, please install Sqlite3 "
|
||||
"development environment before installing drogon"
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
else if (dbType == "no dbms")
|
||||
@ -825,7 +829,6 @@ void create_model::createModel(const std::string &path)
|
||||
|
||||
void create_model::handleCommand(std::vector<std::string> ¶meters)
|
||||
{
|
||||
#if USE_ORM
|
||||
std::cout << "Create model" << std::endl;
|
||||
if (parameters.size() == 0)
|
||||
{
|
||||
@ -835,10 +838,4 @@ void create_model::handleCommand(std::vector<std::string> ¶meters)
|
||||
{
|
||||
createModel(path);
|
||||
}
|
||||
#else
|
||||
std::cout
|
||||
<< "No database can be found in your system, please install one first!"
|
||||
<< std::endl;
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
@ -16,10 +16,8 @@
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <json/json.h>
|
||||
#if USE_ORM
|
||||
#include <drogon/orm/DbClient.h>
|
||||
using namespace drogon::orm;
|
||||
#endif
|
||||
#include <drogon/DrObject.h>
|
||||
#include "CommandHandler.h"
|
||||
#include <string>
|
||||
|
@ -105,7 +105,7 @@ void create_plugin::handleCommand(std::vector<std::string> ¶meters)
|
||||
if (!oHeadFile || !oSourceFile)
|
||||
{
|
||||
perror("");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::cout << "create a plugin:" << className << std::endl;
|
||||
|
@ -330,7 +330,6 @@ void create_view::newViewSourceFile(std::ofstream &file,
|
||||
file << "//this file is generated by program(drogon_ctl) "
|
||||
"automatically,don't modify it!\n";
|
||||
file << "#include \"" << className << ".h\"\n";
|
||||
file << "#include <drogon/config.h>\n";
|
||||
file << "#include <string>\n";
|
||||
file << "#include <sstream>\n";
|
||||
file << "#include <map>\n";
|
||||
|
@ -38,7 +38,7 @@ std::string press::detail()
|
||||
void outputErrorAndExit(const string_view &err)
|
||||
{
|
||||
std::cout << err << std::endl;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
void press::handleCommand(std::vector<std::string> ¶meters)
|
||||
{
|
||||
|
@ -1,85 +1,85 @@
|
||||
cmake_minimum_required (VERSION 3.2)
|
||||
Project([[ProjectName]])
|
||||
PROJECT([[ProjectName]])
|
||||
|
||||
link_directories(/usr/local/lib)
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_DIRECTORIES(/usr/local/lib)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
IF (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
EXEC_PROGRAM (gcc ARGS "--version | grep '^gcc'|awk '{print $3}' | sed s'/)//g' | sed s'/-.*//g'" OUTPUT_VARIABLE version)
|
||||
MESSAGE(STATUS "This is gcc version:: " ${version})
|
||||
if(version LESS 5.4.0)
|
||||
MESSAGE(STATUS "gcc is too old")
|
||||
stop()
|
||||
elseif(version LESS 7.1.0)
|
||||
set(CMAKE_CXX_STD_FLAGS c++14)
|
||||
MESSAGE(STATUS "c++14")
|
||||
else()
|
||||
set(CMAKE_CXX_STD_FLAGS c++17)
|
||||
MESSAGE(STATUS "c++17")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_CXX_STD_FLAGS c++17)
|
||||
endif()
|
||||
INCLUDE(CheckIncludeFileCXX)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
CHECK_INCLUDE_FILE_CXX(any HAS_ANY)
|
||||
CHECK_INCLUDE_FILE_CXX(string_view HAS_STRING_VIEW)
|
||||
IF(HAS_ANY AND HAS_STRING_VIEW)
|
||||
SET(CMAKE_CXX_STANDARD 17)
|
||||
ELSE()
|
||||
SET(CMAKE_CXX_STANDARD 14)
|
||||
ENDIF()
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -std=${CMAKE_CXX_STD_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -std=${CMAKE_CXX_STD_FLAGS}")
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules/)
|
||||
IF(CMAKE_CXX_STANDARD LESS 17)
|
||||
#With C++14, use boost to support any and string_view
|
||||
MESSAGE(STATUS "use c++14")
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
IF(Boost_FOUND)
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "use c++17")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules/)
|
||||
|
||||
#jsoncpp
|
||||
find_package (Jsoncpp REQUIRED)
|
||||
include_directories(${JSONCPP_INCLUDE_DIRS})
|
||||
link_libraries(${JSONCPP_LIBRARIES})
|
||||
FIND_PACKAGE (Jsoncpp REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${JSONCPP_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${JSONCPP_LIBRARIES})
|
||||
|
||||
#uuid
|
||||
find_package (UUID REQUIRED)
|
||||
include_directories(${UUID_INCLUDE_DIR})
|
||||
link_libraries(${UUID_LIBRARIES})
|
||||
FIND_PACKAGE (UUID REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${UUID_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${UUID_LIBRARIES})
|
||||
|
||||
#OpenSSL
|
||||
find_package (OpenSSL)
|
||||
if(OpenSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
link_libraries(${OPENSSL_LIBRARIES})
|
||||
endif()
|
||||
FIND_PACKAGE (OpenSSL)
|
||||
IF(OpenSSL_FOUND)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${OPENSSL_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
#zlib
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
link_libraries(${ZLIB_LIBRARIES})
|
||||
FIND_PACKAGE(ZLIB REQUIRED)
|
||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${ZLIB_LIBRARIES})
|
||||
|
||||
#find postgres
|
||||
find_package(PostgreSQL)
|
||||
if(PostgreSQL_FOUND)
|
||||
include_directories(${PostgreSQL_INCLUDE_DIR})
|
||||
link_libraries(${PostgreSQL_LIBRARIES})
|
||||
endif()
|
||||
FIND_PACKAGE(PostgreSQL)
|
||||
IF(PostgreSQL_FOUND)
|
||||
INCLUDE_DIRECTORIES(${PostgreSQL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${PostgreSQL_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
#Find mysql, only mariadb client liberary is supported
|
||||
find_package(MySQL)
|
||||
if(MYSQL_FOUND)
|
||||
message(STATUS "inc:" ${MYSQL_INCLUDE_DIR})
|
||||
message(STATUS "libs:" ${MYSQL_CLIENT_LIBS})
|
||||
message(STATUS "version:" ${MYSQL_VERSION_STRING})
|
||||
if(MYSQL_VERSION_STRING STREQUAL "")
|
||||
message(STATUS "The mysql in your system is not the mariadb, so we can't use it in drogon")
|
||||
else()
|
||||
message(STATUS "Ok! We find the mariadb!")
|
||||
include_directories(${MYSQL_INCLUDE_DIR})
|
||||
link_libraries(${MYSQL_CLIENT_LIBS})
|
||||
endif()
|
||||
endif()
|
||||
FIND_PACKAGE(MySQL)
|
||||
IF(MYSQL_FOUND)
|
||||
MESSAGE(STATUS "inc:" ${MYSQL_INCLUDE_DIR})
|
||||
MESSAGE(STATUS "libs:" ${MYSQL_CLIENT_LIBS})
|
||||
MESSAGE(STATUS "version:" ${MYSQL_VERSION_STRING})
|
||||
IF(MYSQL_VERSION_STRING STREQUAL "")
|
||||
MESSAGE(STATUS "The mysql in your system is not the mariadb, so we can't use it in drogon")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Ok! We find the mariadb!")
|
||||
INCLUDE_DIRECTORIES(${MYSQL_INCLUDE_DIR})
|
||||
LINK_LIBRARIES(${MYSQL_CLIENT_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
#Find sqlite3.
|
||||
find_package (SQLite3)
|
||||
FIND_PACKAGE (SQLite3)
|
||||
if (SQLITE3_FOUND)
|
||||
include_directories(${SQLITE3_INCLUDE_DIRS})
|
||||
link_libraries(${SQLITE3_LIBRARIES})
|
||||
endif()
|
||||
INCLUDE_DIRECTORIES(${SQLITE3_INCLUDE_DIRS})
|
||||
LINK_LIBRARIES(${SQLITE3_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
AUX_SOURCE_DIRECTORY(./ SRC_DIR)
|
||||
AUX_SOURCE_DIRECTORY(controllers CTL_SRC)
|
||||
@ -87,20 +87,20 @@ AUX_SOURCE_DIRECTORY(filters FILTER_SRC)
|
||||
AUX_SOURCE_DIRECTORY(plugins PLUGIN_SRC)
|
||||
AUX_SOURCE_DIRECTORY(models MODEL_SRC)
|
||||
|
||||
include_directories(/usr/local/include)
|
||||
INCLUDE_DIRECTORIES(/usr/local/include)
|
||||
|
||||
FILE(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/views/*.csp)
|
||||
foreach(cspFile ${SCP_LIST})
|
||||
message(STATUS "cspFile:" ${cspFile})
|
||||
FOREACH(cspFile ${SCP_LIST})
|
||||
MESSAGE(STATUS "cspFile:" ${cspFile})
|
||||
EXEC_PROGRAM(basename ARGS "${cspFile} .csp" OUTPUT_VARIABLE classname)
|
||||
message(STATUS "view classname:" ${classname})
|
||||
add_custom_command(OUTPUT ${classname}.h ${classname}.cc
|
||||
MESSAGE(STATUS "view classname:" ${classname})
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${classname}.h ${classname}.cc
|
||||
COMMAND drogon_ctl
|
||||
ARGS create view ${cspFile}
|
||||
DEPENDS ${cspFile}
|
||||
VERBATIM )
|
||||
set(VIEWSRC ${VIEWSRC} ${classname}.cc)
|
||||
endforeach()
|
||||
SET(VIEWSRC ${VIEWSRC} ${classname}.cc)
|
||||
ENDFOREACH()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_executable([[ProjectName]] ${SRC_DIR} ${CTL_SRC} ${FILTER_SRC} ${VIEWSRC} ${PLUGIN_SRC} ${MODEL_SRC})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
ADD_EXECUTABLE([[ProjectName]] ${SRC_DIR} ${CTL_SRC} ${FILTER_SRC} ${VIEWSRC} ${PLUGIN_SRC} ${MODEL_SRC})
|
||||
|
@ -9,7 +9,6 @@ using namespace drogon_ctl;
|
||||
*/
|
||||
|
||||
#include "[[className]].h"
|
||||
#include <trantor/utils/config.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <string>
|
||||
<%c++
|
||||
@ -17,6 +16,7 @@ using namespace drogon_ctl;
|
||||
auto className=@@.get<std::string>("className");
|
||||
%>
|
||||
|
||||
using namespace drogon;
|
||||
using namespace drogon_model::[[dbName]];
|
||||
|
||||
<%c++for(auto col:cols){
|
||||
|
@ -22,6 +22,7 @@ using namespace drogon_ctl;
|
||||
#include <tuple>
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace drogon::orm;
|
||||
|
||||
namespace drogon_model
|
||||
|
@ -13,8 +13,8 @@
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
#include <drogon/version.h>
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/version.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace drogon_ctl;
|
||||
@ -32,6 +32,6 @@ void version::handleCommand(std::vector<std::string> ¶meters)
|
||||
std::cout << "A utility for drogon" << std::endl;
|
||||
std::cout << "Version:" << VERSION << std::endl;
|
||||
std::cout << "Git commit:" << VERSION_MD5 << std::endl;
|
||||
std::cout << "Compile config:" << compileFlags << " " << includeDirs
|
||||
std::cout << "Compile config:" << COMPILATION_FLAGS << " " << INCLUDING_DIRS
|
||||
<< std::endl;
|
||||
}
|
||||
|
@ -1,40 +1,62 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
FILE(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/simple_example/*.csp)
|
||||
foreach(cspFile ${SCP_LIST})
|
||||
message(STATUS "cspFile:" ${cspFile})
|
||||
FOREACH(cspFile ${SCP_LIST})
|
||||
MESSAGE(STATUS "cspFile:" ${cspFile})
|
||||
EXEC_PROGRAM(basename ARGS "${cspFile} .csp" OUTPUT_VARIABLE classname)
|
||||
message(STATUS "view classname:" ${classname})
|
||||
add_custom_command(OUTPUT ${classname}.h ${classname}.cc
|
||||
MESSAGE(STATUS "view classname:" ${classname})
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${classname}.h ${classname}.cc
|
||||
COMMAND drogon_ctl
|
||||
ARGS create view ${cspFile}
|
||||
DEPENDS ${cspFile}
|
||||
VERBATIM )
|
||||
set(VIEWSRC ${VIEWSRC} ${classname}.cc)
|
||||
endforeach()
|
||||
SET(VIEWSRC ${VIEWSRC} ${classname}.cc)
|
||||
ENDFOREACH()
|
||||
|
||||
|
||||
AUX_SOURCE_DIRECTORY(simple_example DIR_STATIC)
|
||||
SET(simple_example_sources simple_example/CustomCtrl.cc
|
||||
simple_example/CustomHeaderFilter.cc
|
||||
simple_example/DoNothingPlugin.cc
|
||||
simple_example/ForwardCtrl.cc
|
||||
simple_example/JsonTestController.cc
|
||||
simple_example/ListParaCtl.cc
|
||||
simple_example/PipeliningTest.cc
|
||||
simple_example/TestController.cc
|
||||
simple_example/TestPlugin.cc
|
||||
simple_example/TestViewCtl.cc
|
||||
simple_example/WebSocketTest.cc
|
||||
simple_example/api_Attachment.cc
|
||||
simple_example/api_v1_ApiTest.cc
|
||||
simple_example/TimeFilter.cc
|
||||
simple_example/main.cc)
|
||||
|
||||
add_executable(webapp ${DIR_STATIC} ${VIEWSRC})
|
||||
add_dependencies(webapp drogon_ctl)
|
||||
ADD_EXECUTABLE(webapp ${simple_example_sources} ${VIEWSRC})
|
||||
ADD_DEPENDENCIES(webapp drogon_ctl)
|
||||
|
||||
AUX_SOURCE_DIRECTORY(client_example DIR_CLIENT)
|
||||
AUX_SOURCE_DIRECTORY(benchmark DIR_BENCHMARK)
|
||||
SET(client_example_sources client_example/main.cc)
|
||||
SET(benchmark_sources benchmark/BenchmarkCtrl.cc
|
||||
benchmark/JsonCtrl.cc
|
||||
benchmark/main.cc)
|
||||
#AUX_SOURCE_DIRECTORY(simple_example_test DIR_TEST)
|
||||
|
||||
add_executable(client ${DIR_CLIENT})
|
||||
add_executable(benchmark ${DIR_BENCHMARK})
|
||||
add_executable(webapp_test simple_example_test/main.cc)
|
||||
add_executable(pipelining_test simple_example_test/HttpPipeliningTest.cc)
|
||||
add_executable(websocket_test simple_example_test/WebSocketTest.cc)
|
||||
ADD_EXECUTABLE(client ${client_example_sources})
|
||||
ADD_EXECUTABLE(benchmark ${benchmark_sources})
|
||||
ADD_EXECUTABLE(webapp_test simple_example_test/main.cc)
|
||||
ADD_EXECUTABLE(pipelining_test simple_example_test/HttpPipeliningTest.cc)
|
||||
ADD_EXECUTABLE(websocket_test simple_example_test/WebSocketTest.cc)
|
||||
|
||||
add_custom_command(TARGET webapp POST_BUILD
|
||||
ADD_CUSTOM_COMMAND(TARGET webapp POST_BUILD
|
||||
COMMAND gzip
|
||||
ARGS -c ${CMAKE_CURRENT_SOURCE_DIR}/simple_example/index.html > ${CMAKE_CURRENT_BINARY_DIR}/index.html.gz
|
||||
VERBATIM)
|
||||
add_custom_command(TARGET webapp POST_BUILD
|
||||
ADD_CUSTOM_COMMAND(TARGET webapp POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${PROJECT_SOURCE_DIR}/config.example.json ${PROJECT_SOURCE_DIR}/drogon.jpg
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/simple_example/index.html
|
||||
${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.pem $<TARGET_FILE_DIR:webapp>)
|
||||
${PROJECT_SOURCE_DIR}/trantor/trantor/tests/server.pem $<TARGET_FILE_DIR:webapp>)
|
||||
|
||||
SET(example_targets webapp webapp_test client benchmark pipelining_test websocket_test)
|
||||
|
||||
SET_PROPERTY(TARGET ${example_targets} PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET ${example_targets} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET ${example_targets} PROPERTY CXX_EXTENSIONS OFF)
|
||||
|
@ -5,8 +5,10 @@ void TestController::asyncHandleHttpRequest(
|
||||
std::function<void(const HttpResponsePtr &)> &&callback)
|
||||
{
|
||||
// write your application logic here
|
||||
LOG_WARN << req->matchedPathPattern();
|
||||
LOG_WARN << req->matchedPathPatternData();
|
||||
auto resp = HttpResponse::newHttpResponse();
|
||||
resp->setContentTypeCodeAndCustomString(CT_TEXT_PLAIN,
|
||||
"Content-Type: plaintext\r\n");
|
||||
resp->setBody("<p>Hello, world!</p>");
|
||||
resp->setExpiredTime(0);
|
||||
callback(resp);
|
||||
|
@ -38,7 +38,7 @@ void ApiTest::your_method_name(
|
||||
double p1,
|
||||
int p2) const
|
||||
{
|
||||
LOG_WARN << req->matchedPathPattern();
|
||||
LOG_WARN << req->matchedPathPatternData();
|
||||
HttpViewData data;
|
||||
data.insert("title", std::string("ApiTest::get"));
|
||||
std::map<std::string, std::string> para;
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "CustomCtrl.h"
|
||||
#include "CustomHeaderFilter.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/drogon.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "CustomCtrl.h"
|
||||
#include "CustomHeaderFilter.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace drogon;
|
||||
using namespace std::chrono_literals;
|
||||
@ -125,7 +127,7 @@ int main()
|
||||
std::cout << banner << std::endl;
|
||||
// app().addListener("::1", 8848); //ipv6
|
||||
app().addListener("0.0.0.0", 8848);
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
// https
|
||||
drogon::app().setSSLFiles("server.pem", "server.pem");
|
||||
drogon::app().addListener("0.0.0.0", 8849, true);
|
||||
@ -206,7 +208,7 @@ int main()
|
||||
drogon::AdviceCallback &&acb,
|
||||
drogon::AdviceChainCallback &&accb) {
|
||||
LOG_DEBUG << "postRouting1";
|
||||
LOG_DEBUG << "Matched path=" << req->matchedPathPattern();
|
||||
LOG_DEBUG << "Matched path=" << req->matchedPathPatternData();
|
||||
for (auto &cookie : req->cookies())
|
||||
{
|
||||
LOG_DEBUG << "cookie: " << cookie.first << "=" << cookie.second;
|
||||
|
@ -26,7 +26,7 @@ int main()
|
||||
{
|
||||
LOG_ERROR << "The response was received in "
|
||||
"the wrong order!";
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -36,12 +36,12 @@ int main()
|
||||
if (resp->getBody().length() > 0)
|
||||
{
|
||||
LOG_ERROR << "The response has a body:" << resp->getBody();
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
@ -53,15 +53,15 @@ int main()
|
||||
if (resp->getBody().length() != 44618)
|
||||
{
|
||||
LOG_ERROR << "The response is error!";
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
auto request = HttpRequest::newHttpRequest();
|
||||
request->setPath("/pipe");
|
||||
for (int i = 0; i < 19; i++)
|
||||
@ -76,7 +76,7 @@ int main()
|
||||
{
|
||||
LOG_ERROR
|
||||
<< "The response was received in the wrong order!";
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -91,12 +91,12 @@ int main()
|
||||
if (resp->getBody().length() == 0)
|
||||
{
|
||||
LOG_ERROR << "The response hasn't a body!";
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -50,14 +50,14 @@ int main(int argc, char *argv[])
|
||||
std::cout << "ws failed!" << std::endl;
|
||||
if (!continually)
|
||||
{
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
app().getLoop()->runAfter(5.0, [continually]() {
|
||||
if (!continually)
|
||||
{
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
app().run();
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
// Make a http client to test the example server app;
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/drogon.h>
|
||||
#include <trantor/net/EventLoopThread.h>
|
||||
#include <trantor/net/TcpClient.h>
|
||||
@ -1031,7 +1032,7 @@ int main(int argc, char *argv[])
|
||||
client->addCookie(sessionID);
|
||||
|
||||
doTest(client, pro1);
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
std::promise<int> pro2;
|
||||
auto sslClient = HttpClient::newHttpClient("127.0.0.1",
|
||||
8849,
|
||||
|
@ -14,11 +14,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#if USE_ORM
|
||||
#include <drogon/orm/DbClient.h>
|
||||
#endif
|
||||
#include <chrono>
|
||||
#include <drogon/utils/HttpConstraint.h>
|
||||
#include <drogon/CacheMap.h>
|
||||
#include <drogon/DrObject.h>
|
||||
#include <drogon/HttpBinder.h>
|
||||
@ -34,13 +31,14 @@
|
||||
#include <drogon/utils/ClassTraits.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/version.h>
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
@ -299,7 +297,8 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
virtual void registerHttpSimpleController(
|
||||
const std::string &pathName,
|
||||
const std::string &ctrlName,
|
||||
const std::vector<any> &filtersAndMethods = std::vector<any>()) = 0;
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods =
|
||||
std::vector<internal::HttpConstraint>{}) = 0;
|
||||
|
||||
/// Register a handler into the framework.
|
||||
/**
|
||||
@ -335,7 +334,8 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
void registerHandler(
|
||||
const std::string &pathPattern,
|
||||
FUNCTION &&function,
|
||||
const std::vector<any> &filtersAndMethods = std::vector<any>(),
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods =
|
||||
std::vector<internal::HttpConstraint>{},
|
||||
const std::string &handlerName = "")
|
||||
{
|
||||
LOG_TRACE << "pathPattern:" << pathPattern;
|
||||
@ -348,22 +348,17 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
std::vector<std::string> filters;
|
||||
for (auto const &filterOrMethod : filtersAndMethods)
|
||||
{
|
||||
if (filterOrMethod.type() == typeid(std::string))
|
||||
if (filterOrMethod.type() == internal::ConstraintType::HttpFilter)
|
||||
{
|
||||
filters.push_back(*any_cast<std::string>(&filterOrMethod));
|
||||
filters.push_back(filterOrMethod.getFilterName());
|
||||
}
|
||||
else if (filterOrMethod.type() == typeid(const char *))
|
||||
else if (filterOrMethod.type() ==
|
||||
internal::ConstraintType::HttpMethod)
|
||||
{
|
||||
filters.push_back(*any_cast<const char *>(&filterOrMethod));
|
||||
}
|
||||
else if (filterOrMethod.type() == typeid(HttpMethod))
|
||||
{
|
||||
validMethods.push_back(*any_cast<HttpMethod>(&filterOrMethod));
|
||||
validMethods.push_back(filterOrMethod.getHttpMethod());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Invalid controller constraint type:"
|
||||
<< filterOrMethod.type().name() << std::endl;
|
||||
LOG_ERROR << "Invalid controller constraint type";
|
||||
exit(1);
|
||||
}
|
||||
@ -790,7 +785,6 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
*/
|
||||
virtual void setHomePage(const std::string &homePageFile) = 0;
|
||||
|
||||
#if USE_ORM
|
||||
/// Get a database client by @param name
|
||||
/**
|
||||
* NOTE:
|
||||
@ -833,7 +827,6 @@ class HttpAppFramework : public trantor::NonCopyable
|
||||
const std::string &filename = "",
|
||||
const std::string &name = "default",
|
||||
const bool isFast = false) = 0;
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual void registerHttpController(
|
||||
|
@ -15,6 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <drogon/DrObject.h>
|
||||
#include <drogon/utils/HttpConstraint.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -54,7 +55,8 @@ class HttpController : public DrObject<T>, public HttpControllerBase
|
||||
static void registerMethod(
|
||||
FUNCTION &&function,
|
||||
const std::string &pattern,
|
||||
const std::vector<any> &filtersAndMethods = std::vector<any>(),
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods =
|
||||
std::vector<internal::HttpConstraint>{},
|
||||
bool classNameInPath = true,
|
||||
const std::string &handlerName = "")
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <drogon/Session.h>
|
||||
#include <drogon/UploadFile.h>
|
||||
@ -88,24 +89,26 @@ class HttpRequest
|
||||
|
||||
/// Get the query string of the request.
|
||||
/**
|
||||
* If the http method is GET, the query string is the substring after the
|
||||
* '?' in the URL string. If the http method is POST, the query string is
|
||||
* the content(body) string of the HTTP request.
|
||||
* The query string is the substring after the '?' in the URL string.
|
||||
*/
|
||||
virtual string_view query() const = 0;
|
||||
string_view getQuery() const
|
||||
virtual const std::string &query() const = 0;
|
||||
const std::string &getQuery() const
|
||||
{
|
||||
return query();
|
||||
}
|
||||
|
||||
/// Get the content string of the request, which is the body part of the
|
||||
/// request.
|
||||
virtual string_view body() const = 0;
|
||||
string_view body() const
|
||||
{
|
||||
return string_view(bodyData(), bodyLength());
|
||||
}
|
||||
string_view getBody() const
|
||||
{
|
||||
return body();
|
||||
}
|
||||
|
||||
virtual const char *bodyData() const = 0;
|
||||
virtual size_t bodyLength() const = 0;
|
||||
/// Set the content string of the request.
|
||||
virtual void setBody(const std::string &body) = 0;
|
||||
virtual void setBody(std::string &&body) = 0;
|
||||
@ -118,11 +121,17 @@ class HttpRequest
|
||||
}
|
||||
|
||||
/// Get the matched path pattern after routing
|
||||
virtual const string_view &matchedPathPattern() const = 0;
|
||||
const string_view &getMatchedPathPattern() const
|
||||
string_view getMatchedPathPattern() const
|
||||
{
|
||||
return matchedPathPattern();
|
||||
}
|
||||
string_view matchedPathPattern() const
|
||||
{
|
||||
return string_view(matchedPathPatternData(),
|
||||
matchedPathPatternLength());
|
||||
}
|
||||
virtual const char *matchedPathPatternData() const = 0;
|
||||
virtual size_t matchedPathPatternLength() const = 0;
|
||||
|
||||
/// Return the enum type version of the request.
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <drogon/Cookie.h>
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <drogon/HttpViewData.h>
|
||||
@ -69,9 +70,23 @@ class HttpResponse
|
||||
/// Set the response content type and the content-type string, The string
|
||||
/// must contain the header name and CRLF.
|
||||
/// For example, "content-type: text/plain\r\n"
|
||||
virtual void setContentTypeCodeAndCustomString(
|
||||
ContentType type,
|
||||
const string_view &typeString) = 0;
|
||||
void setContentTypeCodeAndCustomString(ContentType type,
|
||||
const string_view &typeString)
|
||||
{
|
||||
setContentTypeCodeAndCustomString(type,
|
||||
typeString.data(),
|
||||
typeString.length());
|
||||
}
|
||||
template <int N>
|
||||
void setContentTypeCodeAndCustomString(ContentType type,
|
||||
const char (&typeString)[N])
|
||||
{
|
||||
assert(N > 0);
|
||||
setContentTypeCodeAndCustomString(type, typeString, N - 1);
|
||||
}
|
||||
virtual void setContentTypeCodeAndCustomString(ContentType type,
|
||||
const char *typeString,
|
||||
size_t typeStringLength) = 0;
|
||||
|
||||
/// Set the reponse content type and the character set.
|
||||
/// virtual void setContentTypeCodeAndCharacterSet(ContentType type, const
|
||||
|
@ -15,6 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <drogon/DrObject.h>
|
||||
#include <drogon/utils/HttpConstraint.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -52,8 +53,9 @@ class HttpSimpleController : public DrObject<T>, public HttpSimpleControllerBase
|
||||
HttpSimpleController()
|
||||
{
|
||||
}
|
||||
static void __registerSelf(const std::string &path,
|
||||
const std::vector<any> &filtersAndMethods)
|
||||
static void __registerSelf(
|
||||
const std::string &path,
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods)
|
||||
{
|
||||
LOG_TRACE << "register simple controller("
|
||||
<< HttpSimpleController<T>::classTypeName()
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#pragma once
|
||||
#include <atomic>
|
||||
#include <drogon/config.h>
|
||||
#include <thread>
|
||||
|
||||
namespace drogon
|
||||
|
@ -14,7 +14,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <drogon/utils/any.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
|
||||
@ -135,8 +136,16 @@ class HttpViewData
|
||||
* < --> <
|
||||
* > --> >
|
||||
*/
|
||||
static std::string htmlTranslate(const std::string &str);
|
||||
static std::string htmlTranslate(const string_view &str);
|
||||
|
||||
static std::string htmlTranslate(const char *str, size_t length);
|
||||
static std::string htmlTranslate(const std::string &str)
|
||||
{
|
||||
return htmlTranslate(str.data(), str.length());
|
||||
}
|
||||
static std::string htmlTranslate(const string_view &str)
|
||||
{
|
||||
return htmlTranslate(str.data(), str.length());
|
||||
}
|
||||
static bool needTranslation(const std::string &str)
|
||||
{
|
||||
for (auto const &c : str)
|
||||
|
@ -110,7 +110,7 @@ class MultiPartParser
|
||||
protected:
|
||||
std::vector<HttpFile> _files;
|
||||
std::map<std::string, std::string> _parameters;
|
||||
int parse(const string_view &content, const std::string &boundary);
|
||||
int parse(const HttpRequestPtr &req, const std::string &boundary);
|
||||
int parseEntity(const char *begin, const char *end);
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/utils/any.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
@ -63,11 +62,33 @@ class WebSocketConnection
|
||||
virtual void forceClose() = 0;
|
||||
|
||||
/// Set custom data on the connection
|
||||
virtual void setContext(const any &context) = 0;
|
||||
void setContext(const std::shared_ptr<void> &context)
|
||||
{
|
||||
_contextPtr = context;
|
||||
}
|
||||
void setContext(std::shared_ptr<void> &&context)
|
||||
{
|
||||
_contextPtr = std::move(context);
|
||||
}
|
||||
|
||||
/// Get custom data from the connection
|
||||
virtual const any &getContext() const = 0;
|
||||
virtual any *getMutableContext() = 0;
|
||||
template <typename T>
|
||||
std::shared_ptr<T> getContext() const
|
||||
{
|
||||
return std::static_pointer_cast<T>(_contextPtr);
|
||||
}
|
||||
|
||||
/// Return true if the context is set by user.
|
||||
bool hasContext()
|
||||
{
|
||||
return (bool)_contextPtr;
|
||||
}
|
||||
|
||||
/// Clear the context.
|
||||
void clearContext()
|
||||
{
|
||||
_contextPtr.reset();
|
||||
}
|
||||
|
||||
/// Set the heartbeat(ping) message sent to the peer.
|
||||
/**
|
||||
@ -78,6 +99,9 @@ class WebSocketConnection
|
||||
virtual void setPingMessage(
|
||||
const std::string &message,
|
||||
const std::chrono::duration<long double> &interval) = 0;
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> _contextPtr;
|
||||
};
|
||||
typedef std::shared_ptr<WebSocketConnection> WebSocketConnectionPtr;
|
||||
} // namespace drogon
|
||||
|
12
lib/inc/drogon/config.h.in
Normal file
12
lib/inc/drogon/config.h.in
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#cmakedefine01 USE_POSTGRESQL
|
||||
#cmakedefine01 USE_MYSQL
|
||||
#cmakedefine01 USE_SQLITE3
|
||||
#cmakedefine OpenSSL_FOUND
|
||||
|
||||
#cmakedefine COMPILATION_FLAGS "@COMPILATION_FLAGS@@DROGON_CXX_STANDARD@"
|
||||
#cmakedefine COMPILER_COMMAND "@COMPILER_COMMAND@"
|
||||
#cmakedefine COMPILER_ID "@COMPILER_ID@"
|
||||
|
||||
#cmakedefine INCLUDING_DIRS "@INCLUDING_DIRS@"
|
@ -14,8 +14,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
|
64
lib/inc/drogon/utils/HttpConstraint.h
Normal file
64
lib/inc/drogon/utils/HttpConstraint.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
*
|
||||
* HttpConstraint.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <string>
|
||||
namespace drogon
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
enum class ConstraintType
|
||||
{
|
||||
None,
|
||||
HttpMethod,
|
||||
HttpFilter
|
||||
};
|
||||
|
||||
class HttpConstraint
|
||||
{
|
||||
public:
|
||||
HttpConstraint(HttpMethod method)
|
||||
: _type(ConstraintType::HttpMethod), _method(method)
|
||||
{
|
||||
}
|
||||
HttpConstraint(const std::string &filterName)
|
||||
: _type(ConstraintType::HttpFilter), _filterName(filterName)
|
||||
{
|
||||
}
|
||||
HttpConstraint(const char *filterName)
|
||||
: _type(ConstraintType::HttpFilter), _filterName(filterName)
|
||||
{
|
||||
}
|
||||
ConstraintType type() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
HttpMethod getHttpMethod() const
|
||||
{
|
||||
return _method;
|
||||
}
|
||||
const std::string &getFilterName() const
|
||||
{
|
||||
return _filterName;
|
||||
}
|
||||
|
||||
private:
|
||||
ConstraintType _type = ConstraintType::None;
|
||||
HttpMethod _method;
|
||||
std::string _filterName;
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace drogon
|
@ -14,10 +14,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <trantor/utils/Date.h>
|
||||
#include <vector>
|
||||
|
||||
namespace drogon
|
||||
@ -58,9 +58,17 @@ std::string base64Encode(const unsigned char *bytes_to_encode,
|
||||
std::string base64Decode(std::string const &encoded_string);
|
||||
|
||||
/// Decode from or encode to the URL format string
|
||||
std::string urlDecode(const std::string &szToDecode);
|
||||
std::string urlDecode(const string_view &szToDecode);
|
||||
std::string urlDecode(const char *begin, const char *end);
|
||||
inline std::string urlDecode(const std::string &szToDecode)
|
||||
{
|
||||
auto begin = szToDecode.data();
|
||||
return urlDecode(begin, begin + szToDecode.length());
|
||||
}
|
||||
inline std::string urlDecode(const string_view &szToDecode)
|
||||
{
|
||||
auto begin = szToDecode.data();
|
||||
return urlDecode(begin, begin + szToDecode.length());
|
||||
}
|
||||
std::string urlEncode(const std::string &str);
|
||||
|
||||
/// Commpress or decompress data using gzip lib.
|
||||
|
31
lib/inc/drogon/utils/any.h
Normal file
31
lib/inc/drogon/utils/any.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
*
|
||||
* any.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#if __cplusplus >= 201703L
|
||||
#include <any>
|
||||
#else
|
||||
#include <boost/any.hpp>
|
||||
#endif
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
#if __cplusplus >= 201703L
|
||||
using std::any;
|
||||
using std::any_cast;
|
||||
#else
|
||||
using boost::any;
|
||||
using boost::any_cast;
|
||||
#endif
|
||||
} // namespace drogon
|
28
lib/inc/drogon/utils/string_view.h
Normal file
28
lib/inc/drogon/utils/string_view.h
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
*
|
||||
* string_view.h
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#if __cplusplus >= 201703L
|
||||
#include <string_view>
|
||||
#else
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#endif
|
||||
namespace drogon
|
||||
{
|
||||
#if __cplusplus >= 201703L
|
||||
using std::string_view;
|
||||
#else
|
||||
using boost::string_view;
|
||||
#endif
|
||||
} // namespace drogon
|
@ -14,7 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "ConfigLoader.h"
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@ -160,7 +160,7 @@ static void loadControllers(const Json::Value &controllers)
|
||||
auto ctrlName = controller.get("controller", "").asString();
|
||||
if (path == "" || ctrlName == "")
|
||||
continue;
|
||||
std::vector<any> constraints;
|
||||
std::vector<internal::HttpConstraint> constraints;
|
||||
if (!controller["http_methods"].isNull())
|
||||
{
|
||||
for (auto const &method : controller["http_methods"])
|
||||
@ -316,7 +316,7 @@ static void loadApp(const Json::Value &app)
|
||||
else
|
||||
{
|
||||
std::cerr << "Error format of client_max_body_size" << std::endl;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
auto maxMemoryBodySize =
|
||||
app.get("client_max_memory_body_size", "64K").asString();
|
||||
@ -327,7 +327,7 @@ static void loadApp(const Json::Value &app)
|
||||
else
|
||||
{
|
||||
std::cerr << "Error format of client_max_memory_body_size" << std::endl;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
auto maxWsMsgSize =
|
||||
app.get("client_max_websocket_message_size", "128K").asString();
|
||||
@ -339,7 +339,7 @@ static void loadApp(const Json::Value &app)
|
||||
{
|
||||
std::cerr << "Error format of client_max_websocket_message_size"
|
||||
<< std::endl;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
drogon::app().setHomePage(app.get("home_page", "index.html").asString());
|
||||
}
|
||||
@ -347,7 +347,6 @@ static void loadDbClients(const Json::Value &dbClients)
|
||||
{
|
||||
if (!dbClients)
|
||||
return;
|
||||
#if USE_ORM
|
||||
for (auto const &client : dbClients)
|
||||
{
|
||||
auto type = client.get("rdbms", "postgresql").asString();
|
||||
@ -377,12 +376,6 @@ static void loadDbClients(const Json::Value &dbClients)
|
||||
name,
|
||||
isFast);
|
||||
}
|
||||
#else
|
||||
std::cout << "No database is supported by drogon, please install the "
|
||||
"database development library first."
|
||||
<< std::endl;
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
static void loadListeners(const Json::Value &listeners)
|
||||
{
|
||||
|
44
lib/src/DbClientManagerSkipped.cc
Normal file
44
lib/src/DbClientManagerSkipped.cc
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
*
|
||||
* DbClientManagerSkipped.cc
|
||||
* An Tao
|
||||
*
|
||||
* Copyright 2018, An Tao. All rights reserved.
|
||||
* https://github.com/an-tao/drogon
|
||||
* Use of this source code is governed by a MIT license
|
||||
* that can be found in the License file.
|
||||
*
|
||||
* Drogon
|
||||
*
|
||||
*/
|
||||
|
||||
#include "DbClientManager.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace drogon::orm;
|
||||
using namespace drogon;
|
||||
|
||||
void DbClientManager::createDbClients(
|
||||
const std::vector<trantor::EventLoop *> &ioloops)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void DbClientManager::createDbClient(const std::string &dbType,
|
||||
const std::string &host,
|
||||
const u_short port,
|
||||
const std::string &databaseName,
|
||||
const std::string &userName,
|
||||
const std::string &password,
|
||||
const size_t connectionNum,
|
||||
const std::string &filename,
|
||||
const std::string &name,
|
||||
const bool isFast)
|
||||
{
|
||||
LOG_FATAL << "No database is supported by drogon, please install the "
|
||||
"database development library first.";
|
||||
abort();
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
#include "AOPAdvice.h"
|
||||
#include "ConfigLoader.h"
|
||||
#include "HttpServer.h"
|
||||
#include <drogon/config.h>
|
||||
#include <algorithm>
|
||||
#include <drogon/CacheMap.h>
|
||||
#include <drogon/DrClassMap.h>
|
||||
@ -128,7 +129,7 @@ void HttpAppFrameworkImpl::registerWebSocketController(
|
||||
void HttpAppFrameworkImpl::registerHttpSimpleController(
|
||||
const std::string &pathName,
|
||||
const std::string &ctrlName,
|
||||
const std::vector<any> &filtersAndMethods)
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods)
|
||||
{
|
||||
assert(!_running);
|
||||
_httpSimpleCtrlsRouter.registerHttpSimpleController(pathName,
|
||||
@ -292,13 +293,11 @@ void HttpAppFrameworkImpl::run()
|
||||
_sslCertPath,
|
||||
_sslKeyPath,
|
||||
_threadNum);
|
||||
#if USE_ORM
|
||||
// A fast database client instance should be created in the main event loop,
|
||||
// so put the main loop into ioLoops.
|
||||
ioLoops.push_back(getLoop());
|
||||
_dbClientManager.createDbClients(ioLoops);
|
||||
ioLoops.pop_back();
|
||||
#endif
|
||||
_httpCtrlsRouter.init(ioLoops);
|
||||
_httpSimpleCtrlsRouter.init(ioLoops);
|
||||
_staticFileRouter.init();
|
||||
@ -366,11 +365,7 @@ void HttpAppFrameworkImpl::onConnection(const trantor::TcpConnectionPtr &conn)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CXX_STD >= 17
|
||||
if (!conn->getContext().has_value())
|
||||
#else
|
||||
if (conn->getContext().empty())
|
||||
#endif
|
||||
if (!conn->hasContext())
|
||||
{
|
||||
// If the connection is connected to the SSL port and then
|
||||
// disconnected before the SSL handshake.
|
||||
@ -449,7 +444,6 @@ void HttpAppFrameworkImpl::onAsyncRequest(
|
||||
callback(resp);
|
||||
return;
|
||||
}
|
||||
// LOG_TRACE << "query: " << req->query() ;
|
||||
|
||||
std::string sessionId = req->getCookie("JSESSIONID");
|
||||
bool needSetJsessionid = false;
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DbClientManager.h"
|
||||
#include "HttpClientImpl.h"
|
||||
#include "HttpControllersRouter.h"
|
||||
#include "HttpRequestImpl.h"
|
||||
@ -26,9 +27,7 @@
|
||||
#include "WebsocketControllersRouter.h"
|
||||
#include "StaticFileRouter.h"
|
||||
#include "SessionManager.h"
|
||||
#if USE_ORM
|
||||
#include "../../orm_lib/src/DbClientManager.h"
|
||||
#endif
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <drogon/HttpSimpleController.h>
|
||||
#include <drogon/version.h>
|
||||
@ -106,8 +105,8 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
virtual void registerHttpSimpleController(
|
||||
const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<any> &filtersAndMethods =
|
||||
std::vector<any>()) override;
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods =
|
||||
std::vector<internal::HttpConstraint>{}) override;
|
||||
|
||||
virtual void setCustom404Page(const HttpResponsePtr &resp) override
|
||||
{
|
||||
@ -344,7 +343,6 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
return _serverHeader;
|
||||
}
|
||||
|
||||
#if USE_ORM
|
||||
virtual orm::DbClientPtr getDbClient(
|
||||
const std::string &name = "default") override
|
||||
{
|
||||
@ -378,7 +376,6 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
name,
|
||||
isFast);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline static HttpAppFrameworkImpl &instance()
|
||||
{
|
||||
@ -461,9 +458,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
Json::Value _jsonConfig;
|
||||
PluginsManager _pluginsManager;
|
||||
HttpResponsePtr _custom404;
|
||||
#if USE_ORM
|
||||
orm::DbClientManager _dbClientManager;
|
||||
#endif
|
||||
static InitBeforeMainFunction _initFirst;
|
||||
std::vector<std::function<bool(const trantor::InetAddress &,
|
||||
const trantor::InetAddress &)>>
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "HttpResponseParser.h"
|
||||
#include <drogon/config.h>
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -205,7 +206,7 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
||||
_server,
|
||||
"httpClient");
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
if (_useSSL)
|
||||
{
|
||||
_tcpClient->enableSSL();
|
||||
@ -227,7 +228,8 @@ void HttpClientImpl::sendRequestInLoop(const drogon::HttpRequestPtr &req,
|
||||
return;
|
||||
if (connPtr->connected())
|
||||
{
|
||||
connPtr->setContext(HttpResponseParser(connPtr));
|
||||
connPtr->setContext(
|
||||
std::make_shared<HttpResponseParser>());
|
||||
// send request;
|
||||
LOG_TRACE << "Connection established!";
|
||||
while (thisPtr->_pipeliningCallbacks.size() <=
|
||||
@ -316,8 +318,8 @@ void HttpClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr,
|
||||
const HttpRequestPtr &req)
|
||||
{
|
||||
trantor::MsgBuffer buffer;
|
||||
auto implPtr = std::dynamic_pointer_cast<HttpRequestImpl>(req);
|
||||
assert(implPtr);
|
||||
assert(req);
|
||||
auto implPtr = static_cast<HttpRequestImpl *>(req.get());
|
||||
implPtr->appendToBuffer(&buffer);
|
||||
LOG_TRACE << "Send request:"
|
||||
<< std::string(buffer.peek(), buffer.readableBytes());
|
||||
@ -328,8 +330,7 @@ void HttpClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr,
|
||||
void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr,
|
||||
trantor::MsgBuffer *msg)
|
||||
{
|
||||
HttpResponseParser *responseParser =
|
||||
any_cast<HttpResponseParser>(connPtr->getMutableContext());
|
||||
auto responseParser = connPtr->getContext<HttpResponseParser>();
|
||||
|
||||
// LOG_TRACE << "###:" << msg->readableBytes();
|
||||
auto msgSize = msg->readableBytes();
|
||||
|
@ -389,7 +389,7 @@ void HttpControllersRouter::doControllerHandler(
|
||||
{
|
||||
// make a copy response;
|
||||
auto newResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
|
||||
*static_cast<HttpResponseImpl *>(responsePtr.get()));
|
||||
newResp->setExpiredTime(-1); // make it temporary
|
||||
newResp->addCookie("JSESSIONID", sessionId);
|
||||
invokeCallback(callback, req, newResp);
|
||||
@ -444,8 +444,7 @@ void HttpControllersRouter::doControllerHandler(
|
||||
if (resp->expiredTime() >= 0)
|
||||
{
|
||||
// cache the response;
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
|
||||
->makeHeaderString();
|
||||
static_cast<HttpResponseImpl *>(resp.get())->makeHeaderString();
|
||||
auto loop = req->getLoop();
|
||||
if (loop->isInLoopThread())
|
||||
{
|
||||
@ -464,7 +463,7 @@ void HttpControllersRouter::doControllerHandler(
|
||||
{
|
||||
// make a copy
|
||||
newResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(resp));
|
||||
*static_cast<HttpResponseImpl *>(resp.get()));
|
||||
newResp->setExpiredTime(-1); // make it temporary
|
||||
}
|
||||
newResp->addCookie("JSESSIONID", sessionId);
|
||||
|
@ -25,7 +25,7 @@ using namespace drogon;
|
||||
|
||||
void HttpRequestImpl::parseParameters() const
|
||||
{
|
||||
auto input = query();
|
||||
auto input = queryView();
|
||||
if (input.empty())
|
||||
return;
|
||||
std::string type = getHeaderBy("content-type");
|
||||
|
@ -123,7 +123,7 @@ class HttpRequestImpl : public HttpRequest
|
||||
_query = query;
|
||||
}
|
||||
|
||||
virtual string_view body() const override
|
||||
string_view bodyView() const
|
||||
{
|
||||
if (_cacheFilePtr)
|
||||
{
|
||||
@ -131,6 +131,22 @@ class HttpRequestImpl : public HttpRequest
|
||||
}
|
||||
return _content;
|
||||
}
|
||||
virtual const char *bodyData() const override
|
||||
{
|
||||
if (_cacheFilePtr)
|
||||
{
|
||||
return _cacheFilePtr->getStringView().data();
|
||||
}
|
||||
return _content.data();
|
||||
}
|
||||
virtual size_t bodyLength() const override
|
||||
{
|
||||
if (_cacheFilePtr)
|
||||
{
|
||||
return _cacheFilePtr->getStringView().length();
|
||||
}
|
||||
return _content.length();
|
||||
}
|
||||
|
||||
void appendToBody(const char *data, size_t length)
|
||||
{
|
||||
@ -146,9 +162,9 @@ class HttpRequestImpl : public HttpRequest
|
||||
|
||||
void reserveBodySize();
|
||||
|
||||
virtual string_view query() const override
|
||||
string_view queryView() const
|
||||
{
|
||||
if (_query != "")
|
||||
if (!_query.empty())
|
||||
return _query;
|
||||
if (_method == Post)
|
||||
{
|
||||
@ -159,6 +175,11 @@ class HttpRequestImpl : public HttpRequest
|
||||
return _query;
|
||||
}
|
||||
|
||||
virtual const std::string &query() const override
|
||||
{
|
||||
return _query;
|
||||
}
|
||||
|
||||
virtual const trantor::InetAddress &peerAddr() const override
|
||||
{
|
||||
return _peer;
|
||||
@ -323,9 +344,13 @@ class HttpRequestImpl : public HttpRequest
|
||||
return _contentType;
|
||||
}
|
||||
|
||||
virtual const string_view &matchedPathPattern() const override
|
||||
virtual const char *matchedPathPatternData() const override
|
||||
{
|
||||
return _matchedPathPattern;
|
||||
return _matchedPathPattern.data();
|
||||
}
|
||||
virtual size_t matchedPathPatternLength() const override
|
||||
{
|
||||
return _matchedPathPattern.length();
|
||||
}
|
||||
|
||||
void setMatchedPathPattern(const std::string &pathPattern)
|
||||
|
@ -202,8 +202,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
|
||||
{
|
||||
resp->setStatusCode(k413RequestEntityTooLarge);
|
||||
auto httpString =
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(
|
||||
resp)
|
||||
static_cast<HttpResponseImpl *>(resp.get())
|
||||
->renderToString();
|
||||
reset();
|
||||
connPtr->send(httpString);
|
||||
@ -212,8 +211,7 @@ bool HttpRequestParser::parseRequest(MsgBuffer *buf)
|
||||
{
|
||||
resp->setStatusCode(k100Continue);
|
||||
auto httpString =
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(
|
||||
resp)
|
||||
static_cast<HttpResponseImpl *>(resp.get())
|
||||
->renderToString();
|
||||
connPtr->send(httpString);
|
||||
}
|
||||
|
@ -16,15 +16,16 @@
|
||||
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "WebSocketConnectionImpl.h"
|
||||
#include <deque>
|
||||
#include <drogon/HttpResponse.h>
|
||||
#include <mutex>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <mutex>
|
||||
#include <deque>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
class HttpRequestParser
|
||||
class HttpRequestParser : public trantor::NonCopyable
|
||||
{
|
||||
public:
|
||||
enum HttpRequestParseState
|
||||
|
@ -100,10 +100,11 @@ class HttpResponseImpl : public HttpResponse
|
||||
|
||||
virtual void setContentTypeCodeAndCustomString(
|
||||
ContentType type,
|
||||
const string_view &typeString) override
|
||||
const char *typeString,
|
||||
size_t typeStringLength) override
|
||||
{
|
||||
_contentType = type;
|
||||
setContentType(typeString);
|
||||
setContentType(string_view{typeString, typeStringLength});
|
||||
}
|
||||
|
||||
// virtual void setContentTypeCodeAndCharacterSet(ContentType type, const
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
using namespace trantor;
|
||||
using namespace drogon;
|
||||
HttpResponseParser::HttpResponseParser(const trantor::TcpConnectionPtr &connPtr)
|
||||
HttpResponseParser::HttpResponseParser()
|
||||
: _state(HttpResponseParseState::kExpectResponseLine),
|
||||
_response(new HttpResponseImpl)
|
||||
{
|
||||
@ -138,7 +138,7 @@ bool HttpResponseParser::parseResponse(MsgBuffer *buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
if(_parseResponseForHeadMethod)
|
||||
if (_parseResponseForHeadMethod)
|
||||
{
|
||||
_response->_leftBodyLength = 0;
|
||||
_state = HttpResponseParseState::kGotAll;
|
||||
|
@ -16,14 +16,15 @@
|
||||
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <drogon/WebSocketConnection.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <trantor/net/TcpConnection.h>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
class HttpResponseParser
|
||||
class HttpResponseParser : public trantor::NonCopyable
|
||||
{
|
||||
public:
|
||||
enum class HttpResponseParseState
|
||||
@ -38,7 +39,7 @@ class HttpResponseParser
|
||||
kGotAll,
|
||||
};
|
||||
|
||||
explicit HttpResponseParser(const trantor::TcpConnectionPtr &connPtr);
|
||||
HttpResponseParser();
|
||||
|
||||
// default copy-ctor, dtor and assignment are fine
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "HttpServer.h"
|
||||
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include "HttpRequestParser.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <drogon/HttpRequest.h>
|
||||
#include <drogon/HttpResponse.h>
|
||||
@ -100,34 +99,32 @@ void HttpServer::onConnection(const TcpConnectionPtr &conn)
|
||||
{
|
||||
if (conn->connected())
|
||||
{
|
||||
conn->setContext(HttpRequestParser(conn));
|
||||
conn->setContext(std::make_shared<HttpRequestParser>(conn));
|
||||
_connectionCallback(conn);
|
||||
}
|
||||
else if (conn->disconnected())
|
||||
{
|
||||
LOG_TRACE << "conn disconnected!";
|
||||
_connectionCallback(conn);
|
||||
HttpRequestParser *requestParser =
|
||||
any_cast<HttpRequestParser>(conn->getMutableContext());
|
||||
auto requestParser = conn->getContext<HttpRequestParser>();
|
||||
if (requestParser)
|
||||
{
|
||||
if (requestParser->webSocketConn())
|
||||
{
|
||||
requestParser->webSocketConn()->onClose();
|
||||
}
|
||||
#if (CXX_STD > 14)
|
||||
conn->getMutableContext()->reset(); // reset(): since c++17
|
||||
#else
|
||||
conn->getMutableContext()->clear();
|
||||
#endif
|
||||
conn->clearContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf)
|
||||
{
|
||||
HttpRequestParser *requestParser =
|
||||
any_cast<HttpRequestParser>(conn->getMutableContext());
|
||||
if (!conn->hasContext())
|
||||
return;
|
||||
auto requestParser = conn->getContext<HttpRequestParser>();
|
||||
if (!requestParser)
|
||||
return;
|
||||
// With the pipelining feature or web socket, it is possible to receice
|
||||
// multiple messages at once, so
|
||||
// the while loop is necessary
|
||||
@ -165,16 +162,20 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf)
|
||||
std::make_shared<WebSocketConnectionImpl>(conn);
|
||||
_newWebsocketCallback(
|
||||
requestParser->requestImpl(),
|
||||
[=](const HttpResponsePtr &resp) mutable {
|
||||
if (resp->statusCode() == k101SwitchingProtocols)
|
||||
[conn, wsConn, requestParser](
|
||||
const HttpResponsePtr &resp) mutable {
|
||||
if (conn->connected())
|
||||
{
|
||||
requestParser->setWebsockConnection(wsConn);
|
||||
if (resp->statusCode() ==
|
||||
k101SwitchingProtocols)
|
||||
{
|
||||
requestParser->setWebsockConnection(wsConn);
|
||||
}
|
||||
auto httpString =
|
||||
((HttpResponseImpl *)resp.get())
|
||||
->renderToString();
|
||||
conn->send(httpString);
|
||||
}
|
||||
auto httpString =
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(
|
||||
resp)
|
||||
->renderToString();
|
||||
conn->send(httpString);
|
||||
},
|
||||
wsConn);
|
||||
}
|
||||
@ -187,23 +188,20 @@ void HttpServer::onMessage(const TcpConnectionPtr &conn, MsgBuffer *buf)
|
||||
break;
|
||||
}
|
||||
}
|
||||
onRequests(conn, requests);
|
||||
onRequests(conn, requests, requestParser);
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServer::onRequests(const TcpConnectionPtr &conn,
|
||||
const std::vector<HttpRequestImplPtr> &requests)
|
||||
void HttpServer::onRequests(
|
||||
const TcpConnectionPtr &conn,
|
||||
const std::vector<HttpRequestImplPtr> &requests,
|
||||
const std::shared_ptr<HttpRequestParser> &requestParser)
|
||||
{
|
||||
if (requests.empty())
|
||||
return;
|
||||
auto responsePtrs =
|
||||
std::make_shared<std::vector<std::pair<HttpResponsePtr, bool>>>();
|
||||
auto loopFlagPtr = std::make_shared<bool>(true);
|
||||
|
||||
HttpRequestParser *requestParser =
|
||||
any_cast<HttpRequestParser>(conn->getMutableContext());
|
||||
if (!requestParser)
|
||||
return;
|
||||
for (auto &req : requests)
|
||||
{
|
||||
if (!conn->connected())
|
||||
@ -239,122 +237,83 @@ void HttpServer::onRequests(const TcpConnectionPtr &conn,
|
||||
requestParser->stop();
|
||||
}
|
||||
|
||||
_httpAsyncCallback(req, [=](const HttpResponsePtr &response) {
|
||||
if (!response)
|
||||
return;
|
||||
response->setCloseConnection(_close);
|
||||
|
||||
auto newResp = response;
|
||||
auto &sendfileName =
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(newResp)
|
||||
->sendfileName();
|
||||
|
||||
if (app().isGzipEnabled() && sendfileName.empty() &&
|
||||
req->getHeaderBy("accept-encoding").find("gzip") !=
|
||||
std::string::npos &&
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(response)
|
||||
->getHeaderBy("content-encoding")
|
||||
.empty() &&
|
||||
response->getContentType() < CT_APPLICATION_OCTET_STREAM &&
|
||||
response->getBody().length() > 1024)
|
||||
{
|
||||
// use gzip
|
||||
LOG_TRACE << "Use gzip to compress the body";
|
||||
size_t zlen = response->getBody().length();
|
||||
auto strCompress =
|
||||
utils::gzipCompress(response->getBody().data(),
|
||||
response->getBody().length());
|
||||
if (strCompress)
|
||||
{
|
||||
if (zlen > 0)
|
||||
{
|
||||
LOG_TRACE << "length after compressing:" << zlen;
|
||||
if (response->expiredTime() >= 0)
|
||||
{
|
||||
// cached response,we need to make a clone
|
||||
newResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(
|
||||
response));
|
||||
newResp->setExpiredTime(-1);
|
||||
}
|
||||
newResp->setBody(std::move(*strCompress));
|
||||
newResp->addHeader("Content-Encoding", "gzip");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "gzip got 0 length result";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (conn->getLoop()->isInLoopThread())
|
||||
{
|
||||
/*
|
||||
* A client that supports persistent connections MAY
|
||||
* “pipeline” its requests (i.e., send multiple requests
|
||||
* without waiting for each response). A server MUST send
|
||||
* its responses to those requests in the same order that
|
||||
* the requests were received. rfc2616-8.1.1.2
|
||||
*/
|
||||
_httpAsyncCallback(
|
||||
req,
|
||||
[conn,
|
||||
_close,
|
||||
req,
|
||||
loopFlagPtr,
|
||||
responsePtrs,
|
||||
isHeadMethod,
|
||||
this,
|
||||
requestParser](const HttpResponsePtr &response) {
|
||||
if (!response)
|
||||
return;
|
||||
if (!conn->connected())
|
||||
return;
|
||||
if (requestParser->getFirstRequest() == req)
|
||||
response->setCloseConnection(_close);
|
||||
auto newResp = response;
|
||||
auto &sendfileName =
|
||||
static_cast<HttpResponseImpl *>(newResp.get())
|
||||
->sendfileName();
|
||||
|
||||
if (app().isGzipEnabled() && sendfileName.empty() &&
|
||||
req->getHeaderBy("accept-encoding").find("gzip") !=
|
||||
std::string::npos &&
|
||||
static_cast<HttpResponseImpl *>(response.get())
|
||||
->getHeaderBy("content-encoding")
|
||||
.empty() &&
|
||||
response->getContentType() < CT_APPLICATION_OCTET_STREAM &&
|
||||
response->getBody().length() > 1024)
|
||||
{
|
||||
requestParser->popFirstRequest();
|
||||
if (*loopFlagPtr)
|
||||
// use gzip
|
||||
LOG_TRACE << "Use gzip to compress the body";
|
||||
size_t zlen = response->getBody().length();
|
||||
auto strCompress =
|
||||
utils::gzipCompress(response->getBody().data(),
|
||||
response->getBody().length());
|
||||
if (strCompress)
|
||||
{
|
||||
(*responsePtrs).emplace_back(newResp, isHeadMethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::pair<HttpResponsePtr, bool>> resps;
|
||||
resps.emplace_back(newResp, isHeadMethod);
|
||||
while (requestParser->numberOfRequestsInPipelining() >
|
||||
0)
|
||||
if (zlen > 0)
|
||||
{
|
||||
auto resp = requestParser->getFirstResponse();
|
||||
if (resp.first)
|
||||
LOG_TRACE << "length after compressing:" << zlen;
|
||||
if (response->expiredTime() >= 0)
|
||||
{
|
||||
requestParser->popFirstRequest();
|
||||
resps.push_back(std::move(resp));
|
||||
// cached response,we need to make a clone
|
||||
newResp = std::make_shared<HttpResponseImpl>(
|
||||
*static_cast<HttpResponseImpl *>(
|
||||
response.get()));
|
||||
newResp->setExpiredTime(-1);
|
||||
}
|
||||
else
|
||||
break;
|
||||
newResp->setBody(std::move(*strCompress));
|
||||
newResp->addHeader("Content-Encoding", "gzip");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR << "gzip got 0 length result";
|
||||
}
|
||||
sendResponses(conn, resps);
|
||||
}
|
||||
if (requestParser->isStop() &&
|
||||
requestParser->numberOfRequestsInPipelining() == 0)
|
||||
}
|
||||
if (conn->getLoop()->isInLoopThread())
|
||||
{
|
||||
/*
|
||||
* A client that supports persistent connections MAY
|
||||
* “pipeline” its requests (i.e., send multiple requests
|
||||
* without waiting for each response). A server MUST send
|
||||
* its responses to those requests in the same order that
|
||||
* the requests were received. rfc2616-8.1.1.2
|
||||
*/
|
||||
if (!conn->connected())
|
||||
return;
|
||||
if (requestParser->getFirstRequest() == req)
|
||||
{
|
||||
requestParser->popFirstRequest();
|
||||
if (*loopFlagPtr)
|
||||
{
|
||||
sendResponses(conn, *responsePtrs);
|
||||
responsePtrs->clear();
|
||||
(*responsePtrs).emplace_back(newResp, isHeadMethod);
|
||||
}
|
||||
conn->shutdown();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// some earlier requests are waiting for responses;
|
||||
requestParser->pushResponseToPipelining(req,
|
||||
newResp,
|
||||
isHeadMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
conn->getLoop()->queueInLoop([conn,
|
||||
req,
|
||||
newResp,
|
||||
this,
|
||||
isHeadMethod]() {
|
||||
HttpRequestParser *requestParser =
|
||||
any_cast<HttpRequestParser>(conn->getMutableContext());
|
||||
if (requestParser)
|
||||
{
|
||||
if (requestParser->getFirstRequest() == req)
|
||||
else
|
||||
{
|
||||
requestParser->popFirstRequest();
|
||||
std::vector<std::pair<HttpResponsePtr, bool>> resps;
|
||||
resps.emplace_back(newResp, isHeadMethod);
|
||||
while (
|
||||
@ -371,24 +330,75 @@ void HttpServer::onRequests(const TcpConnectionPtr &conn,
|
||||
break;
|
||||
}
|
||||
sendResponses(conn, resps);
|
||||
if (requestParser->isStop() &&
|
||||
requestParser->numberOfRequestsInPipelining() ==
|
||||
0)
|
||||
{
|
||||
conn->shutdown();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (requestParser->isStop() &&
|
||||
requestParser->numberOfRequestsInPipelining() == 0)
|
||||
{
|
||||
// some earlier requests are waiting for
|
||||
// responses;
|
||||
requestParser->pushResponseToPipelining(
|
||||
req, newResp, isHeadMethod);
|
||||
if (*loopFlagPtr)
|
||||
{
|
||||
sendResponses(conn, *responsePtrs);
|
||||
responsePtrs->clear();
|
||||
}
|
||||
conn->shutdown();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
else
|
||||
{
|
||||
// some earlier requests are waiting for responses;
|
||||
requestParser->pushResponseToPipelining(req,
|
||||
newResp,
|
||||
isHeadMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
conn->getLoop()->queueInLoop([conn,
|
||||
req,
|
||||
newResp,
|
||||
this,
|
||||
isHeadMethod,
|
||||
requestParser]() {
|
||||
if (conn->connected())
|
||||
{
|
||||
if (requestParser->getFirstRequest() == req)
|
||||
{
|
||||
requestParser->popFirstRequest();
|
||||
std::vector<std::pair<HttpResponsePtr, bool>>
|
||||
resps;
|
||||
resps.emplace_back(newResp, isHeadMethod);
|
||||
while (requestParser
|
||||
->numberOfRequestsInPipelining() > 0)
|
||||
{
|
||||
auto resp =
|
||||
requestParser->getFirstResponse();
|
||||
if (resp.first)
|
||||
{
|
||||
requestParser->popFirstRequest();
|
||||
resps.push_back(std::move(resp));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
sendResponses(conn, resps);
|
||||
if (requestParser->isStop() &&
|
||||
requestParser
|
||||
->numberOfRequestsInPipelining() ==
|
||||
0)
|
||||
{
|
||||
conn->shutdown();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// some earlier requests are waiting for
|
||||
// responses;
|
||||
requestParser->pushResponseToPipelining(
|
||||
req, newResp, isHeadMethod);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
*loopFlagPtr = false;
|
||||
if (conn->connected() && !responsePtrs->empty())
|
||||
@ -400,7 +410,7 @@ void HttpServer::sendResponse(const TcpConnectionPtr &conn,
|
||||
bool isHeadMethod)
|
||||
{
|
||||
conn->getLoop()->assertInLoopThread();
|
||||
auto respImplPtr = std::dynamic_pointer_cast<HttpResponseImpl>(response);
|
||||
auto respImplPtr = static_cast<HttpResponseImpl *>(response.get());
|
||||
if (!isHeadMethod)
|
||||
{
|
||||
auto httpString = respImplPtr->renderToString();
|
||||
@ -438,8 +448,7 @@ void HttpServer::sendResponses(
|
||||
trantor::MsgBuffer buffer(256 * responses.size());
|
||||
for (auto const &resp : responses)
|
||||
{
|
||||
auto respImplPtr =
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp.first);
|
||||
auto respImplPtr = static_cast<HttpResponseImpl *>(resp.first.get());
|
||||
if (!resp.second)
|
||||
{
|
||||
// Not HEAD method
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "WebSocketConnectionImpl.h"
|
||||
#include "HttpRequestParser.h"
|
||||
#include <drogon/WebSocketController.h>
|
||||
#include <drogon/config.h>
|
||||
#include <trantor/net/TcpServer.h>
|
||||
#include <trantor/net/callbacks.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
@ -87,18 +87,17 @@ class HttpServer : trantor::NonCopyable
|
||||
}
|
||||
void start();
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
void enableSSL(const std::string &certPath, const std::string &keyPath)
|
||||
{
|
||||
_server.enableSSL(certPath, keyPath);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void onConnection(const trantor::TcpConnectionPtr &conn);
|
||||
void onMessage(const trantor::TcpConnectionPtr &, trantor::MsgBuffer *);
|
||||
void onRequests(const trantor::TcpConnectionPtr &,
|
||||
const std::vector<HttpRequestImplPtr> &);
|
||||
const std::vector<HttpRequestImplPtr> &,
|
||||
const std::shared_ptr<HttpRequestParser> &);
|
||||
void sendResponse(const trantor::TcpConnectionPtr &,
|
||||
const HttpResponsePtr &,
|
||||
bool isHeadMethod);
|
||||
|
@ -16,13 +16,14 @@
|
||||
#include "AOPAdvice.h"
|
||||
#include "FiltersFunction.h"
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#include <drogon/utils/HttpConstraint.h>
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
void HttpSimpleControllersRouter::registerHttpSimpleController(
|
||||
const std::string &pathName,
|
||||
const std::string &ctrlName,
|
||||
const std::vector<any> &filtersAndMethods)
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods)
|
||||
{
|
||||
assert(!pathName.empty());
|
||||
assert(!ctrlName.empty());
|
||||
@ -34,22 +35,16 @@ void HttpSimpleControllersRouter::registerHttpSimpleController(
|
||||
std::vector<std::string> filters;
|
||||
for (auto const &filterOrMethod : filtersAndMethods)
|
||||
{
|
||||
if (filterOrMethod.type() == typeid(std::string))
|
||||
if (filterOrMethod.type() == internal::ConstraintType::HttpFilter)
|
||||
{
|
||||
filters.push_back(*any_cast<std::string>(&filterOrMethod));
|
||||
filters.push_back(filterOrMethod.getFilterName());
|
||||
}
|
||||
else if (filterOrMethod.type() == typeid(const char *))
|
||||
else if (filterOrMethod.type() == internal::ConstraintType::HttpMethod)
|
||||
{
|
||||
filters.push_back(*any_cast<const char *>(&filterOrMethod));
|
||||
}
|
||||
else if (filterOrMethod.type() == typeid(HttpMethod))
|
||||
{
|
||||
validMethods.push_back(*any_cast<HttpMethod>(&filterOrMethod));
|
||||
validMethods.push_back(filterOrMethod.getHttpMethod());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Invalid controller constraint type:"
|
||||
<< filterOrMethod.type().name() << std::endl;
|
||||
LOG_ERROR << "Invalid controller constraint type";
|
||||
exit(1);
|
||||
}
|
||||
@ -242,7 +237,7 @@ void HttpSimpleControllersRouter::doControllerHandler(
|
||||
{
|
||||
// make a copy response;
|
||||
auto newResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(responsePtr));
|
||||
*static_cast<HttpResponseImpl *>(responsePtr.get()));
|
||||
newResp->setExpiredTime(-1); // make it temporary
|
||||
newResp->addCookie("JSESSIONID", sessionId);
|
||||
invokeCallback(callback, req, newResp);
|
||||
@ -262,7 +257,7 @@ void HttpSimpleControllersRouter::doControllerHandler(
|
||||
if (resp->expiredTime() >= 0)
|
||||
{
|
||||
// cache the response;
|
||||
std::dynamic_pointer_cast<HttpResponseImpl>(resp)
|
||||
static_cast<HttpResponseImpl *>(resp.get())
|
||||
->makeHeaderString();
|
||||
auto loop = req->getLoop();
|
||||
if (loop->isInLoopThread())
|
||||
@ -282,8 +277,7 @@ void HttpSimpleControllersRouter::doControllerHandler(
|
||||
{
|
||||
// make a copy
|
||||
newResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(
|
||||
resp));
|
||||
*static_cast<HttpResponseImpl *>(resp.get()));
|
||||
newResp->setExpiredTime(-1); // make it temporary
|
||||
}
|
||||
newResp->addCookie("JSESSIONID", sessionId);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "HttpControllersRouter.h"
|
||||
#include "HttpRequestImpl.h"
|
||||
#include "HttpResponseImpl.h"
|
||||
#include <drogon/utils/HttpConstraint.h>
|
||||
#include <atomic>
|
||||
#include <drogon/HttpBinder.h>
|
||||
#include <drogon/HttpFilter.h>
|
||||
@ -62,7 +63,7 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable
|
||||
void registerHttpSimpleController(
|
||||
const std::string &pathName,
|
||||
const std::string &ctrlName,
|
||||
const std::vector<any> &filtersAndMethods);
|
||||
const std::vector<internal::HttpConstraint> &filtersAndMethods);
|
||||
void route(const HttpRequestImplPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
bool needSetJsessionid,
|
||||
|
@ -13,9 +13,10 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <drogon/HttpTypes.h>
|
||||
#include <drogon/WebSocketConnection.h>
|
||||
#include <drogon/config.h>
|
||||
#include <string>
|
||||
#include <trantor/utils/MsgBuffer.h>
|
||||
|
||||
|
@ -16,18 +16,14 @@
|
||||
|
||||
using namespace drogon;
|
||||
|
||||
std::string HttpViewData::htmlTranslate(const std::string &str)
|
||||
{
|
||||
return htmlTranslate(string_view(str));
|
||||
}
|
||||
|
||||
std::string HttpViewData::htmlTranslate(const string_view &str)
|
||||
std::string HttpViewData::htmlTranslate(const char *str, size_t length)
|
||||
{
|
||||
std::string ret;
|
||||
ret.reserve(str.length() + 64);
|
||||
for (auto &ch : str)
|
||||
ret.reserve(length + 64);
|
||||
auto end = str + length;
|
||||
while (str != end)
|
||||
{
|
||||
switch (ch)
|
||||
switch (*str)
|
||||
{
|
||||
case '"':
|
||||
ret.append(""", 6);
|
||||
@ -42,9 +38,10 @@ std::string HttpViewData::htmlTranslate(const string_view &str)
|
||||
ret.append(">", 4);
|
||||
break;
|
||||
default:
|
||||
ret.push_back(ch);
|
||||
ret.push_back(*str);
|
||||
break;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -13,9 +13,8 @@
|
||||
*/
|
||||
|
||||
#include "ListenerManager.h"
|
||||
#include <trantor/utils/config.h>
|
||||
#include <drogon/config.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
@ -53,7 +52,7 @@ void ListenerManager::addListener(const std::string &ip,
|
||||
const std::string &certFile,
|
||||
const std::string &keyFile)
|
||||
{
|
||||
#ifndef USE_OPENSSL
|
||||
#ifndef OpenSSL_FOUND
|
||||
if (useSSL)
|
||||
{
|
||||
LOG_ERROR << "Can't use SSL without OpenSSL found in your system";
|
||||
@ -108,7 +107,7 @@ std::vector<trantor::EventLoop *> ListenerManager::createListeners(
|
||||
|
||||
if (listener._useSSL)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
auto cert = listener._certFile;
|
||||
auto key = listener._keyFile;
|
||||
if (cert == "")
|
||||
@ -149,7 +148,7 @@ std::vector<trantor::EventLoop *> ListenerManager::createListeners(
|
||||
"drogon");
|
||||
if (listener._useSSL)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
auto cert = listener._certFile;
|
||||
auto key = listener._keyFile;
|
||||
if (cert == "")
|
||||
|
@ -17,7 +17,8 @@
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <drogon/MultiPart.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#ifdef USE_OPENSSL
|
||||
#include <drogon/config.h>
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/md5.h>
|
||||
#else
|
||||
#include "ssl_funcs/Md5.h"
|
||||
@ -46,7 +47,7 @@ int MultiPartParser::parse(const HttpRequestPtr &req)
|
||||
if (req->method() != Post)
|
||||
return -1;
|
||||
const std::string &contentType =
|
||||
std::dynamic_pointer_cast<HttpRequestImpl>(req)->getHeaderBy(
|
||||
static_cast<HttpRequestImpl *>(req.get())->getHeaderBy(
|
||||
"content-type");
|
||||
if (contentType.empty())
|
||||
{
|
||||
@ -64,7 +65,8 @@ int MultiPartParser::parse(const HttpRequestPtr &req)
|
||||
if (pos == std::string::npos)
|
||||
return -1;
|
||||
std::string boundary = contentType.substr(pos + 9);
|
||||
return parse(req->query(), boundary);
|
||||
|
||||
return parse(req, boundary);
|
||||
}
|
||||
|
||||
int MultiPartParser::parseEntity(const char *begin, const char *end)
|
||||
@ -108,11 +110,12 @@ int MultiPartParser::parseEntity(const char *begin, const char *end)
|
||||
}
|
||||
}
|
||||
|
||||
int MultiPartParser::parse(const string_view &content,
|
||||
int MultiPartParser::parse(const HttpRequestPtr &req,
|
||||
const std::string &boundary)
|
||||
{
|
||||
string_view::size_type pos1, pos2;
|
||||
pos1 = 0;
|
||||
auto content = static_cast<HttpRequestImpl *>(req.get())->bodyView();
|
||||
pos2 = content.find(boundary);
|
||||
while (1)
|
||||
{
|
||||
@ -222,7 +225,7 @@ int HttpFile::saveTo(const std::string &pathAndFilename) const
|
||||
}
|
||||
const std::string HttpFile::getMd5() const
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
MD5_CTX c;
|
||||
unsigned char md5[16] = {0};
|
||||
MD5_Init(&c);
|
||||
|
@ -13,9 +13,9 @@
|
||||
*/
|
||||
|
||||
#include "SharedLibManager.h"
|
||||
#include <drogon/config.h>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <drogon/config.h>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -154,7 +154,7 @@ void SharedLibManager::managerLibs()
|
||||
void *SharedLibManager::loadLibs(const std::string &sourceFile, void *oldHld)
|
||||
{
|
||||
LOG_TRACE << "src:" << sourceFile;
|
||||
std::string cmd = compilerCommand;
|
||||
std::string cmd = COMPILER_COMMAND;
|
||||
auto pos = cmd.rfind("/");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
@ -163,10 +163,10 @@ void *SharedLibManager::loadLibs(const std::string &sourceFile, void *oldHld)
|
||||
cmd.append(" ")
|
||||
.append(sourceFile)
|
||||
.append(" ")
|
||||
.append(compileFlags)
|
||||
.append(COMPILATION_FLAGS)
|
||||
.append(" ")
|
||||
.append(includeDirs);
|
||||
if (std::string(compilerId).find("Clang") != std::string::npos)
|
||||
.append(INCLUDING_DIRS);
|
||||
if (std::string(COMPILER_ID).find("Clang") != std::string::npos)
|
||||
cmd.append(" -shared -fPIC -undefined dynamic_lookup -o ");
|
||||
else
|
||||
cmd.append(" -shared -fPIC --no-gnu-unique -o ");
|
||||
|
@ -69,7 +69,7 @@ void StaticFileRouter::route(
|
||||
{
|
||||
if (cachedResp)
|
||||
{
|
||||
if (std::dynamic_pointer_cast<HttpResponseImpl>(cachedResp)
|
||||
if (static_cast<HttpResponseImpl *>(cachedResp.get())
|
||||
->getHeaderBy("last-modified") ==
|
||||
req->getHeaderBy("if-modified-since"))
|
||||
{
|
||||
@ -124,8 +124,8 @@ void StaticFileRouter::route(
|
||||
{
|
||||
// make a copy
|
||||
auto newCachedResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(
|
||||
cachedResp));
|
||||
*static_cast<HttpResponseImpl *>(
|
||||
cachedResp.get()));
|
||||
newCachedResp->addCookie("JSESSIONID", sessionId);
|
||||
newCachedResp->setExpiredTime(-1);
|
||||
callback(newCachedResp);
|
||||
@ -182,7 +182,7 @@ void StaticFileRouter::route(
|
||||
{
|
||||
// make a copy
|
||||
newCachedResp = std::make_shared<HttpResponseImpl>(
|
||||
*std::dynamic_pointer_cast<HttpResponseImpl>(resp));
|
||||
*static_cast<HttpResponseImpl *>(resp.get()));
|
||||
newCachedResp->setExpiredTime(-1);
|
||||
}
|
||||
newCachedResp->addCookie("JSESSIONID", sessionId);
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <fcntl.h>
|
||||
#include <iomanip>
|
||||
@ -456,18 +455,6 @@ std::string urlEncode(const std::string &src)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string urlDecode(const std::string &szToDecode)
|
||||
{
|
||||
return urlDecode(szToDecode.c_str(),
|
||||
szToDecode.c_str() + szToDecode.length());
|
||||
}
|
||||
|
||||
std::string urlDecode(const string_view &szToDecode)
|
||||
{
|
||||
return urlDecode(szToDecode.data(),
|
||||
szToDecode.data() + szToDecode.length());
|
||||
}
|
||||
|
||||
std::string urlDecode(const char *begin, const char *end)
|
||||
{
|
||||
std::string result;
|
||||
|
@ -18,8 +18,9 @@
|
||||
#include "HttpUtils.h"
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <drogon/config.h>
|
||||
#include <trantor/net/InetAddress.h>
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#include "ssl_funcs/Sha1.h"
|
||||
@ -89,13 +90,10 @@ void WebSocketClientImpl::connectToServerInLoop()
|
||||
LOG_TRACE << "New TcpClient," << _server.toIpPort();
|
||||
_tcpClient =
|
||||
std::make_shared<trantor::TcpClient>(_loop, _server, "httpClient");
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
if (_useSSL)
|
||||
{
|
||||
_tcpClient->enableSSL();
|
||||
}
|
||||
#endif
|
||||
auto thisPtr = shared_from_this();
|
||||
std::weak_ptr<WebSocketClientImpl> weakPtr = thisPtr;
|
||||
|
||||
@ -106,7 +104,7 @@ void WebSocketClientImpl::connectToServerInLoop()
|
||||
return;
|
||||
if (connPtr->connected())
|
||||
{
|
||||
connPtr->setContext(HttpResponseParser(connPtr));
|
||||
connPtr->setContext(std::make_shared<HttpResponseParser>());
|
||||
// send request;
|
||||
LOG_TRACE << "Connection established!";
|
||||
thisPtr->sendReq(connPtr);
|
||||
@ -169,8 +167,7 @@ void WebSocketClientImpl::onRecvMessage(
|
||||
onRecvWsMessage(connPtr, msgBuffer);
|
||||
return;
|
||||
}
|
||||
HttpResponseParser *responseParser =
|
||||
any_cast<HttpResponseParser>(connPtr->getMutableContext());
|
||||
auto responseParser = connPtr->getContext<HttpResponseParser>();
|
||||
|
||||
// LOG_TRACE << "###:" << msg->readableBytes();
|
||||
|
||||
@ -311,8 +308,8 @@ WebSocketClientImpl::WebSocketClientImpl(trantor::EventLoop *loop,
|
||||
void WebSocketClientImpl::sendReq(const trantor::TcpConnectionPtr &connPtr)
|
||||
{
|
||||
trantor::MsgBuffer buffer;
|
||||
auto implPtr = std::dynamic_pointer_cast<HttpRequestImpl>(_upgradeRequest);
|
||||
assert(implPtr);
|
||||
assert(_upgradeRequest);
|
||||
auto implPtr = static_cast<HttpRequestImpl *>(_upgradeRequest.get());
|
||||
implPtr->appendToBuffer(&buffer);
|
||||
LOG_TRACE << "Send request:"
|
||||
<< std::string(buffer.peek(), buffer.readableBytes());
|
||||
|
@ -156,19 +156,6 @@ void WebSocketConnectionImpl::WebSocketConnectionImpl::forceClose()
|
||||
_tcpConn->forceClose();
|
||||
}
|
||||
|
||||
void WebSocketConnectionImpl::setContext(const any &context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
const any &WebSocketConnectionImpl::WebSocketConnectionImpl::getContext() const
|
||||
{
|
||||
return _context;
|
||||
}
|
||||
any *WebSocketConnectionImpl::WebSocketConnectionImpl::getMutableContext()
|
||||
{
|
||||
return &_context;
|
||||
}
|
||||
|
||||
void WebSocketConnectionImpl::setPingMessage(
|
||||
const std::string &message,
|
||||
const std::chrono::duration<long double> &interval)
|
||||
|
@ -69,10 +69,6 @@ class WebSocketConnectionImpl
|
||||
virtual void shutdown() override; // close write
|
||||
virtual void forceClose() override; // close
|
||||
|
||||
virtual void setContext(const any &context) override;
|
||||
virtual const any &getContext() const override;
|
||||
virtual any *getMutableContext() override;
|
||||
|
||||
virtual void setPingMessage(
|
||||
const std::string &message,
|
||||
const std::chrono::duration<long double> &interval) override;
|
||||
@ -105,7 +101,6 @@ class WebSocketConnectionImpl
|
||||
trantor::TcpConnectionPtr _tcpConn;
|
||||
trantor::InetAddress _localAddr;
|
||||
trantor::InetAddress _peerAddr;
|
||||
any _context;
|
||||
bool _isServer = true;
|
||||
WebSocketMessageParser _parser;
|
||||
trantor::TimerId _pingTimerId = trantor::InvalidTimerId;
|
||||
|
@ -15,7 +15,8 @@
|
||||
#include "WebsocketControllersRouter.h"
|
||||
#include "FiltersFunction.h"
|
||||
#include "HttpAppFrameworkImpl.h"
|
||||
#ifdef USE_OPENSSL
|
||||
#include <drogon/config.h>
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#include "ssl_funcs/Sha1.h"
|
||||
|
@ -1,13 +1,29 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
add_executable(cache_map_test CacheMapTest.cc)
|
||||
add_executable(cache_map_test2 CacheMapTest2.cc)
|
||||
add_executable(cookies_test CookiesTest.cc)
|
||||
add_executable(class_name_test ClassNameTest.cc)
|
||||
add_executable(sha1_test Sha1Test.cc)
|
||||
add_executable(view_data_test HttpViewDataTest.cc)
|
||||
add_executable(md5_test Md5Test.cc ../src/ssl_funcs/Md5.cc)
|
||||
add_executable(http_full_date_test HttpFullDateTest.cc)
|
||||
add_executable(gzip_test GzipTest.cc)
|
||||
add_executable(url_codec_test UrlCodecTest.cc)
|
||||
add_executable(main_loop_test MainLoopTest.cc)
|
||||
ADD_EXECUTABLE(cache_map_test CacheMapTest.cc)
|
||||
ADD_EXECUTABLE(cache_map_test2 CacheMapTest2.cc)
|
||||
ADD_EXECUTABLE(cookies_test CookiesTest.cc)
|
||||
ADD_EXECUTABLE(class_name_test ClassNameTest.cc)
|
||||
ADD_EXECUTABLE(sha1_test Sha1Test.cc)
|
||||
ADD_EXECUTABLE(view_data_test HttpViewDataTest.cc)
|
||||
ADD_EXECUTABLE(md5_test Md5Test.cc ../src/ssl_funcs/Md5.cc)
|
||||
ADD_EXECUTABLE(http_full_date_test HttpFullDateTest.cc)
|
||||
ADD_EXECUTABLE(gzip_test GzipTest.cc)
|
||||
ADD_EXECUTABLE(url_codec_test UrlCodecTest.cc)
|
||||
ADD_EXECUTABLE(main_loop_test MainLoopTest.cc)
|
||||
|
||||
SET(test_targets cache_map_test
|
||||
cache_map_test2
|
||||
cookies_test
|
||||
class_name_test
|
||||
sha1_test
|
||||
view_data_test
|
||||
md5_test
|
||||
http_full_date_test
|
||||
gzip_test
|
||||
url_codec_test
|
||||
main_loop_test)
|
||||
|
||||
SET_PROPERTY(TARGET ${test_targets} PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET ${test_targets} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET ${test_targets} PROPERTY CXX_EXTENSIONS OFF)
|
@ -1,5 +1,5 @@
|
||||
#include <drogon/config.h>
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef OpenSSL_FOUND
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#include "../lib/src/ssl_funcs/Sha1.h"
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <iostream>
|
||||
|
||||
@ -9,7 +10,8 @@ int main()
|
||||
auto output2 = drogon::utils::urlDecode(output);
|
||||
std::cout << output2 << std::endl;
|
||||
std::cout << drogon::utils::urlEncode("k2=安&k1=1") << std::endl;
|
||||
std::cout << drogon::utils::urlDecode(string_view("k2%3D%E5%AE%89&k1%3D1"))
|
||||
std::cout << drogon::utils::urlDecode(
|
||||
drogon::string_view("k2%3D%E5%AE%89&k1%3D1"))
|
||||
<< std::endl;
|
||||
return 0;
|
||||
}
|
@ -14,7 +14,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/orm/SqlBinder.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/orm/Exception.h>
|
||||
#include <drogon/orm/Field.h>
|
||||
#include <drogon/orm/Result.h>
|
||||
@ -42,45 +41,38 @@ class DbClient : public trantor::NonCopyable
|
||||
{
|
||||
public:
|
||||
virtual ~DbClient(){};
|
||||
/// Create a new database client with multiple connections;
|
||||
/**
|
||||
* @param connInfo: Connection string with some parameters,
|
||||
* each parameter setting is in the form keyword = value. Spaces around the
|
||||
* equal sign are optional.
|
||||
* To write an empty value, or a value containing spaces, surround it with
|
||||
* single quotes, e.g.,
|
||||
* keyword = 'a value'. Single quotes and backslashes within the value must be
|
||||
* escaped with a backslash, i.e., \' and \\.
|
||||
* Example:
|
||||
* host=localhost port=5432 dbname=mydb connect_timeout=10 password=''
|
||||
* The currently recognized parameter key words are:
|
||||
* - host: can be either a host name or an IP address.
|
||||
* - port: Port number to connect to at the server host.
|
||||
* - dbname: The database name. Defaults to be the same as the user name.
|
||||
* - user: user name to connect as. With PostgreSQL defaults to be the same as
|
||||
* the operating system name of the user running the application.
|
||||
* - password: Password to be used if the server demands password
|
||||
* authentication.
|
||||
*
|
||||
* For other key words on PostgreSQL, see the PostgreSQL documentation.
|
||||
* Only a pair of key values is valid for Sqlite3, and its keyword is
|
||||
* 'filename'.
|
||||
*
|
||||
* @param connNum: The number of connections to database server;
|
||||
*/
|
||||
#if USE_POSTGRESQL
|
||||
/// Create a new database client with multiple connections;
|
||||
/**
|
||||
* @param connInfo: Connection string with some parameters,
|
||||
* each parameter setting is in the form keyword = value. Spaces around the
|
||||
* equal sign are optional.
|
||||
* To write an empty value, or a value containing spaces, surround it with
|
||||
* single quotes, e.g.,
|
||||
* keyword = 'a value'. Single quotes and backslashes within the value must
|
||||
* be escaped with a backslash, i.e., \' and \\. Example: host=localhost
|
||||
* port=5432 dbname=mydb connect_timeout=10 password='' The currently
|
||||
* recognized parameter key words are:
|
||||
* - host: can be either a host name or an IP address.
|
||||
* - port: Port number to connect to at the server host.
|
||||
* - dbname: The database name. Defaults to be the same as the user name.
|
||||
* - user: user name to connect as. With PostgreSQL defaults to be the same
|
||||
* as the operating system name of the user running the application.
|
||||
* - password: Password to be used if the server demands password
|
||||
* authentication.
|
||||
*
|
||||
* For other key words on PostgreSQL, see the PostgreSQL documentation.
|
||||
* Only a pair of key values is valid for Sqlite3, and its keyword is
|
||||
* 'filename'.
|
||||
*
|
||||
* @param connNum: The number of connections to database server;
|
||||
*/
|
||||
static std::shared_ptr<DbClient> newPgClient(const std::string &connInfo,
|
||||
const size_t connNum);
|
||||
#endif
|
||||
#if USE_MYSQL
|
||||
static std::shared_ptr<DbClient> newMysqlClient(const std::string &connInfo,
|
||||
const size_t connNum);
|
||||
#endif
|
||||
#if USE_SQLITE3
|
||||
static std::shared_ptr<DbClient> newSqlite3Client(
|
||||
const std::string &connInfo,
|
||||
const size_t connNum);
|
||||
#endif
|
||||
|
||||
/// Async and nonblocking method
|
||||
/**
|
||||
|
@ -17,13 +17,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <drogon/utils/string_view.h>
|
||||
#include <drogon/orm/ArrayParser.h>
|
||||
#include <drogon/orm/Result.h>
|
||||
#include <drogon/orm/Row.h>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <trantor/utils/config.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __linux__
|
||||
@ -195,7 +195,12 @@ char *Field::as<char *>() const;
|
||||
template <>
|
||||
std::vector<char> Field::as<std::vector<char>>() const;
|
||||
template <>
|
||||
string_view Field::as<string_view>() const;
|
||||
inline drogon::string_view Field::as<drogon::string_view>() const
|
||||
{
|
||||
auto first = _result.getValue(_row, _column);
|
||||
auto length = _result.getLength(_row, _column);
|
||||
return drogon::string_view(first, length);
|
||||
}
|
||||
template <>
|
||||
int Field::as<int>() const;
|
||||
template <>
|
||||
|
@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/orm/Exception.h>
|
||||
#include <drogon/orm/Field.h>
|
||||
#include <drogon/orm/FunctionTraits.h>
|
||||
@ -21,9 +20,6 @@
|
||||
#include <drogon/orm/Row.h>
|
||||
#include <drogon/orm/RowIterator.h>
|
||||
#include <trantor/utils/Logger.h>
|
||||
#if USE_MYSQL
|
||||
#include <mysql.h>
|
||||
#endif
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
@ -315,27 +311,10 @@ class SqlBinder
|
||||
}
|
||||
else if (_type == ClientType::Mysql)
|
||||
{
|
||||
#if USE_MYSQL
|
||||
_objs.push_back(obj);
|
||||
_parameters.push_back((char *)obj.get());
|
||||
_length.push_back(0);
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1:
|
||||
_format.push_back(MYSQL_TYPE_TINY);
|
||||
break;
|
||||
case 2:
|
||||
_format.push_back(MYSQL_TYPE_SHORT);
|
||||
break;
|
||||
case 4:
|
||||
_format.push_back(MYSQL_TYPE_LONG);
|
||||
break;
|
||||
case 8:
|
||||
_format.push_back(MYSQL_TYPE_LONGLONG);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
_format.push_back(getMysqlTypeBySize(sizeof(T)));
|
||||
}
|
||||
else if (_type == ClientType::Sqlite3)
|
||||
{
|
||||
@ -411,6 +390,7 @@ class SqlBinder
|
||||
void exec() noexcept(false);
|
||||
|
||||
private:
|
||||
int getMysqlTypeBySize(size_t size);
|
||||
std::string _sql;
|
||||
DbClient &_client;
|
||||
size_t _paraNum = 0;
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "DbClientImpl.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/orm/DbClient.h>
|
||||
using namespace drogon::orm;
|
||||
using namespace drogon;
|
||||
@ -27,31 +28,40 @@ internal::SqlBinder DbClient::operator<<(std::string &&sql)
|
||||
return internal::SqlBinder(std::move(sql), *this, _type);
|
||||
}
|
||||
|
||||
#if USE_POSTGRESQL
|
||||
std::shared_ptr<DbClient> DbClient::newPgClient(const std::string &connInfo,
|
||||
const size_t connNum)
|
||||
{
|
||||
#if USE_POSTGRESQL
|
||||
return std::make_shared<DbClientImpl>(connInfo,
|
||||
connNum,
|
||||
ClientType::PostgreSQL);
|
||||
}
|
||||
#else
|
||||
LOG_FATAL << "PostgreSQL is not supported!";
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_MYSQL
|
||||
std::shared_ptr<DbClient> DbClient::newMysqlClient(const std::string &connInfo,
|
||||
const size_t connNum)
|
||||
{
|
||||
#if USE_MYSQL
|
||||
return std::make_shared<DbClientImpl>(connInfo, connNum, ClientType::Mysql);
|
||||
}
|
||||
#else
|
||||
LOG_FATAL << "Mysql is not supported!";
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_SQLITE3
|
||||
std::shared_ptr<DbClient> DbClient::newSqlite3Client(
|
||||
const std::string &connInfo,
|
||||
const size_t connNum)
|
||||
{
|
||||
#if USE_SQLITE3
|
||||
return std::make_shared<DbClientImpl>(connInfo,
|
||||
connNum,
|
||||
ClientType::Sqlite3);
|
||||
}
|
||||
#else
|
||||
LOG_FATAL << "Sqlite3 is not supported!";
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "DbClientImpl.h"
|
||||
#include "DbConnection.h"
|
||||
#include <drogon/config.h>
|
||||
#if USE_POSTGRESQL
|
||||
#include "postgresql_impl/PgConnection.h"
|
||||
#endif
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "DbClientLockFree.h"
|
||||
#include "DbConnection.h"
|
||||
#include "TransactionImpl.h"
|
||||
#include <drogon/config.h>
|
||||
#if USE_POSTGRESQL
|
||||
#include "postgresql_impl/PgConnection.h"
|
||||
#endif
|
||||
|
@ -12,8 +12,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "DbClientManager.h"
|
||||
#include "../../lib/src/DbClientManager.h"
|
||||
#include "DbClientLockFree.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -84,13 +84,6 @@ std::vector<char> Field::as<std::vector<char>>() const
|
||||
return utils::hexToBinaryVector(sv.data() + 2, sv.length() - 2);
|
||||
}
|
||||
}
|
||||
template <>
|
||||
string_view Field::as<string_view>() const
|
||||
{
|
||||
auto first = _result.getValue(_row, _column);
|
||||
auto length = _result.getLength(_row, _column);
|
||||
return string_view(first, length);
|
||||
}
|
||||
|
||||
template <>
|
||||
int Field::as<int>() const
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#if USE_MYSQL
|
||||
#include <mysql.h>
|
||||
#endif
|
||||
using namespace drogon::orm;
|
||||
using namespace drogon::orm::internal;
|
||||
void SqlBinder::exec()
|
||||
@ -258,4 +261,31 @@ SqlBinder &SqlBinder::operator<<(std::nullptr_t nullp)
|
||||
_format.push_back(Sqlite3TypeNull);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
int SqlBinder::getMysqlTypeBySize(size_t size)
|
||||
{
|
||||
#if USE_MYSQL
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
return MYSQL_TYPE_TINY;
|
||||
break;
|
||||
case 2:
|
||||
return MYSQL_TYPE_SHORT;
|
||||
break;
|
||||
case 4:
|
||||
return MYSQL_TYPE_LONG;
|
||||
break;
|
||||
case 8:
|
||||
return MYSQL_TYPE_LONGLONG;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
LOG_FATAL << "Mysql is not supported!";
|
||||
exit(1);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
@ -105,7 +105,7 @@ MysqlConnection::MysqlConnection(trantor::EventLoop *loop,
|
||||
LOG_FATAL << "Socket fd < 0, Usually this is because the number of "
|
||||
"files opened by the program exceeds the system "
|
||||
"limit. Please use the ulimit command to check.";
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
_channelPtr =
|
||||
std::unique_ptr<trantor::Channel>(new trantor::Channel(loop, fd));
|
||||
|
@ -1,4 +1,7 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
add_executable(mysql_test1 test1.cc)
|
||||
#add_executable(test2 test2.cc)
|
||||
ADD_EXECUTABLE(mysql_test1 test1.cc)
|
||||
|
||||
SET_PROPERTY(TARGET mysql_test1 PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET mysql_test1 PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET mysql_test1 PROPERTY CXX_EXTENSIONS OFF)
|
@ -50,7 +50,7 @@ PgConnection::PgConnection(trantor::EventLoop *loop,
|
||||
LOG_FATAL << "Socket fd < 0, Usually this is because the number of "
|
||||
"files opened by the program exceeds the system "
|
||||
"limit. Please use the ulimit command to check.";
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
_channel.setReadCallback([=]() {
|
||||
if (_status != ConnectStatus_Ok)
|
||||
|
@ -1,4 +1,8 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
add_executable(pg_test1 test1.cc)
|
||||
add_executable(pg_test2 test2.cc)
|
||||
ADD_EXECUTABLE(pg_test1 test1.cc)
|
||||
ADD_EXECUTABLE(pg_test2 test2.cc)
|
||||
|
||||
SET_PROPERTY(TARGET pg_test1 pg_test2 PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET pg_test1 pg_test2 PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET pg_test1 pg_test2 PROPERTY CXX_EXTENSIONS OFF)
|
@ -48,7 +48,7 @@ Sqlite3Connection::Sqlite3Connection(
|
||||
auto ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
LOG_FATAL << sqlite3_errstr(ret);
|
||||
LOG_FATAL << "SQLITE_CONFIG_MULTITHREAD is not supported!";
|
||||
}
|
||||
});
|
||||
// Get the key and value
|
||||
@ -82,7 +82,7 @@ Sqlite3Connection::Sqlite3Connection(
|
||||
auto thisPtr = shared_from_this();
|
||||
if (ret != SQLITE_OK)
|
||||
{
|
||||
LOG_FATAL << sqlite3_errstr(ret);
|
||||
LOG_FATAL << sqlite3_errmsg(_conn.get());
|
||||
_closeCb(thisPtr);
|
||||
}
|
||||
else
|
||||
|
@ -1,3 +1,7 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
add_executable(sqlite3_test1 test1.cc Groups.cc)
|
||||
ADD_EXECUTABLE(sqlite3_test1 test1.cc Groups.cc)
|
||||
|
||||
SET_PROPERTY(TARGET sqlite3_test1 PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET sqlite3_test1 PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET sqlite3_test1 PROPERTY CXX_EXTENSIONS OFF)
|
@ -1,3 +1,7 @@
|
||||
link_libraries(drogon trantor pthread dl)
|
||||
LINK_LIBRARIES(drogon trantor pthread dl)
|
||||
|
||||
add_executable(db_test db_test.cc Users.cc)
|
||||
ADD_EXECUTABLE(db_test db_test.cc Users.cc)
|
||||
|
||||
SET_PROPERTY(TARGET db_test PROPERTY CXX_STANDARD ${DROGON_CXX_STANDARD})
|
||||
SET_PROPERTY(TARGET db_test PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
SET_PROPERTY(TARGET db_test PROPERTY CXX_EXTENSIONS OFF)
|
@ -8,7 +8,6 @@
|
||||
#include "Users.h"
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <string>
|
||||
#include <trantor/utils/config.h>
|
||||
|
||||
using namespace drogon_model::postgres;
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
*
|
||||
*/
|
||||
#include "Users.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/orm/DbClient.h>
|
||||
#include <iostream>
|
||||
#include <trantor/utils/Logger.h>
|
||||
@ -33,7 +34,7 @@ void testOutput(bool isGood, const std::string &testMessage)
|
||||
{
|
||||
std::cout << RED << testMessage << "\t\tBAD\n";
|
||||
std::cout << RESET;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,12 +44,6 @@ int main()
|
||||
#if USE_POSTGRESQL
|
||||
auto clientPtr = DbClient::newPgClient(
|
||||
"host=127.0.0.1 port=5432 dbname=postgres user=antao", 1);
|
||||
#elif USE_MYSQL
|
||||
auto clientPtr = DbClient::newMysqlClient(
|
||||
"host=127.0.0.1 port=3306 dbname=test user=root", 1);
|
||||
#else
|
||||
DbClientPtr clientPtr;
|
||||
return -1;
|
||||
#endif
|
||||
LOG_DEBUG << "start!";
|
||||
sleep(1);
|
||||
|
2
trantor
2
trantor
@ -1 +1 @@
|
||||
Subproject commit ad24f2c6733681f69c0c5bd9f218ef35c4f346d2
|
||||
Subproject commit 93078923084bab9f4bd9e534e080f806df66fe5e
|
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
echo "update config.h"
|
||||
if [ ! -f $2 ];then
|
||||
mv -f $1 $2
|
||||
else
|
||||
diff $1 $2
|
||||
if [ $? -eq 1 ];then
|
||||
mv -f $1 $2
|
||||
fi
|
||||
fi
|
||||
rm -f $1
|
Loading…
x
Reference in New Issue
Block a user