Port drogon to Windows (#335)

Co-authored-by: mcirsta <mforce2@gmail.com>
This commit is contained in:
An Tao 2020-01-25 11:58:20 +08:00 committed by GitHub
parent 4f319dd9c9
commit 58702dc41e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1587 additions and 370 deletions

6
.gitignore vendored
View File

@ -39,3 +39,9 @@ html/
latex/
.vscode
*.kdev4
.cproject
.project
.settings/
.vs/
CMakeSettings.json

4
.gitmodules vendored
View File

@ -1,6 +1,4 @@
[submodule "trantor"]
path = trantor
url = https://github.com/an-tao/trantor.git
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest

View File

@ -1,7 +1,7 @@
matrix:
include:
- os: linux
dist: xenial
dist: bionic
- os: osx
osx_image: xcode11
@ -38,6 +38,14 @@ addons:
- lz4
- mariadb
- sqlite3
before_install:
- wget https://github.com/google/googletest/archive/release-1.10.0.tar.gz
- tar xf release-1.10.0.tar.gz
- cd googletest-release-1.10.0
- cmake .
- make
- sudo make install
- cd -
before_script:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
brew services restart postgresql;

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.5)
project(drogon CXX)
message(STATUS "compiler: " ${CMAKE_CXX_COMPILER_ID})
option(BUILD_CTL "Build drogon_ctl" ON)
option(BUILD_EXAMPLES "Build examples" ON)
option(BUILD_ORM "Build orm" ON)
@ -43,9 +43,10 @@ endforeach()
if(BUILD_DROGON_SHARED)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${INSTALL_LIB_DIR}" isSystemDir)
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${INSTALL_LIB_DIR}"
isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${INSTALL_LIB_DIR}")
set(CMAKE_INSTALL_RPATH "${INSTALL_LIB_DIR}")
endif("${isSystemDir}" STREQUAL "-1")
add_library(${PROJECT_NAME} SHARED)
else()
@ -69,16 +70,30 @@ target_include_directories(
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/trantor>)
if(WIN32)
target_include_directories(
${PROJECT_NAME}
PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/third_party/mman-win32>)
endif(WIN32)
# set the include list for dynamic view compiling
list(APPEND INCLUDE_DIRS_FOR_DYNAMIC_VIEW
${PROJECT_SOURCE_DIR}/lib/inc
${PROJECT_SOURCE_DIR}/orm_lib/inc
${PROJECT_SOURCE_DIR}/trantor)
if(WIN32)
add_subdirectory(third_party/mman-win32)
endif(WIN32)
add_subdirectory(trantor)
target_link_libraries(${PROJECT_NAME} PUBLIC trantor)
target_link_libraries(${PROJECT_NAME} PRIVATE dl)
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE mman)
else()
target_link_libraries(${PROJECT_NAME} PRIVATE dl)
endif(WIN32)
if(DROGON_CXX_STANDARD LESS 17)
# With C++14, use boost to support any and string_view
@ -104,43 +119,46 @@ if(NOT EXISTS ${JSONCPP_INCLUDE_DIRS}/json/version.h)
message(FATAL_ERROR "Error: jsoncpp lib is too old.....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(
FATAL_ERROR
"jsoncpp lib is too old,please get new version from https://github.com/open-source-parsers/jsoncpp"
)
endif()
if(NOT WIN32)
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(
FATAL_ERROR
"jsoncpp lib is too old,please get new version from https://github.com/open-source-parsers/jsoncpp"
)
endif()
find_package(UUID REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${UUID_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${UUID_LIBRARIES})
find_package(UUID REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${UUID_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${UUID_LIBRARIES})
try_compile(normal_uuid ${CMAKE_BINARY_DIR}/cmaketest
${PROJECT_SOURCE_DIR}/cmake/tests/normal_uuid_lib_test.cc
LINK_LIBRARIES ${UUID_LIBRARIES}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${UUID_INCLUDE_DIR}")
try_compile(ossp_uuid ${CMAKE_BINARY_DIR}/cmaketest
${PROJECT_SOURCE_DIR}/cmake/tests/ossp_uuid_lib_test.cc
LINK_LIBRARIES ${UUID_LIBRARIES}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${UUID_INCLUDE_DIR}")
if(normal_uuid)
try_compile(normal_uuid ${CMAKE_BINARY_DIR}/cmaketest
${PROJECT_SOURCE_DIR}/cmake/tests/normal_uuid_lib_test.cc
LINK_LIBRARIES ${UUID_LIBRARIES}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${UUID_INCLUDE_DIR}")
try_compile(ossp_uuid ${CMAKE_BINARY_DIR}/cmaketest
${PROJECT_SOURCE_DIR}/cmake/tests/ossp_uuid_lib_test.cc
LINK_LIBRARIES ${UUID_LIBRARIES}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${UUID_INCLUDE_DIR}")
if(normal_uuid)
add_definitions(-DUSE_OSSP_UUID=0)
elseif(ossp_uuid)
elseif(ossp_uuid)
add_definitions(-DUSE_OSSP_UUID=1)
else()
else()
message(FATAL_ERROR "uuid lib error")
endif()
find_package(ZLIB REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZLIB_LIBRARIES})
endif()
endif(NOT WIN32)
if(NOT MSVC)
find_package(ZLIB REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZLIB_LIBRARIES})
endif(NOT MSVC)
set(DROGON_SOURCES
lib/src/AOPAdvice.cc
@ -170,13 +188,16 @@ set(DROGON_SOURCES
lib/src/PluginsManager.cc
lib/src/SecureSSLRedirector.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)
if(NOT WIN32)
set(DROGON_SOURCES ${DROGON_SOURCES} lib/src/SharedLibManager.cc)
endif(NOT WIN32)
find_package(OpenSSL)
if(OpenSSL_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${OPENSSL_INCLUDE_DIR})
@ -221,21 +242,19 @@ if(BUILD_ORM)
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!")
target_include_directories(${PROJECT_NAME} PRIVATE ${MYSQL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${MYSQL_CLIENT_LIBS})
set(DROGON_SOURCES ${DROGON_SOURCES}
orm_lib/src/mysql_impl/MysqlConnection.cc
orm_lib/src/mysql_impl/MysqlResultImpl.cc)
endif()
endif()
message(STATUS "Ok! We find the mariadb!")
target_include_directories(${PROJECT_NAME} PRIVATE ${MYSQL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${MYSQL_CLIENT_LIBS})
set(DROGON_SOURCES ${DROGON_SOURCES}
orm_lib/src/mysql_impl/MysqlConnection.cc
orm_lib/src/mysql_impl/MysqlResultImpl.cc)
else(MYSQL_FOUND)
if(MSVC)
find_package(ZLIB REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZLIB_LIBRARIES})
endif(MSVC)
endif(MYSQL_FOUND)
# Find sqlite3.
find_package(SQLite3)
@ -359,10 +378,13 @@ if(BUILD_TESTING)
if(SQLITE3_FOUND)
add_subdirectory(${PROJECT_SOURCE_DIR}/orm_lib/src/sqlite3_impl/test)
endif()
enable_testing()
add_subdirectory(third_party/googletest)
add_subdirectory(unittest)
endif()
find_package(GTest)
if(GTest_FOUND)
message(STATUS "gtest found")
enable_testing()
add_subdirectory(unittest)
endif(GTest_FOUND)
endif(BUILD_TESTING)
# Installation

View File

@ -9,7 +9,7 @@
### Overview
**Drogon** is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web application server programs using C++. **Drogon** is the name of a dragon in the American TV series "Game of Thrones" that I really like.
Drogon's main application platform is Linux. It also supports Mac OS and FreeBSD. Currently, it does not support windows. Its main features are as follows:
Drogon is a cross-platform framework, It supports Linux, Mac OS, FreeBSD and Windows. Its main features are as follows:
* Use a non-blocking I/O network lib based on epoll (kqueue under MacOS/FreeBSD) to provide high-concurrency, high-performance network IO, please visit the [benchmarks](https://github.com/an-tao/drogon/wiki/13-Benchmarks) page and [TFB Live Results](https://tfb-status.techempower.com/) for more details;
* Provide a completely asynchronous programming mode;
@ -46,7 +46,7 @@ using namespace drogon;
int main()
{
app().setLogPath("./")
.setLogLevel(trantor::Logger::WARN)
.setLogLevel(trantor::Logger::kWarn)
.addListener("0.0.0.0", 80)
.setThreadNum(16)
.enableRunAsDaemon()

View File

@ -9,7 +9,7 @@
**Drogon**是一个基于C++14/17的Http应用框架使用Drogon可以方便的使用C++构建各种类型的Web应用服务端程序。
本版本库是github上[Drogon工程](https://github.com/an-tao/drogon)的镜像库。**Drogon**是作者非常喜欢的美剧《权力的游戏》中的一条龙的名字(汉译作卓耿)和龙有关但并不是dragon的误写为了不至于引起不必要的误会这里说明一下。
Drogon的主要应用平台是Linux也支持Mac OS、FreeBSD目前还不支持Windows。它的主要特点如下
Drogon是一个跨平台框架它支持Linux也支持Mac OS、FreeBSDWindows。它的主要特点如下
* 网络层使用基于epoll(MacOS/FreeBSD下是kqueue)的非阻塞IO框架提供高并发、高性能的网络IO。详细请见[性能测试](https://github.com/an-tao/drogon/wiki/13-%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95)和[TFB Live Results](https://tfb-status.techempower.com/)
* 全异步编程模式;

View File

@ -35,6 +35,9 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
NAMES jsoncppd
DOC "jsoncpp debug library"
)
if("${JSONCPP_LIBRARY_DEBUG}" STREQUAL "JSONCPP_LIBRARY_DEBUG-NOTFOUND")
set(JSONCPP_LIBRARY_DEBUG ${JSONCPP_LIBRARIES})
endif()
set(JSONCPP_LIBRARIES optimized ${JSONCPP_LIBRARIES} debug ${JSONCPP_LIBRARY_DEBUG})

View File

@ -1,114 +1,111 @@
#--------------------------------------------------------
# --------------------------------------------------------
# Copyright (C) 1995-2007 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
# This program is free software; you can redistribute it and/or modify it under
# the terms of version 2 of the GNU General Public License as published by the
# Free Software Foundation.
#
# There are special exceptions to the terms and conditions of the GPL
# as it is applied to this software. View the full text of the exception
# in file LICENSE.exceptions in the top-level directory of this software
# distribution.
# There are special exceptions to the terms and conditions of the GPL as it is
# applied to this software. View the full text of the exception in file
# LICENSE.exceptions in the top-level directory of this software distribution.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
# Street, Fifth Floor, Boston, MA 02110-1301, USA
#
# The MySQL Connector/ODBC is licensed under the terms of the
# GPL, like most MySQL Connectors. There are special exceptions
# to the terms and conditions of the GPL as it is applied to
# this software, see the FLOSS License Exception available on
# mysql.com.
# The MySQL Connector/ODBC is licensed under the terms of the GPL, like most
# MySQL Connectors. There are special exceptions to the terms and conditions of
# the GPL as it is applied to this software, see the FLOSS License Exception
# available on mysql.com.
##########################################################################
# ##############################################################################
# -------------- FIND MYSQL_INCLUDE_DIR ------------------
find_path(MYSQL_INCLUDE_DIR
NAMES mysql.h
PATH_SUFFIXES mysql
PATHS /usr/include/mysql
/usr/local/include/mysql
/opt/mysql/mysql/include
/opt/mysql/mysql/include/mysql
/opt/mysql/include
/opt/local/include/mysql5
/usr/local/mysql/include
/usr/local/mysql/include/mysql
$ENV{ProgramFiles}/MySQL/*/include
$ENV{SystemDrive}/MySQL/*/include)
#-------------- FIND MYSQL_INCLUDE_DIR ------------------
FIND_PATH(MYSQL_INCLUDE_DIR mysql.h
/usr/include/mysql
/usr/local/include/mysql
/opt/mysql/mysql/include
/opt/mysql/mysql/include/mysql
/opt/mysql/include
/opt/local/include/mysql5
/usr/local/mysql/include
/usr/local/mysql/include/mysql
$ENV{ProgramFiles}/MySQL/*/include
$ENV{SystemDrive}/MySQL/*/include)
if(EXISTS "${MYSQL_INCLUDE_DIR}/mysql.h")
#----------------- FIND MYSQL_LIB_DIR -------------------
IF (WIN32)
# Set lib path suffixes
# dist = for mysql binary distributions
# build = for custom built tree
IF (CMAKE_BUILD_TYPE STREQUAL Debug)
SET(libsuffixDist debug)
SET(libsuffixBuild Debug)
ELSE (CMAKE_BUILD_TYPE STREQUAL Debug)
SET(libsuffixDist opt)
SET(libsuffixBuild Release)
ADD_DEFINITIONS(-DDBUG_OFF)
ENDIF (CMAKE_BUILD_TYPE STREQUAL Debug)
elseif(EXISTS "${MYSQL_INCLUDE_DIR}/mysql/mysql.h")
set(MYSQL_INCLUDE_DIR ${MYSQL_INCLUDE_DIR}/mysql)
endif()
FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient
PATHS
$ENV{MYSQL_DIR}/lib/${libsuffixDist}
$ENV{MYSQL_DIR}/libmysql
$ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
$ENV{MYSQL_DIR}/client/${libsuffixBuild}
$ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
$ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist}
$ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist})
ELSE (WIN32)
FIND_LIBRARY(MYSQL_LIB NAMES mysqlclient_r mariadbclient
PATHS
/usr/lib/mysql
/usr/local/lib/mysql
/usr/local/mysql/lib
/usr/local/mysql/lib/mysql
/opt/local/mysql5/lib
/opt/local/lib/mysql5/mysql
/opt/mysql/mysql/lib/mysql
/opt/mysql/lib/mysql)
ENDIF (WIN32)
# ----------------- FIND MYSQL_LIB_DIR -------------------
if(WIN32)
# Set lib path suffixes dist = for mysql binary distributions build = for
# custom built tree
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(libsuffixDist debug)
set(libsuffixBuild Debug)
else(CMAKE_BUILD_TYPE STREQUAL Debug)
set(libsuffixDist opt)
set(libsuffixBuild Release)
add_definitions(-DDBUG_OFF)
endif(CMAKE_BUILD_TYPE STREQUAL Debug)
IF(MYSQL_LIB)
GET_FILENAME_COMPONENT(MYSQL_LIB_DIR ${MYSQL_LIB} PATH)
ENDIF(MYSQL_LIB)
find_library(MYSQL_LIB
NAMES mariadbclient
PATHS $ENV{MYSQL_DIR}/lib/${libsuffixDist}
$ENV{MYSQL_DIR}/libmysql
$ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
$ENV{MYSQL_DIR}/client/${libsuffixBuild}
$ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
$ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist}
$ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist})
else(WIN32)
find_library(MYSQL_LIB
NAMES mysqlclient_r mariadbclient
PATHS /usr/lib/mysql
/usr/local/lib/mysql
/usr/local/mysql/lib
/usr/local/mysql/lib/mysql
/opt/local/mysql5/lib
/opt/local/lib/mysql5/mysql
/opt/mysql/mysql/lib/mysql
/opt/mysql/lib/mysql)
endif(WIN32)
set(MYSQL_VERSION_STRING "")
if(MYSQL_LIB)
get_filename_component(MYSQL_LIB_DIR ${MYSQL_LIB} PATH)
endif(MYSQL_LIB)
EXEC_PROGRAM (grep ARGS "MARIADB_BASE_VERSION ${MYSQL_INCLUDE_DIR}/*.h|awk '{print $3}'" OUTPUT_VARIABLE MYSQL_VERSION_STRING)
if(MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR)
set(MYSQL_FOUND TRUE)
IF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR)
SET(MYSQL_FOUND TRUE)
# FIND_LIBRARY(MYSQL_ZLIB zlib PATHS ${MYSQL_LIB_DIR})
# FIND_LIBRARY(MYSQL_TAOCRYPT taocrypt PATHS ${MYSQL_LIB_DIR})
set(MYSQL_CLIENT_LIBS ${MYSQL_LIB})
# IF (MYSQL_ZLIB) SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} zlib) ENDIF
# (MYSQL_ZLIB) IF (MYSQL_TAOCRYPT) SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS}
# taocrypt) ENDIF (MYSQL_TAOCRYPT) Added needed mysqlclient dependencies on
# Windows
if(MSVC)
set(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} shlwapi)
endif(MSVC)
FIND_LIBRARY(MYSQL_ZLIB zlib PATHS ${MYSQL_LIB_DIR})
FIND_LIBRARY(MYSQL_TAOCRYPT taocrypt PATHS ${MYSQL_LIB_DIR})
IF (MYSQL_LIB)
SET(MYSQL_CLIENT_LIBS ${MYSQL_LIB})
ELSE()
SET(MYSQL_CLIENT_LIBS mysqlclient_r)
ENDIF()
IF (MYSQL_ZLIB)
SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} zlib)
ENDIF (MYSQL_ZLIB)
IF (MYSQL_TAOCRYPT)
SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} taocrypt)
ENDIF (MYSQL_TAOCRYPT)
# Added needed mysqlclient dependencies on Windows
IF (WIN32)
SET(MYSQL_CLIENT_LIBS ${MYSQL_CLIENT_LIBS} ws2_32)
ENDIF (WIN32)
MESSAGE(STATUS "MySQL Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}")
MESSAGE(STATUS "MySQL client libraries: ${MYSQL_CLIENT_LIBS}")
ELSEIF (MySQL_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Cannot find MySQL. Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}")
ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR)
message(
STATUS
"MySQL Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}")
message(STATUS "MySQL client libraries: ${MYSQL_CLIENT_LIBS}")
elseif(MySQL_FIND_REQUIRED)
message(
FATAL_ERROR
"Cannot find MySQL. Include dir: ${MYSQL_INCLUDE_DIR} library dir: ${MYSQL_LIB_DIR}"
)
endif(MYSQL_INCLUDE_DIR AND MYSQL_LIB_DIR)

View File

@ -215,4 +215,4 @@
}],
//custom_config: custom configuration for users. This object can be get by the app().getCustomConfig() method.
"custom_config": {}
}
}

View File

@ -20,11 +20,7 @@ target_link_libraries(_drogon_ctl ${PROJECT_NAME})
file(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/templates/*.csp)
foreach(cspFile ${SCP_LIST})
message(STATUS "cspFile:" ${cspFile})
exec_program(basename
ARGS
"${cspFile} .csp"
OUTPUT_VARIABLE
classname)
get_filename_component(classname ${cspFile} NAME_WE)
message(STATUS "view classname:" ${classname})
add_custom_command(OUTPUT ${classname}.h ${classname}.cc
COMMAND _drogon_ctl
@ -43,6 +39,9 @@ add_dependencies(drogon_ctl
trantor
makeVersion
_drogon_ctl)
if(WIN32)
target_link_libraries(drogon_ctl PRIVATE ws2_32 Rpcrt4)
endif(WIN32)
message(STATUS "bin:" ${INSTALL_BIN_DIR})
install(TARGETS drogon_ctl RUNTIME DESTINATION ${INSTALL_BIN_DIR})
install(CODE "execute_process( \
@ -54,25 +53,3 @@ 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)
find_program(STRIP strip)
if(STRIP STREQUAL "STRIP-NOTFOUND")
message(STATUS "strip not found")
else()
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
add_custom_command(TARGET
${ctl_targets}
POST_BUILD
VERBATIM
COMMAND ${STRIP}
-u
-r
${ctl_targets})
else()
add_custom_command(TARGET
${ctl_targets}
POST_BUILD
VERBATIM
COMMAND ${STRIP} -s ${ctl_targets})
endif()
endif()

View File

@ -18,7 +18,9 @@
#include <string>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <fstream>
#include <regex>

View File

@ -24,11 +24,17 @@
#include <fstream>
#include <regex>
#include <algorithm>
#ifndef _WIN32
#include <unistd.h>
#include <dirent.h>
#include <dlfcn.h>
#include <unistd.h>
#else
#include <io.h>
#endif
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using namespace drogon_ctl;
static std::string toLower(const std::string &str)
{
@ -716,7 +722,7 @@ void create_model::createModel(const std::string &path,
std::cout << "Connect to server..." << std::endl;
if (forceOverwrite_)
{
sleep(2);
std::this_thread::sleep_for(2s);
}
else
{
@ -810,7 +816,7 @@ void create_model::createModel(const std::string &path,
std::cout << "Connect to server..." << std::endl;
if (forceOverwrite_)
{
sleep(2);
std::this_thread::sleep_for(2s);
}
else
{
@ -882,7 +888,7 @@ void create_model::createModel(const std::string &path,
std::cout << "Connect..." << std::endl;
if (forceOverwrite_)
{
sleep(1);
std::this_thread::sleep_for(1s);
}
else
{
@ -953,6 +959,7 @@ void create_model::createModel(const std::string &path,
void create_model::createModel(const std::string &path,
const std::string &singleModelName)
{
#ifndef _WIN32
DIR *dp;
if ((dp = opendir(path.c_str())) == NULL)
{
@ -960,13 +967,18 @@ void create_model::createModel(const std::string &path,
return;
}
closedir(dp);
#endif
auto configFile = path + "/model.json";
if (access(configFile.c_str(), 0) != 0)
{
std::cerr << "Config file " << configFile << " not found!" << std::endl;
exit(1);
}
#ifdef _WIN32
if (access(configFile.c_str(), 04) != 0)
#else
if (access(configFile.c_str(), R_OK) != 0)
#endif
{
std::cerr << "No permission to read config file " << configFile
<< std::endl;

View File

@ -18,7 +18,9 @@
#include <string>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <fstream>
#include <regex>

View File

@ -14,10 +14,16 @@
#include "create_project.h"
#include <drogon/DrTemplateBase.h>
#include <drogon/utils/Utilities.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h>
#include <direct.h>
#endif
#include <fstream>
using namespace drogon_ctl;
@ -71,7 +77,8 @@ void create_project::createProject(const std::string &projectName)
exit(1);
}
std::cout << "create a project named " << projectName << std::endl;
mkdir(projectName.data(), 0755);
drogon::utils::createPath(projectName);
// 1.create CMakeLists.txt
auto r = chdir(projectName.data());
(void)(r);
@ -79,12 +86,12 @@ void create_project::createProject(const std::string &projectName)
newCmakeFile(cmakeFile, projectName);
std::ofstream mainFile("main.cc", std::ofstream::out);
newMainFile(mainFile);
mkdir("views", 0755);
mkdir("controllers", 0755);
mkdir("filters", 0755);
mkdir("plugins", 0755);
mkdir("build", 0755);
mkdir("models", 0755);
drogon::utils::createPath("views");
drogon::utils::createPath("controllers");
drogon::utils::createPath("filters");
drogon::utils::createPath("plugins");
drogon::utils::createPath("build");
drogon::utils::createPath("models");
std::ofstream gitFile(".gitignore", std::ofstream::out);
newGitIgFile(gitFile);

View File

@ -13,7 +13,6 @@
*/
#include "cmd.h"
#include <string>
#include <vector>
#include <iostream>

View File

@ -19,7 +19,9 @@
#include <memory>
#include <iomanip>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#endif
using namespace drogon_ctl;
std::string press::detail()

View File

@ -42,7 +42,7 @@ aux_source_directory(models MODEL_SRC)
file(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/views/*.csp)
foreach(cspFile ${SCP_LIST})
message(STATUS "cspFile:" ${cspFile})
EXEC_PROGRAM(basename ARGS "${cspFile} .csp" OUTPUT_VARIABLE classname)
get_filename_component(classname ${cspFile} NAME_WE)
message(STATUS "view classname:" ${classname})
ADD_CUSTOM_COMMAND(OUTPUT ${classname}.h ${classname}.cc
COMMAND drogon_ctl

View File

@ -3,11 +3,7 @@ link_libraries(${PROJECT_NAME})
file(GLOB SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/simple_example/*.csp)
foreach(cspFile ${SCP_LIST})
message(STATUS "cspFile:" ${cspFile})
exec_program(basename
ARGS
"${cspFile} .csp"
OUTPUT_VARIABLE
classname)
get_filename_component(classname ${cspFile} NAME_WE)
message(STATUS "view classname:" ${classname})
add_custom_command(OUTPUT ${classname}.h ${classname}.cc
COMMAND drogon_ctl
@ -52,14 +48,17 @@ add_executable(pipelining_test simple_example_test/HttpPipeliningTest.cc)
add_executable(websocket_test simple_example_test/WebSocketTest.cc)
add_executable(multiple_ws_test simple_example_test/MultipleWsTest.cc)
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)
if(NOT WIN32)
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)
endif(NOT WIN32)
add_custom_command(
TARGET webapp POST_BUILD
COMMAND ${CMAKE_COMMAND}

View File

@ -5,7 +5,7 @@ int main()
{
app()
.setLogPath("./")
.setLogLevel(trantor::Logger::WARN)
.setLogLevel(trantor::Logger::kWarn)
.addListener("0.0.0.0", 7770)
.setThreadNum(0)
.registerSyncAdvice([](const HttpRequestPtr &req) -> HttpResponsePtr {

View File

@ -6,10 +6,10 @@ using namespace drogon;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
{
int count = 0;
auto client = HttpClient::newHttpClient("http://www.baidu.com");
auto client = HttpClient::newHttpClient("https://www.baidu.com");
auto req = HttpRequest::newHttpRequest();
req->setMethod(drogon::Get);
req->setPath("/s");

View File

@ -5,7 +5,9 @@
*/
#include "TestPlugin.h"
#include <unistd.h>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using namespace drogon;
@ -19,7 +21,7 @@ void TestPlugin::initAndStart(const Json::Value &config)
while (!stop_)
{
LOG_DEBUG << "TestPlugin heartbeat!";
sleep(interval_);
std::this_thread::sleep_for(std::chrono::seconds(interval_));
}
});
}

View File

@ -1,4 +1,4 @@
#include "api_v1_ApiTest.h"
#include "api_v1_ApiTest.h"
using namespace api::v1;
// add definition of your processing function here
void ApiTest::rootGet(const HttpRequestPtr &req,
@ -398,7 +398,6 @@ void ApiTest::formTest(const HttpRequestPtr &req,
ret["k1"] = parameters["k1"];
ret["k2"] = parameters["k2"];
ret["k3"] = parameters["k3"];
if (parameters["k1"] == "1" && parameters["k2"] == "" &&
parameters["k3"] == "test@example.com")
{

View File

@ -49,7 +49,7 @@ using namespace drogon;
int main()
{
app().setLogPath("./");
app().setLogLevel(trantor::Logger::WARN);
app().setLogLevel(trantor::Logger::kWarn);
app().addListener("0.0.0.0", 80);
app().setThreadNum(16);
app().enableRunAsDaemon();

View File

@ -301,5 +301,9 @@ int main()
auto resp = HttpResponse::newFileResponse("index.html");
resp->setExpiredTime(0);
app().setCustom404Page(resp);
std::cout << "Date: "
<< std::string{drogon::utils::getHttpFullDate(
trantor::Date::now())}
<< std::endl;
app().run();
}

View File

@ -6,7 +6,7 @@
using namespace drogon;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
auto client = HttpClient::newHttpClient("127.0.0.1", 8848);
client->setPipeliningDepth(64);
int counter = -1;

View File

@ -1,4 +1,4 @@
/**
/**
*
* test.cc
* An Tao
@ -20,14 +20,16 @@
#include <mutex>
#include <future>
#ifndef _WIN32
#include <unistd.h>
#endif
#define RESET "\033[0m"
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define JPG_LEN 44618
#define INDEX_LEN 10605
#define INDEX_LEN 10606
using namespace drogon;
@ -831,7 +833,7 @@ void doTest(const HttpClientPtr &client,
if (resp->getBody().length() == JPG_LEN)
{
outputGood(req, isHttps);
auto lastModified = resp->getHeader("last-modified");
auto &lastModified = resp->getHeader("last-modified");
// LOG_DEBUG << lastModified;
// Test 'Not Modified'
auto req = HttpRequest::newHttpRequest();
@ -1098,7 +1100,7 @@ void doTest(const HttpClientPtr &client,
int main(int argc, char *argv[])
{
trantor::EventLoopThread loop[2];
trantor::Logger::setLogLevel(trantor::Logger::LogLevel::DEBUG);
trantor::Logger::setLogLevel(trantor::Logger::LogLevel::kDebug);
bool ever = false;
if (argc > 1 && std::string(argv[1]) == "-f")
ever = true;
@ -1113,7 +1115,6 @@ int main(int argc, char *argv[])
client->setPipeliningDepth(10);
if (sessionID)
client->addCookie(sessionID);
doTest(client, pro1);
if (app().supportSSL())
{
@ -1130,7 +1131,6 @@ int main(int argc, char *argv[])
}
auto f1 = pro1.get_future();
f1.get();
// LOG_DEBUG << sslClient.use_count();
} while (ever);
// getchar();
loop[0].getLoop()->quit();

View File

@ -23,7 +23,9 @@
#include <vector>
#include <type_traits>
#include <cstdlib>
#ifndef _MSC_VER
#include <cxxabi.h>
#endif
#include <stdio.h>
namespace drogon
@ -104,6 +106,7 @@ class DrClassMap
*/
static std::string demangle(const char *mangled_name)
{
#ifndef _MSC_VER
std::size_t len = 0;
int status = 0;
std::unique_ptr<char, decltype(&std::free)> ptr(
@ -115,6 +118,13 @@ class DrClassMap
}
LOG_ERROR << "Demangle error!";
return "";
#else
auto pos = strstr(mangled_name, " ");
if (pos == nullptr)
return std::string{mangled_name};
else
return std::string{pos + 1};
#endif
}
protected:

View File

@ -658,8 +658,10 @@ class HttpAppFramework : public trantor::NonCopyable
* presents an absolute path, otherwise it presents a relative path to the
* document_root path.
* @param isCaseSensitive
* @param allowAll If it is set to false, only static files with a valid extension can be accessed.
* @param isRecursive If it is set to false, files in sub directories can't be accessed.
* @param allowAll If it is set to false, only static files with a valid
* extension can be accessed.
* @param isRecursive If it is set to false, files in sub directories can't
* be accessed.
* @return HttpAppFramework&
*/
virtual HttpAppFramework &addALocation(
@ -698,17 +700,19 @@ class HttpAppFramework : public trantor::NonCopyable
virtual HttpAppFramework &setFileTypes(
const std::vector<std::string> &types) = 0;
/// Enable supporting for dynamic views loading.
/**
*
* @param libPaths is a vactor that contains paths to view files.
*
* @note
* It is disabled by default.
* This operation can be performed by an option in the configuration file.
*/
/// Enable supporting for dynamic views loading.
/**
*
* @param libPaths is a vactor that contains paths to view files.
*
* @note
* It is disabled by default.
* This operation can be performed by an option in the configuration file.
*/
#ifndef _WIN32
virtual HttpAppFramework &enableDynamicViewsLoading(
const std::vector<std::string> &libPaths) = 0;
#endif
/// Set the maximum number of all connections.
/**

View File

@ -28,6 +28,7 @@
#define METHOD_LIST_BEGIN \
static void initPathRouting() \
{
#ifndef _MSC_VER
#define METHOD_ADD(method, pattern, filters...) \
registerMethod(&method, pattern, {filters}, true, #method)
@ -36,6 +37,16 @@
#define ADD_METHOD_VIA_REGEX(method, regex, filters...) \
registerMethodViaRegex(&method, regex, {filters}, #method)
#else
#define METHOD_ADD(method, pattern, ...) \
registerMethod(&method, pattern, {##__VA_ARGS__}, true, #method)
#define ADD_METHOD_TO(method, path_pattern, ...) \
registerMethod(&method, path_pattern, {##__VA_ARGS__}, false, #method)
#define ADD_METHOD_VIA_REGEX(method, regex, ...) \
registerMethodViaRegex(&method, regex, {##__VA_ARGS__}, #method)
#endif
#define METHOD_LIST_END \
return; \

View File

@ -24,7 +24,11 @@
#define PATH_LIST_BEGIN \
static void initPathRouting() \
{
#ifndef _MSC_VER
#define PATH_ADD(path, filters...) registerSelf__(path, {filters});
#else
#define PATH_ADD(path, ...) registerSelf__(path, {##__VA_ARGS__});
#endif
#define PATH_LIST_END }
namespace drogon

View File

@ -69,8 +69,12 @@ class IOThreadStorage : public trantor::NonCopyable
static_assert(std::is_constructible<C, Args &&...>::value,
"Unable to construct storage with given signature");
size_t numThreads = app().getThreadNum();
#ifdef _WIN32
assert(numThreads > 0 && numThreads != size_t(-1));
#else
assert(numThreads > 0 &&
numThreads != std::numeric_limits<size_t>::max());
#endif
// set the size to numThreads+1 to enable access to this in the main
// thread.
storage_.reserve(numThreads + 1);

View File

@ -77,7 +77,7 @@ class HttpFile
/// Return the file content.
char *fileData() noexcept
{
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L | defined _WIN32
return fileContent_.data();
#else
return (char *)(fileContent_.data());

View File

@ -29,8 +29,11 @@
paths() \
{ \
std::vector<std::pair<std::string, std::vector<std::string>>> vet;
#ifndef _MSC_VER
#define WS_PATH_ADD(path, filters...) vet.push_back({path, {filters}})
#else
#define WS_PATH_ADD(path, ...) vet.push_back({path, {##__VA_ARGS__}})
#endif
#define WS_PATH_LIST_END \
return vet; \

View File

@ -13,7 +13,7 @@
*/
#pragma once
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L | defined _WIN32
#include <any>
#else
#include <boost/any.hpp>
@ -21,7 +21,7 @@
namespace drogon
{
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L | defined _WIN32
using std::any;
using std::any_cast;
#else

View File

@ -13,20 +13,31 @@
*/
#pragma once
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L | defined _WIN32
#include <string_view>
#else
#include <boost/utility/string_view.hpp>
#include <boost/functional/hash.hpp>
#endif
#include <trantor/utils/LogStream.h>
namespace drogon
{
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L | defined _WIN32
using std::string_view;
#else
using boost::string_view;
#endif
} // namespace drogon
namespace trantor
{
inline LogStream &operator<<(LogStream &ls, const drogon::string_view &v)
{
ls.append(v.data(), v.length());
return ls;
}
} // namespace trantor
#if __cplusplus < 201703L
namespace std
@ -77,13 +88,5 @@ struct hash<drogon::string_view>
}
};
} // namespace std
#include <trantor/utils/LogStream.h>
namespace trantor
{
inline LogStream &operator<<(LogStream &ls, const drogon::string_view &v)
{
ls.append(v.data(), v.length());
return ls;
}
} // namespace trantor
#endif

View File

@ -14,15 +14,19 @@
#include "CacheFile.h"
#include <trantor/utils/Logger.h>
#ifdef _WIN32
#include <mman.h>
#else
#include <unistd.h>
#include <sys/mman.h>
#endif
using namespace drogon;
CacheFile::CacheFile(const std::string &path, bool autoDelete)
: autoDelete_(autoDelete), path_(path)
{
file_ = fopen(path_.data(), "w+");
file_ = fopen(path_.data(), "wb+");
}
CacheFile::~CacheFile()
@ -73,4 +77,4 @@ char *CacheFile::data()
}
}
return data_;
}
}

View File

@ -20,7 +20,11 @@
#include <sstream>
#include <thread>
#include <trantor/utils/Logger.h>
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
using namespace drogon;
static bool bytesSize(std::string &sizeStr, size_t &size)
@ -95,7 +99,11 @@ ConfigLoader::ConfigLoader(const std::string &configFile)
std::cerr << "Config file " << configFile << " not found!" << std::endl;
exit(1);
}
#ifdef _WIN32
if (access(configFile.c_str(), 04) != 0)
#else
if (access(configFile.c_str(), R_OK) != 0)
#endif
{
std::cerr << "No permission to read config file " << configFile
<< std::endl;
@ -135,19 +143,19 @@ static void loadLogSetting(const Json::Value &log)
auto logLevel = log.get("log_level", "DEBUG").asString();
if (logLevel == "TRACE")
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
}
else if (logLevel == "DEBUG")
{
trantor::Logger::setLogLevel(trantor::Logger::DEBUG);
trantor::Logger::setLogLevel(trantor::Logger::kDebug);
}
else if (logLevel == "INFO")
{
trantor::Logger::setLogLevel(trantor::Logger::INFO);
trantor::Logger::setLogLevel(trantor::Logger::kInfo);
}
else if (logLevel == "WARN")
{
trantor::Logger::setLogLevel(trantor::Logger::WARN);
trantor::Logger::setLogLevel(trantor::Logger::kWarn);
}
}
static void loadControllers(const Json::Value &controllers)
@ -304,7 +312,7 @@ static void loadApp(const Json::Value &app)
{
drogon::app().setMaxConnectionNumPerIP(maxConnsPerIP);
}
#ifndef _WIN32
// dynamic views
auto enableDynamicViews = app.get("load_dynamic_views", false).asBool();
if (enableDynamicViews)
@ -321,6 +329,7 @@ static void loadApp(const Json::Value &app)
drogon::app().enableDynamicViewsLoading(paths);
}
}
#endif
// log
loadLogSetting(app["log"]);
// run as daemon

View File

@ -51,12 +51,16 @@
#include <tuple>
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <sys/wait.h>
#include <unistd.h>
#include <sys/file.h>
#include <uuid.h>
#include <unistd.h>
#else
#include <io.h>
#endif
using namespace drogon;
using namespace std::placeholders;
@ -104,7 +108,7 @@ std::string getGitCommit()
static void godaemon(void)
{
printf("Initializing daemon mode\n");
#ifndef _WIN32
if (getppid() != 1)
{
pid_t pid;
@ -131,13 +135,19 @@ static void godaemon(void)
ret = dup(0);
(void)ret;
umask(0);
#else
LOG_ERROR << "Cannot run as daemon in Windows";
exit(1);
#endif
return;
}
HttpAppFrameworkImpl::~HttpAppFrameworkImpl() noexcept
{
// Destroy the following objects before the loop destruction
// Destroy the following objects before the loop destruction
#ifndef _WIN32
sharedLibManagerPtr_.reset();
#endif
sessionManagerPtr_.reset();
}
HttpAppFramework &HttpAppFrameworkImpl::setStaticFilesCacheTime(int cacheTime)
@ -154,6 +164,7 @@ HttpAppFramework &HttpAppFrameworkImpl::setGzipStatic(bool useGzipStatic)
staticFileRouterPtr_->setGzipStatic(useGzipStatic);
return *this;
}
#ifndef _WIN32
HttpAppFramework &HttpAppFrameworkImpl::enableDynamicViewsLoading(
const std::vector<std::string> &libPaths)
{
@ -179,6 +190,7 @@ HttpAppFramework &HttpAppFrameworkImpl::enableDynamicViewsLoading(
}
return *this;
}
#endif
HttpAppFramework &HttpAppFrameworkImpl::setFileTypes(
const std::vector<std::string> &types)
{
@ -293,7 +305,11 @@ HttpAppFramework &HttpAppFrameworkImpl::setLogPath(
std::cerr << "Log path dose not exist!\n";
exit(1);
}
#ifdef _WIN32
if (access(logPath.c_str(), 06) != 0)
#else
if (access(logPath.c_str(), R_OK | W_OK) != 0)
#endif
{
std::cerr << "Unable to access log path!\n";
exit(1);
@ -342,6 +358,7 @@ void HttpAppFrameworkImpl::run()
// set relaunching
if (relaunchOnError_)
{
#ifndef _WIN32
while (true)
{
int child_status = 0;
@ -361,12 +378,17 @@ void HttpAppFrameworkImpl::run()
LOG_INFO << "start new process";
}
getLoop()->resetAfterFork();
#endif
}
// set logger
if (!logPath_.empty())
{
if (access(logPath_.c_str(), R_OK | W_OK) >= 0)
#ifdef _WIN32
if (access(logPath_.c_str(), 06) != 0)
#else
if (access(logPath_.c_str(), R_OK | W_OK) != 0)
#endif
{
std::string baseName = logfileBaseName_;
if (baseName == "")
@ -395,12 +417,13 @@ void HttpAppFrameworkImpl::run()
// now start runing!!
running_ = true;
#ifndef _WIN32
if (!libFilePaths_.empty())
{
sharedLibManagerPtr_ = std::unique_ptr<SharedLibManager>(
new SharedLibManager(getLoop(), libFilePaths_));
}
#endif
// Create all listeners.
auto ioLoops = listenerManagerPtr_->createListeners(
std::bind(&HttpAppFrameworkImpl::onAsyncRequest, this, _1, _2),
@ -650,7 +673,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(
bool needSetJsessionid = false;
if (sessionId.empty())
{
sessionId = utils::getUuid().c_str();
sessionId = utils::getUuid();
needSetJsessionid = true;
}
req->setSession(
@ -852,4 +875,4 @@ HttpAppFramework &HttpAppFrameworkImpl::addALocation(
allowAll,
isRecursive);
return *this;
}
}

View File

@ -213,8 +213,10 @@ class HttpAppFrameworkImpl : public HttpAppFramework
const std::string &uploadPath) override;
virtual HttpAppFramework &setFileTypes(
const std::vector<std::string> &types) override;
#ifndef _WIN32
virtual HttpAppFramework &enableDynamicViewsLoading(
const std::vector<std::string> &libPaths) override;
#endif
virtual HttpAppFramework &setMaxConnectionNum(
size_t maxConnections) override;
virtual HttpAppFramework &setMaxConnectionNumPerIP(
@ -409,7 +411,11 @@ class HttpAppFrameworkImpl : public HttpAppFramework
{
return loop->index();
}
#ifdef _WIN32
return size_t(-1);
#else
return std::numeric_limits<size_t>::max();
#endif
}
private:
@ -463,8 +469,9 @@ class HttpAppFrameworkImpl : public HttpAppFramework
size_t threadNum_{1};
std::vector<std::string> libFilePaths_;
#ifndef _WIN32
std::unique_ptr<SharedLibManager> sharedLibManagerPtr_;
#endif
std::string sslCertPath_;
std::string sslKeyPath_;

View File

@ -19,7 +19,9 @@
#include <drogon/utils/Utilities.h>
#include <fstream>
#include <iostream>
#ifndef _WIN32
#include <unistd.h>
#endif
using namespace drogon;
void HttpRequestImpl::parseJson() const

View File

@ -18,14 +18,17 @@
#include <drogon/config.h>
#include <trantor/utils/Logger.h>
#include <fcntl.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef _WIN32
#include <sys/wait.h>
#include <sys/file.h>
#include <unistd.h>
#endif
namespace drogon
{
#ifndef _WIN32
class DrogonFileLocker : public trantor::NonCopyable
{
public:
@ -43,6 +46,7 @@ class DrogonFileLocker : public trantor::NonCopyable
int fd_{0};
};
#endif
} // namespace drogon
using namespace trantor;

View File

@ -28,7 +28,9 @@
#include <fstream>
#include <iostream>
#include <sys/stat.h>
#ifndef _WIN32
#include <unistd.h>
#endif
using namespace drogon;

View File

@ -102,6 +102,9 @@ void SharedLibManager::managerLibs()
#ifdef __linux__
if (st.st_mtim.tv_sec >
dlMap_[filename].mTime.tv_sec)
#elif defined _WIN32
if (st.st_mtime >
dlMap_[filename].mTime.tv_sec)
#else
if (st.st_mtimespec.tv_sec >
dlMap_[filename].mTime.tv_sec)
@ -129,6 +132,8 @@ void SharedLibManager::managerLibs()
dlStat.handle = loadLibs(srcFile, oldHandle);
#ifdef __linux__
dlStat.mTime = st.st_mtim;
#elif defined _WIN32
dlStat.mTime.tv_sec = st.st_mtime;
#else
dlStat.mTime = st.st_mtimespec;
#endif

View File

@ -20,7 +20,9 @@
#include <iostream>
#include <algorithm>
#include <fcntl.h>
#ifndef _WIN32
#include <sys/file.h>
#endif
#include <sys/stat.h>
using namespace drogon;
@ -209,11 +211,15 @@ void StaticFileRouter::sendStaticFileResponse(
{
LOG_TRACE << "last modify time:" << fileStat.st_mtime;
struct tm tm1;
#ifdef _WIN32
gmtime_s(&tm1, &fileStat.st_mtime);
#else
gmtime_r(&fileStat.st_mtime, &tm1);
#endif
timeStr.resize(64);
auto len = strftime((char *)timeStr.data(),
timeStr.size(),
"%a, %d %b %Y %T GMT",
"%a, %d %b %Y %H:%M:%S GMT",
&tm1);
timeStr.resize(len);
const std::string &modiStr =

View File

@ -14,7 +14,13 @@
#include <drogon/utils/Utilities.h>
#include <trantor/utils/Logger.h>
#ifdef _WIN32
#include <Rpc.h>
#include <direct.h>
#include <io.h>
#else
#include <uuid.h>
#endif
#include <zlib.h>
#include <iomanip>
#include <mutex>
@ -27,7 +33,9 @@
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
@ -181,6 +189,32 @@ std::string hexToBinaryString(const char *ptr, size_t length)
}
return ret;
}
#ifdef _WIN32
char *strptime(const char *s, const char *f, struct tm *tm)
{
// std::get_time is defined such that its
// format parameters are the exact same as strptime.
std::istringstream input(s);
input.imbue(std::locale(setlocale(LC_ALL, nullptr)));
input >> std::get_time(tm, f);
if (input.fail())
{
return nullptr;
}
return (char *)(s + input.tellg());
}
time_t timegm(struct tm *tm)
{
struct tm my_tm;
memcpy(&my_tm, tm, sizeof(struct tm));
/* _mkgmtime() changes the value of the struct tm* you pass in, so
* use a copy
*/
return _mkgmtime(&my_tm);
}
#endif
std::string binaryStringToHex(const unsigned char *ptr, size_t length)
{
std::string idString;
@ -271,6 +305,25 @@ std::string getUuid()
std::string ret{binaryStringToHex((const unsigned char *)str, len)};
free(str);
return ret;
#elif defined _WIN32
uuid_t uu;
UuidCreate(&uu);
char tempStr[100];
auto len = snprintf(tempStr,
sizeof(tempStr),
"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
uu.Data1,
uu.Data2,
uu.Data3,
uu.Data4[0],
uu.Data4[1],
uu.Data4[2],
uu.Data4[3],
uu.Data4[4],
uu.Data4[5],
uu.Data4[6],
uu.Data4[7]);
return std::string{tempStr, static_cast<size_t>(len)};
#else
uuid_t uu;
uuid_generate(uu);
@ -664,7 +717,7 @@ std::string urlDecode(const char *begin, const char *end)
if ((i + 2) < len && isxdigit(begin[i + 1]) &&
isxdigit(begin[i + 2]))
{
uint x1 = begin[i + 1];
unsigned int x1 = begin[i + 1];
if (x1 >= '0' && x1 <= '9')
{
x1 -= '0';
@ -677,7 +730,7 @@ std::string urlDecode(const char *begin, const char *end)
{
x1 = x1 - 'A' + 10;
}
uint x2 = begin[i + 2];
unsigned int x2 = begin[i + 2];
if (x2 >= '0' && x2 <= '9')
{
x2 -= '0';
@ -820,7 +873,7 @@ char *getHttpFullDate(const trantor::Date &date)
return lastTimeString;
}
lastSecond = nowSecond;
date.toCustomedFormattedString("%a, %d %b %Y %T GMT",
date.toCustomedFormattedString("%a, %d %b %Y %H:%M:%S GMT",
lastTimeString,
sizeof(lastTimeString));
return lastTimeString;
@ -828,7 +881,7 @@ char *getHttpFullDate(const trantor::Date &date)
trantor::Date getHttpDate(const std::string &httpFullDateString)
{
struct tm tmptm;
strptime(httpFullDateString.c_str(), "%a, %d %b %Y %T", &tmptm);
strptime(httpFullDateString.c_str(), "%a, %d %b %Y %H:%M:%S", &tmptm);
auto epoch = timegm(&tmptm);
return trantor::Date(epoch * MICRO_SECONDS_PRE_SEC);
}
@ -884,7 +937,11 @@ int createPath(const std::string &path)
{
auto tmpPath = path;
std::stack<std::string> pathStack;
#ifdef _WIN32
while (access(tmpPath.c_str(), 06) != 0)
#else
while (access(tmpPath.c_str(), F_OK) != 0)
#endif
{
if (tmpPath == "./" || tmpPath == "/")
return -1;
@ -922,7 +979,11 @@ int createPath(const std::string &path)
}
pathStack.pop();
#ifdef _WIN32
if (mkdir(tmpPath.c_str()) == -1)
#else
if (mkdir(tmpPath.c_str(), 0755) == -1)
#endif
{
LOG_ERROR << "Can't create path:" << path;
return -1;

View File

@ -5,11 +5,12 @@
#include <thread>
#include <trantor/net/EventLoopThread.h>
#include <trantor/utils/Logger.h>
#include <unistd.h>
#include <chrono>
#include <thread>
using namespace std::chrono_literals;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
trantor::EventLoopThread loopThread;
loopThread.run();
@ -17,7 +18,7 @@ int main()
0.1,
4,
30);
sleep(3);
std::this_thread::sleep_for(3s);
for (int i = 0; i < 40; ++i)
{
cache.insert(drogon::utils::formattedString("aaa%d", i),
@ -33,10 +34,10 @@ int main()
cache.insert("2", "second", 5);
cache.insert("3", "third", 5);
std::thread thread1([&] {
sleep(1);
std::this_thread::sleep_for(1s);
cache.erase("3");
cache.insert("3", "THIRD");
sleep(10);
std::this_thread::sleep_for(10s);
if (cache.find("1"))
{
LOG_DEBUG << "sleep 10,1 item:" << cache["1"];
@ -45,7 +46,7 @@ int main()
{
LOG_DEBUG << "can't find 1 item";
}
sleep(15);
std::this_thread::sleep_for(15s);
if (cache.find("1"))
{
LOG_DEBUG << "sleep 15,1 item:" << cache["1"];
@ -54,7 +55,7 @@ int main()
{
LOG_DEBUG << "can't find 1 item";
}
sleep(20);
std::this_thread::sleep_for(20s);
if (cache.find("1"))
{
LOG_DEBUG << "sleep 20,1 item:" << cache["1"];
@ -63,7 +64,7 @@ int main()
{
LOG_DEBUG << "can't find 1 item";
}
sleep(22);
std::this_thread::sleep_for(22s);
if (cache.find("1"))
{
LOG_DEBUG << "sleep22,1 item:" << cache["1"];

View File

@ -6,11 +6,10 @@
#include <thread>
#include <trantor/net/EventLoopThread.h>
#include <trantor/utils/Logger.h>
#include <unistd.h>
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
trantor::EventLoopThread loopThread;
loopThread.run();

View File

@ -1,6 +1,5 @@
#include <drogon/drogon.h>
#include <thread>
#include <unistd.h>
int main()
{

View File

@ -1,4 +1,4 @@
#include <drogon/utils/string_view.h>
#include <drogon/utils/string_view.h>
#include <drogon/utils/Utilities.h>
#include <iostream>

View File

@ -37,8 +37,8 @@ enum class CompareOperator
GE,
LT,
LE,
LIKE,
IN,
Like,
In,
IsNull,
IsNotNull
};
@ -103,7 +103,7 @@ class Criteria
case CompareOperator::LE:
conditionString_ += " <= $?";
break;
case CompareOperator::LIKE:
case CompareOperator::Like:
conditionString_ += " like $?";
break;
case CompareOperator::IsNull:
@ -121,7 +121,7 @@ class Criteria
const CompareOperator &opera,
const std::vector<T> &args)
{
assert(opera == CompareOperator::IN && args.size() > 0);
assert(opera == CompareOperator::In && args.size() > 0);
conditionString_ = colName + " in (";
for (size_t i = 0; i < args.size(); ++i)
{
@ -144,7 +144,7 @@ class Criteria
const CompareOperator &opera,
std::vector<T> &&args)
{
assert(opera == CompareOperator::IN && args.size() > 0);
assert(opera == CompareOperator::In && args.size() > 0);
conditionString_ = colName + " in (";
for (size_t i = 0; i < args.size(); ++i)
{

View File

@ -115,14 +115,14 @@ class DbClient : public trantor::NonCopyable
/// Async and nonblocking method
template <typename... Arguments>
std::future<const Result> execSqlAsyncFuture(const std::string &sql,
Arguments &&... args) noexcept
std::future<Result> execSqlAsyncFuture(const std::string &sql,
Arguments &&... args) noexcept
{
auto binder = *this << sql;
(void)std::initializer_list<int>{
(binder << std::forward<Arguments>(args), 0)...};
std::shared_ptr<std::promise<const Result>> prom =
std::make_shared<std::promise<const Result>>();
std::shared_ptr<std::promise<Result>> prom =
std::make_shared<std::promise<Result>>();
binder >> [=](const Result &r) { prom->set_value(r); };
binder >> [=](const std::exception_ptr &e) { prom->set_exception(e); };
binder.exec();

View File

@ -26,32 +26,11 @@
#include <sstream>
#include <string>
#include <vector>
#ifdef __linux__
#include <arpa/inet.h>
inline uint64_t ntohll(const uint64_t &input)
{
uint64_t rval;
uint8_t *data = (uint8_t *)&rval;
data[0] = input >> 56;
data[1] = input >> 48;
data[2] = input >> 40;
data[3] = input >> 32;
data[4] = input >> 24;
data[5] = input >> 16;
data[6] = input >> 8;
data[7] = input >> 0;
return rval;
}
inline uint64_t htonll(const uint64_t &input)
{
return (ntohll(input));
}
#endif
#ifdef _WIN32
#if (defined __linux__) | (defined __MINGW32__)
inline uint64_t ntohll(const uint64_t &input)
{
uint64_t rval;

View File

@ -20,6 +20,10 @@
#include <type_traits>
#include <vector>
#ifdef _WIN32
using ssize_t = std::intptr_t;
#endif
namespace drogon
{
namespace orm

View File

@ -19,10 +19,10 @@
#include <memory>
#include <string>
#include <future>
#include <algorithm>
#ifdef _WIN32
#define noexcept _NOEXCEPT
#endif
#include <assert.h>
namespace drogon
{
namespace orm
@ -59,6 +59,10 @@ class Result
Result(const ResultImplPtr &ptr) : resultPtr_(ptr)
{
}
Result(const Result &r) noexcept = default;
Result(Result &&) noexcept = default;
Result &operator=(const Result &r) noexcept;
Result &operator=(Result &&) noexcept;
using DifferenceType = long;
using SizeType = unsigned long;
using Reference = Row;
@ -138,8 +142,11 @@ class Result
const char *getValue(SizeType row, RowSizeType column) const;
bool isNull(SizeType row, RowSizeType column) const;
FieldSizeType getLength(SizeType row, RowSizeType column) const;
#ifdef _MSC_VER
public:
#else
protected:
#endif
Result()
{
}
@ -151,6 +158,7 @@ inline void swap(Result &one, Result &two) noexcept
} // namespace orm
} // namespace drogon
#ifndef _MSC_VER
namespace std
{
template <>
@ -159,3 +167,4 @@ inline void swap(drogon::orm::Result &one, drogon::orm::Result &two) noexcept
one.swap(two);
}
} // namespace std
#endif

View File

@ -95,6 +95,8 @@ class ConstResultIterator
{
return index_ <= other.index_;
}
ConstResultIterator(const ConstResultIterator &) noexcept = default;
ConstResultIterator(ConstResultIterator &&) noexcept = default;
private:
friend class Result;

View File

@ -70,6 +70,9 @@ class Row
ConstReverseIterator rend() const;
ConstReverseIterator crend() const;
Row(const Row &r) noexcept = default;
Row(Row &&) noexcept = default;
private:
const Result result_;

View File

@ -29,6 +29,9 @@
#include <string.h>
#include <string>
#include <vector>
#ifdef _WIN32
#include <winsock2.h>
#endif
namespace drogon
{

View File

@ -15,6 +15,7 @@
#include "DbClientImpl.h"
#include "DbConnection.h"
#include <drogon/config.h>
#include <drogon/utils/string_view.h>
#if USE_POSTGRESQL
#include "postgresql_impl/PgConnection.h"
#endif
@ -32,14 +33,17 @@
#include <memory>
#include <sstream>
#include <stdio.h>
#ifndef _WIN32
#include <sys/select.h>
#include <unistd.h>
#endif
#include <thread>
#include <trantor/net/EventLoop.h>
#include <trantor/net/inner/Channel.h>
#include <unistd.h>
#include <unordered_set>
#include <vector>
using namespace drogon;
using namespace drogon::orm;
DbClientImpl::DbClientImpl(const std::string &connInfo,

View File

@ -30,11 +30,13 @@
#include <memory>
#include <sstream>
#include <stdio.h>
#ifndef _WIN32
#include <sys/select.h>
#include <unistd.h>
#endif
#include <thread>
#include <trantor/net/EventLoop.h>
#include <trantor/net/inner/Channel.h>
#include <unistd.h>
#include <unordered_set>
#include <vector>

View File

@ -31,7 +31,7 @@ namespace drogon
{
namespace orm
{
#if __cplusplus >= 201703L
#if __cplusplus >= 201703L | defined _WIN32
using SharedMutex = std::shared_mutex;
#else
using SharedMutex = std::shared_timed_mutex;

View File

@ -154,3 +154,14 @@ int Result::oid(RowSizeType column) const noexcept
{
return resultPtr_->oid(column);
}
Result &Result::operator=(const Result &r) noexcept
{
resultPtr_ = r.resultPtr_;
return *this;
}
Result &Result::operator=(Result &&r) noexcept
{
resultPtr_ = std::move(r.resultPtr_);
return *this;
}

View File

@ -13,9 +13,11 @@
*/
#include "TransactionImpl.h"
#include <drogon/utils/string_view.h>
#include <trantor/utils/Logger.h>
using namespace drogon::orm;
using namespace drogon;
TransactionImpl::TransactionImpl(
ClientType type,

View File

@ -16,9 +16,13 @@
#include "MysqlResultImpl.h"
#include <algorithm>
#include <drogon/utils/Utilities.h>
#include <drogon/utils/string_view.h>
#ifndef _WIN32
#include <poll.h>
#endif
#include <regex>
using namespace drogon;
using namespace drogon::orm;
namespace drogon
{

View File

@ -1,19 +1,21 @@
#include <drogon/orm/DbClient.h>
#include <drogon/utils/Utilities.h>
#include <trantor/utils/Logger.h>
#include <fstream>
#include <iostream>
#include <trantor/utils/Logger.h>
#include <unistd.h>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using namespace drogon::orm;
using namespace drogon;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
auto clientPtr = DbClient::newMysqlClient(
"host= 127.0.0.1 port =3306 dbname= test user = root ", 1);
sleep(1);
std::this_thread::sleep_for(1s);
// for (int i = 0; i < 10; ++i)
// {
// std::string str = formattedString("insert into users

View File

@ -16,10 +16,12 @@
#include "PostgreSQLResultImpl.h"
#include <drogon/orm/Exception.h>
#include <drogon/utils/Utilities.h>
#include <drogon/utils/string_view.h>
#include <trantor/utils/Logger.h>
#include <memory>
#include <stdio.h>
#include <trantor/utils/Logger.h>
using namespace drogon;
using namespace drogon::orm;
namespace drogon

View File

@ -1,17 +1,19 @@
#include <drogon/orm/DbClient.h>
#include <iostream>
#include <trantor/utils/Logger.h>
#include <unistd.h>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using namespace drogon::orm;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
auto clientPtr =
DbClient::newPgClient("host=127.0.0.1 port=5432 dbname=test user=antao",
3);
LOG_DEBUG << "start!";
sleep(1);
std::this_thread::sleep_for(1s);
*clientPtr << "update group_users set join_date=$1,relationship=$2 where "
"g_uuid=420040 and u_uuid=2"
<< nullptr << nullptr << Mode::Blocking >>

View File

@ -4,8 +4,10 @@
#include <iostream>
#include <string>
#include <trantor/utils/Logger.h>
#include <unistd.h>
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using namespace drogon::orm;
class User
{
@ -35,11 +37,11 @@ const std::string User::tableName = "users";
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
auto client =
DbClient::newPgClient("host=127.0.0.1 port=5432 dbname=test user=antao",
1);
sleep(1);
std::this_thread::sleep_for(1s);
LOG_DEBUG << "start!";
{
auto trans = client->newTransaction([](bool committed) {

View File

@ -15,8 +15,10 @@
#include "Sqlite3Connection.h"
#include "Sqlite3ResultImpl.h"
#include <drogon/utils/Utilities.h>
#include <drogon/utils/string_view.h>
#include <regex>
using namespace drogon;
using namespace drogon::orm;
std::once_flag Sqlite3Connection::once_;

View File

@ -3,14 +3,20 @@
#include <drogon/orm/DbClient.h>
#include <iostream>
#include <trantor/utils/Logger.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <thread>
#include <chrono>
using namespace std::chrono_literals;
using namespace drogon::orm;
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
auto clientPtr = DbClient::newSqlite3Client("filename=test.db", 1);
sleep(1);
std::this_thread::sleep_for(1s);
LOG_DEBUG << "start!";
// *clientPtr << "Drop table groups;" << Mode::Blocking >>
@ -103,11 +109,11 @@ int main()
for (auto row : r)
{
std::cout << "is_default: "
<< (row[(size_t)0].isNull() ? "is null, "
: "is not null, ")
<< "bool value:" << row[(size_t)0].as<bool>() << "("
<< row[(size_t)0].as<std::string>() << ")"
<< std::endl;
<< (row[(unsigned long)0].isNull() ? "is null, "
: "is not null, ")
<< "bool value:" << row[(unsigned long)0].as<bool>()
<< "(" << row[(unsigned long)0].as<std::string>()
<< ")" << std::endl;
}
} >> [](const DrogonDbException &e) {
std::cerr << e.base().what() << std::endl;

View File

@ -18,9 +18,10 @@
#include <trantor/utils/Logger.h>
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <thread>
#include <stdlib.h>
using namespace std::chrono_literals;
using namespace drogon::orm;
using namespace drogon_model::postgres;
@ -542,7 +543,7 @@ void doTest(const drogon::orm::DbClientPtr &clientPtr)
/// 5.3 select where in
mapper.findBy(
Criteria(Users::Cols::_id,
CompareOperator::IN,
CompareOperator::In,
std::vector<int32_t>{10, 200}),
[](std::vector<Users> users) {
testOutput(users.size() == 1,
@ -567,13 +568,13 @@ void doTest(const drogon::orm::DbClientPtr &clientPtr)
}
int main(int argc, char *argv[])
{
trantor::Logger::setLogLevel(trantor::Logger::DEBUG);
trantor::Logger::setLogLevel(trantor::Logger::kDebug);
#if USE_POSTGRESQL
auto clientPtr = DbClient::newPgClient(
"host=127.0.0.1 port=5432 dbname=postgres user=postgres", 1);
#endif
LOG_DEBUG << "start!";
sleep(1);
std::this_thread::sleep_for(1s);
if (argc == 2)
{
gLoops = atoi(argv[1]);

26
test.sh
View File

@ -1,5 +1,7 @@
#!/bin/bash
drogon_ctl_exec=`pwd`/build/drogon_ctl/drogon_ctl
echo ${drogon_ctl_exec}
cd build/examples/
#Make webapp run as a daemon
@ -25,7 +27,7 @@ echo "Test http requests and responses."
./webapp_test
if [ $? -ne 0 ]; then
echo "Error in testing"
echo "Error in testing http requests"
exit -1
fi
@ -33,7 +35,7 @@ fi
echo "Test the WebSocket"
./websocket_test -t
if [ $? -ne 0 ]; then
echo "Error in testing"
echo "Error in testing WebSocket"
exit -1
fi
@ -41,7 +43,7 @@ fi
echo "Test the pipelining"
./pipelining_test
if [ $? -ne 0 ]; then
echo "Error in testing"
echo "Error in testing pipelining"
exit -1
fi
@ -51,16 +53,16 @@ killall -9 webapp
echo "Test the drogon_ctl"
rm -rf drogon_test
drogon_ctl create project drogon_test
${drogon_ctl_exec} create project drogon_test
cd drogon_test/controllers
drogon_ctl create controller Test::SimpleCtrl
drogon_ctl create controller -h Test::HttpCtrl
drogon_ctl create controller -w Test::WebsockCtrl
drogon_ctl create controller SimpleCtrl
drogon_ctl create controller -h HttpCtrl
drogon_ctl create controller -w WebsockCtrl
${drogon_ctl_exec} create controller Test::SimpleCtrl
${drogon_ctl_exec} create controller -h Test::HttpCtrl
${drogon_ctl_exec} create controller -w Test::WebsockCtrl
${drogon_ctl_exec} create controller SimpleCtrl
${drogon_ctl_exec} create controller -h HttpCtrl
${drogon_ctl_exec} create controller -w WebsockCtrl
if [ ! -f "Test_SimpleCtrl.h" -o ! -f "Test_SimpleCtrl.cc" -o ! -f "Test_HttpCtrl.h" -o ! -f "Test_HttpCtrl.cc" -o ! -f "Test_WebsockCtrl.h" -o ! -f "Test_WebsockCtrl.cc" ]; then
echo "Failed to create controllers"
@ -74,7 +76,7 @@ fi
cd ../filters
drogon_ctl create filter Test::TestFilter
${drogon_ctl_exec} create filter Test::TestFilter
if [ ! -f "Test_TestFilter.h" -o ! -f "Test_TestFilter.cc" ]; then
echo "Failed to create filters"
@ -83,7 +85,7 @@ fi
cd ../plugins
drogon_ctl create plugin Test::TestPlugin
${drogon_ctl_exec} create plugin Test::TestPlugin
if [ ! -f "Test_TestPlugin.h" -o ! -f "Test_TestPlugin.cc" ]; then
echo "Failed to create plugins"

@ -1 +0,0 @@
Subproject commit 2002f267f05be6f41a3d458954414ba2bfa3ff1d

2
third_party/mman-win32/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
x64
mman.VC.db

33
third_party/mman-win32/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,33 @@
project (mman-win32 C)
cmake_minimum_required (VERSION 3.5)
option (BUILD_TESTS "tests?" OFF)
set (headers mman.h)
set (sources mman.c)
add_library (mman STATIC ${sources})
set_target_properties(mman PROPERTIES EXPORT_NAME MMAN)
install (TARGETS mman
EXPORT MMANTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib${LIB_SUFFIX})
install(EXPORT MMANTargets
DESTINATION "${INSTALL_DROGON_CMAKE_DIR}"
COMPONENT dev)
install (FILES ${headers} DESTINATION include/sys)
if (BUILD_TESTS)
enable_testing ()
add_executable (t_mman test.c)
target_link_libraries (t_mman mman)
add_test (NAME t_mman COMMAND t_mman${CMAKE_EXECUTABLE_SUFFIX})
endif ()

68
third_party/mman-win32/Makefile vendored Normal file
View File

@ -0,0 +1,68 @@
#
# mman-win32 (mingw32) Makefile
#
include config.mak
CFLAGS=-Wall -O3 -fomit-frame-pointer
ifeq ($(BUILD_STATIC),yes)
TARGETS+=libmman.a
INSTALL+=static-install
endif
ifeq ($(BUILD_SHARED),yes)
TARGETS+=libmman.dll
INSTALL+=shared-install
CFLAGS+=-DMMAN_LIBRARY_DLL -DMMAN_LIBRARY
endif
ifeq ($(BUILD_MSVC),yes)
SHFLAGS+=-Wl,--output-def,libmman.def
INSTALL+=lib-install
endif
all: $(TARGETS)
mman.o: mman.c mman.h
$(CC) -o mman.o -c mman.c $(CFLAGS)
libmman.a: mman.o
$(AR) cru libmman.a mman.o
$(RANLIB) libmman.a
libmman.dll: mman.o
$(CC) -shared -o libmman.dll mman.o -Wl,--out-implib,libmman.dll.a
header-install:
mkdir -p $(DESTDIR)$(incdir)
cp mman.h $(DESTDIR)$(incdir)
static-install: header-install
mkdir -p $(DESTDIR)$(libdir)
cp libmman.a $(DESTDIR)$(libdir)
shared-install: header-install
mkdir -p $(DESTDIR)$(libdir)
cp libmman.dll.a $(DESTDIR)$(libdir)
mkdir -p $(DESTDIR)$(bindir)
cp libmman.dll $(DESTDIR)$(bindir)
lib-install:
mkdir -p $(DESTDIR)$(libdir)
cp libmman.lib $(DESTDIR)$(libdir)
install: $(INSTALL)
test.exe: test.c mman.c mman.h
$(CC) -o test.exe test.c -L. -lmman
test: $(TARGETS) test.exe
test.exe
clean::
rm -f mman.o libmman.a libmman.dll.a libmman.dll libmman.def libmman.lib test.exe *.dat
distclean: clean
rm -f config.mak
.PHONY: clean distclean install test

10
third_party/mman-win32/README.md vendored Normal file
View File

@ -0,0 +1,10 @@
mman-win32
==========
mman library for Windows. mirror of https://code.google.com/p/mman-win32/
A light implementation of the mmap functions for MinGW.
The mmap-win32 library implements a wrapper for mmap functions around the memory mapping Windows API.
License: MIT License

BIN
third_party/mman-win32/UpgradeLog.htm vendored Normal file

Binary file not shown.

170
third_party/mman-win32/configure vendored Normal file
View File

@ -0,0 +1,170 @@
#!/bin/sh
# mmap-win32 configure script
#
# Parts copied from FFmpeg's configure
#
set_all(){
value=$1
shift
for var in $*; do
eval $var=$value
done
}
enable(){
set_all yes $*
}
disable(){
set_all no $*
}
enabled(){
eval test "x\$$1" = "xyes"
}
disabled(){
eval test "x\$$1" = "xno"
}
show_help(){
echo "Usage: configure [options]"
echo "Options: [defaults in brackets after descriptions]"
echo "All \"enable\" options have \"disable\" counterparts"
echo
echo " --help print this message"
echo " --prefix=PREFIX install in PREFIX [$PREFIX]"
echo " --bindir=DIR install binaries in DIR [$PREFIX/bin]"
echo " --libdir=DIR install libs in DIR [$PREFIX/lib]"
echo " --incdir=DIR install includes in DIR [$PREFIX/include]"
echo " --enable-static build static libraries [yes]"
echo " --enable-shared build shared libraries [no]"
echo " --enable-msvc create msvc-compatible import lib [auto]"
echo
echo " --cc=CC use C compiler CC [$cc_default]"
echo " --cross-prefix=PREFIX use PREFIX for compilation tools [$cross_prefix]"
exit 1
}
die_unknown(){
echo "Unknown option \"$1\"."
echo "See $0 --help for available options."
exit 1
}
PREFIX="/mingw"
ar="ar"
cc_default="gcc"
ranlib="ranlib"
strip="strip"
DEFAULT="msvc
"
DEFAULT_YES="static
stripping
"
DEFAULT_NO="shared
"
CMDLINE_SELECT="$DEFAULT
$DEFAULT_NO
$DEFAULT_YES
"
enable $DEFAULT_YES
disable $DEFAULT_NO
for opt do
optval="${opt#*=}"
case "$opt" in
--help)
show_help
;;
--prefix=*)
PREFIX="$optval"
;;
--bindir=*)
bindir="$optval"
;;
--libdir=*)
libdir="$optval"
;;
--incdir=*)
incdir="$optval"
;;
--cc=*)
cc="$optval"
;;
--cross-prefix=*)
cross_prefix="$optval"
;;
--enable-?*|--disable-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
echo "$CMDLINE_SELECT" | grep -q "^ *$option\$" || die_unknown $opt
$action $option
;;
*)
die_unknown $opt
;;
esac
done
bindir="${PREFIX}/bin"
libdir="${PREFIX}/lib"
incdir="${PREFIX}/include/sys"
ar="${cross_prefix}${ar}"
cc_default="${cross_prefix}${cc_default}"
ranlib="${cross_prefix}${ranlib}"
strip="${cross_prefix}${strip}"
if ! test -z $cc; then
cc_default="${cc}"
fi
cc="${cc_default}"
disabled static && disabled shared && {
echo "At least one library type must be set.";
exit 1;
}
if enabled msvc; then
lib /? > /dev/null 2>&1 /dev/null || {
echo "MSVC's lib command not found."
echo "Make sure MSVC is installed and its bin folder is in your \$PATH."
exit 1
}
fi
if ! enabled stripping; then
strip="echo ignoring strip"
fi
enabled msvc && libcmd="lib" || libcmd="echo ignoring lib"
echo "# Automatically generated by configure" > config.mak
echo "PREFIX=$PREFIX" >> config.mak
echo "bindir=$bindir" >> config.mak
echo "libdir=$libdir" >> config.mak
echo "incdir=$incdir" >> config.mak
echo "AR=$ar" >> config.mak
echo "CC=$cc" >> config.mak
echo "RANLIB=$ranlib" >> config.mak
echo "STRIP=$strip" >> config.mak
echo "BUILD_STATIC=$static" >> config.mak
echo "BUILD_SHARED=$shared" >> config.mak
echo "BUILD_MSVC=$msvc" >> config.mak
echo "LIBCMD=$libcmd" >> config.mak
echo "prefix: $PREFIX"
echo "bindir: $bindir"
echo "libdir: $libdir"
echo "incdir: $incdir"
echo "ar: $ar"
echo "cc: $cc"
echo "ranlib: $ranlib"
echo "strip: $strip"
echo "static: $static"
echo "shared: $shared"

13
third_party/mman-win32/mman-win32.pro vendored Normal file
View File

@ -0,0 +1,13 @@
QT -= core gui
TARGET = mman
TEMPLATE = lib
DEFINES += MMAN_LIBRARY_DLL
DEFINES += MMAN_LIBRARY
HEADERS += \
mman.h
SOURCES += \
mman.c

185
third_party/mman-win32/mman.c vendored Normal file
View File

@ -0,0 +1,185 @@
#include <windows.h>
#include <errno.h>
#include <io.h>
#include "mman.h"
#ifndef FILE_MAP_EXECUTE
#define FILE_MAP_EXECUTE 0x0020
#endif /* FILE_MAP_EXECUTE */
static int __map_mman_error(const DWORD err, const int deferr)
{
if (err == 0)
return 0;
//TODO: implement
return err;
}
static DWORD __map_mmap_prot_page(const int prot)
{
DWORD protect = 0;
if (prot == PROT_NONE)
return protect;
if ((prot & PROT_EXEC) != 0)
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_READWRITE : PAGE_READONLY;
}
return protect;
}
static DWORD __map_mmap_prot_file(const int prot)
{
DWORD desiredAccess = 0;
if (prot == PROT_NONE)
return desiredAccess;
if ((prot & PROT_READ) != 0)
desiredAccess |= FILE_MAP_READ;
if ((prot & PROT_WRITE) != 0)
desiredAccess |= FILE_MAP_WRITE;
if ((prot & PROT_EXEC) != 0)
desiredAccess |= FILE_MAP_EXECUTE;
return desiredAccess;
}
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off)
{
HANDLE fm, h;
void * map = MAP_FAILED;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4293)
#endif
const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
const DWORD protect = __map_mmap_prot_page(prot);
const DWORD desiredAccess = __map_mmap_prot_file(prot);
const OffsetType maxSize = off + (OffsetType)len;
const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
(DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
errno = 0;
if (len == 0
/* Usupported protection combinations */
|| prot == PROT_EXEC)
{
errno = EINVAL;
return MAP_FAILED;
}
h = ((flags & MAP_ANONYMOUS) == 0) ?
(HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return MAP_FAILED;
}
fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
if (fm == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}
if ((flags & MAP_FIXED) == 0)
{
map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
}
else
{
map = MapViewOfFileEx(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len, addr);
}
CloseHandle(fm);
if (map == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}
return map;
}
int munmap(void *addr, size_t len)
{
if (UnmapViewOfFile(addr))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int _mprotect(void *addr, size_t len, int prot)
{
DWORD newProtect = __map_mmap_prot_page(prot);
DWORD oldProtect = 0;
if (VirtualProtect(addr, len, newProtect, &oldProtect))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int msync(void *addr, size_t len, int flags)
{
if (FlushViewOfFile(addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int mlock(const void *addr, size_t len)
{
if (VirtualLock((LPVOID)addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int munlock(const void *addr, size_t len)
{
if (VirtualUnlock((LPVOID)addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}

76
third_party/mman-win32/mman.h vendored Normal file
View File

@ -0,0 +1,76 @@
/*
* sys/mman.h
* mman-win32
*/
#ifndef _SYS_MMAN_H_
#define _SYS_MMAN_H_
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
/* All the headers include this file. */
#ifndef _MSC_VER
#include <_mingw.h>
#endif
#if defined(MMAN_LIBRARY_DLL)
/* Windows shared libraries (DLL) must be declared export when building the lib and import when building the
application which links against the library. */
#if defined(MMAN_LIBRARY)
#define MMANSHARED_EXPORT __declspec(dllexport)
#else
#define MMANSHARED_EXPORT __declspec(dllimport)
#endif /* MMAN_LIBRARY */
#else
/* Static libraries do not require a __declspec attribute.*/
#define MMANSHARED_EXPORT
#endif /* MMAN_LIBRARY_DLL */
/* Determine offset type */
#include <stdint.h>
#if defined(_WIN64)
typedef int64_t OffsetType;
#else
typedef uint32_t OffsetType;
#endif
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MAP_FILE 0
#define MAP_SHARED 1
#define MAP_PRIVATE 2
#define MAP_TYPE 0xf
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *)-1)
/* Flags for msync. */
#define MS_ASYNC 1
#define MS_SYNC 2
#define MS_INVALIDATE 4
MMANSHARED_EXPORT void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off);
MMANSHARED_EXPORT int munmap(void *addr, size_t len);
MMANSHARED_EXPORT int _mprotect(void *addr, size_t len, int prot);
MMANSHARED_EXPORT int msync(void *addr, size_t len, int flags);
MMANSHARED_EXPORT int mlock(const void *addr, size_t len);
MMANSHARED_EXPORT int munlock(const void *addr, size_t len);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_MMAN_H_ */

28
third_party/mman-win32/mman.sln vendored Normal file
View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mman", "mman.vcxproj", "{592F578E-6F24-47C0-9F6C-07BC9B730E27}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x64.ActiveCfg = Debug|x64
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x64.Build.0 = Debug|x64
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x86.ActiveCfg = Debug|Win32
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Debug|x86.Build.0 = Debug|Win32
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x64.ActiveCfg = Release|x64
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x64.Build.0 = Release|x64
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x86.ActiveCfg = Release|Win32
{592F578E-6F24-47C0-9F6C-07BC9B730E27}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

122
third_party/mman-win32/mman.vcxproj vendored Normal file
View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{592F578E-6F24-47C0-9F6C-07BC9B730E27}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="mman.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="mman.h" />
</ItemGroup>
<ItemGroup>
<None Include="UpgradeLog.htm" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="mman.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mman.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="UpgradeLog.htm" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

235
third_party/mman-win32/test.c vendored Normal file
View File

@ -0,0 +1,235 @@
#include "mman.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifndef NULL
#define NULL (void*)0
#endif
const char* map_file_name = "map_file.dat";
int test_anon_map_readwrite()
{
void* map = mmap(NULL, 1024, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_READ | PROT_WRITE) returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_READ | PROT_WRITE) returned unexpected error: %d\n", errno);
return result;
}
int test_anon_map_readonly()
{
void* map = mmap(NULL, 1024, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return result;
}
int test_anon_map_writeonly()
{
void* map = mmap(NULL, 1024, PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_WRITE) returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_WRITE) returned unexpected error: %d\n", errno);
return result;
}
int test_anon_map_readonly_nowrite()
{
void* map = mmap(NULL, 1024, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return -1;
}
if (*((unsigned char*)map) != 0)
printf("test_anon_map_readonly_nowrite (MAP_ANONYMOUS, PROT_READ) returned unexpected value: %d\n",
(int)*((unsigned char*)map));
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return result;
}
int test_file_map_readwrite()
{
mode_t mode = S_IRUSR | S_IWUSR;
int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
void* map = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
if (map == MAP_FAILED)
{
printf("mmap returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap returned unexpected error: %d\n", errno);
close(o);
/*TODO: get file info and content and compare it with the sources conditions */
unlink(map_file_name);
return result;
}
int test_file_map_mlock_munlock()
{
const size_t map_size = 1024;
int result = 0;
mode_t mode = S_IRUSR | S_IWUSR;
int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
if (o == -1)
{
printf("unable to create file %s: %d\n", map_file_name, errno);
return -1;
}
void* map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
if (map == MAP_FAILED)
{
printf("mmap returned unexpected error: %d\n", errno);
result = -1;
goto done_close;
}
if (mlock(map, map_size) != 0)
{
printf("mlock returned unexpected error: %d\n", errno);
result = -1;
goto done_munmap;
}
*((unsigned char*)map) = 1;
if (munlock(map, map_size) != 0)
{
printf("munlock returned unexpected error: %d\n", errno);
result = -1;
}
done_munmap:
result = munmap(map, map_size);
if (result != 0)
printf("munmap returned unexpected error: %d\n", errno);
done_close:
close(o);
unlink(map_file_name);
done:
return result;
}
int test_file_map_msync()
{
const size_t map_size = 1024;
int result = 0;
mode_t mode = S_IRUSR | S_IWUSR;
int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
if (o == -1)
{
printf("unable to create file %s: %d\n", map_file_name, errno);
return -1;
}
void* map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
if (map == MAP_FAILED)
{
printf("mmap returned unexpected error: %d\n", errno);
result = -1;
goto done_close;
}
*((unsigned char*)map) = 1;
if (msync(map, map_size, MS_SYNC) != 0)
{
printf("msync returned unexpected error: %d\n", errno);
result = -1;
}
result = munmap(map, map_size);
if (result != 0)
printf("munmap returned unexpected error: %d\n", errno);
done_close:
close(o);
unlink(map_file_name);
done:
return result;
}
#define EXEC_TEST(name) \
if (name() != 0) { result = -1; printf( #name ": fail\n"); } \
else { printf(#name ": pass\n"); }
int main()
{
int result = 0;
EXEC_TEST(test_anon_map_readwrite);
//NOTE: this test must cause an access violation exception
//EXEC_TEST(test_anon_map_readonly);
EXEC_TEST(test_anon_map_readonly_nowrite);
EXEC_TEST(test_anon_map_writeonly);
EXEC_TEST(test_file_map_readwrite);
EXEC_TEST(test_file_map_mlock_munlock);
EXEC_TEST(test_file_map_msync);
//TODO: EXEC_TEST(test_file_map_mprotect);
return result;
}

@ -1 +1 @@
Subproject commit 08eb8986c873c3186e9b4550be0a7a01b4193f76
Subproject commit faea59cfe6e1e836a7e9d8a08669b8e2d3a466ae

View File

@ -1,4 +1,4 @@
add_executable(msgbuffer_unittest MsgBufferUnittest.cpp)
add_executable(drogon_msgbuffer_unittest MsgBufferUnittest.cpp)
add_executable(drobject_unittest DrObjectUnittest.cpp)
add_executable(gzip_unittest GzipUnittest.cpp)
add_executable(md5_unittest MD5Unittest.cpp ../lib/src/ssl_funcs/Md5.cc)
@ -6,7 +6,7 @@ add_executable(sha1_unittest SHA1Unittest.cpp ../lib/src/ssl_funcs/Sha1.cc)
add_executable(ostringstream_unittest OStringStreamUnitttest.cpp)
set(UNITTEST_TARGETS
msgbuffer_unittest
drogon_msgbuffer_unittest
drobject_unittest
gzip_unittest
md5_unittest
@ -20,6 +20,6 @@ set_property(TARGET ${UNITTEST_TARGETS} PROPERTY CXX_EXTENSIONS OFF)
include(GoogleTest)
foreach(T ${UNITTEST_TARGETS})
target_link_libraries(${T} PRIVATE drogon gtest)
target_link_libraries(${T} PRIVATE drogon GTest::GTest)
gtest_discover_tests(${T})
endforeach()

View File

@ -1,4 +1,4 @@
#include <drogon/utils/Utilities.h>
#include <drogon/utils/Utilities.h>
#include <gtest/gtest.h>
#include <string>
#include <iostream>