Merge pull request #228 from CrowCpp/revamped_setup

Revamped setup
This commit is contained in:
Farook Al-Sammarraie 2021-10-05 13:33:12 +03:00 committed by GitHub
commit 41468b0ccd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 962 additions and 329 deletions

View File

@ -17,14 +17,19 @@ steps:
- export DEBIAN_FRONTEND=noninteractive
- export TRAVIS_BRANCH=$DRONE_BRANCH
- export TRAVIS_JOB_ID=$DRONE_BUILD_NUMBER
- export COVERALLS_PULL_REQUEST=$DRONE_PULL_REQUEST
- apt-get -y update
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git
- pip3 install mkdocs-material cpp-coveralls pyyaml
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git openssl libssl-dev
- pip3 install mkdocs-material pyyaml --no-input
- git clone https://github.com/CrowCpp/cpp-coveralls.git
- cd cpp-coveralls
- pip3 install . --no-input
- cd ..
- export CC=/usr/bin/gcc
- export CXX=/usr/bin/g++
- mkdir build
- cd build
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
- cd ..
@ -33,7 +38,7 @@ steps:
- export CXX=/usr/bin/clang++
- mkdir build-clang
- cd build-clang
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
@ -58,11 +63,11 @@ steps:
commands:
- export DEBIAN_FRONTEND=noninteractive
- apt-get -y update
- apt-get -y install libboost-all-dev zlib1g-dev gcc clang make cmake python3
- apt-get -y install libboost-all-dev zlib1g-dev gcc clang make cmake python3 openssl libssl-dev
- mkdir build
- cd build
- cmake --version
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
- cd ..
@ -70,7 +75,7 @@ steps:
- export CXX=/usr/bin/clang++
- mkdir build-clang
- cd build-clang
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
@ -108,13 +113,17 @@ steps:
- export TRAVIS_BRANCH=$DRONE_REPO_BRANCH
- export TRAVIS_JOB_ID=$DRONE_BUILD_NUMBER
- apt-get -y update
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git
- pip3 install mkdocs-material cpp-coveralls pyyaml
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git openssl libssl-dev
- pip3 install mkdocs-material pyyaml --no-input
- git clone https://github.com/CrowCpp/cpp-coveralls.git
- cd cpp-coveralls
- pip3 install . --no-input
- cd ..
- export CC=/usr/bin/gcc
- export CXX=/usr/bin/g++
- mkdir build
- cd build
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
- cd ..
@ -123,7 +132,7 @@ steps:
- export CXX=/usr/bin/clang++
- mkdir build-clang
- cd build-clang
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
- cd ..
@ -151,11 +160,11 @@ steps:
commands:
- export DEBIAN_FRONTEND=noninteractive
- apt-get -y update
- apt-get -y install libboost-all-dev zlib1g-dev gcc clang make cmake python3
- apt-get -y install libboost-all-dev zlib1g-dev gcc clang make cmake python3 openssl libssl-dev
- mkdir build
- cd build
- cmake --version
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4
- cd ..
@ -163,7 +172,7 @@ steps:
- export CXX=/usr/bin/clang++
- mkdir build-clang
- cd build-clang
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
- make -j4
- ctest -V -j4

View File

@ -33,6 +33,7 @@ addons:
- mkdocs
- graphviz
- zlib1g-dev
- libssl-dev
before_install:
- if [ "$TRAVIS_COMPILER" == "gcc" -a "$TRAVIS_CPU_ARCH" == "amd64" ]; then export PUSH_COVERAGE=ON; fi
@ -45,12 +46,12 @@ before_script:
- mkdir build
- cd build
- cmake --version
- cmake ..
- cmake .. -DCROW_ENABLE_COMPRESSION=ON -DCROW_ENABLE_SSL=ON -DCROW_AMALGAMATE=ON
script: make -j4 && ctest -V -j4
after_success:
- cd ..
- if [ "$PUSH_COVERAGE" == "ON" ]; then coveralls -i include --exclude-pattern .*/http_parser_merged.h --exclude-pattern .*/TinySHA1.hpp --gcov-options '\-lp'; fi
- if [ "$PUSH_COVERAGE" == "ON" ]; then coveralls -i include --exclude-pattern .*/http_parser_merged.h --exclude-pattern .*/TinySHA1.hpp --gcov-options '\-lp'; fi
- chmod +x scripts/generateDocumentationAndDeploy.sh
- if [ "$TRAVIS_BUILD_DOCS" == "ON" ]; then ./scripts/generateDocumentationAndDeploy.sh; fi

View File

@ -3,68 +3,104 @@
#####################################
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)
# Define the Project Name and Description
project (crow_all LANGUAGES CXX)
# Define the project name and language
project(Crow
LANGUAGES CXX
)
# Define the module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
# Check if Crow is the main project
set(CROW_IS_MAIN_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(CROW_IS_MAIN_PROJECT ON)
endif()
# Set required C++ Standard
# Set required C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release")
# Default to build type "Release" unless tests are being built
if(NOT CMAKE_BUILD_TYPE)
if (NOT CROW_BUILD_TESTS)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release")
else()
message(STATUS "No build type selected but tests are being built, default to Debug")
set(CMAKE_BUILD_TYPE "Debug")
endif()
endif()
#####################################
# Define Options
#####################################
option(BUILD_EXAMPLES "Builds the examples in the project" ON)
option(BUILD_TESTING "Builds the tests in the project" ON)
option(CROW_BUILD_EXAMPLES "Build the examples in the project" ${CROW_IS_MAIN_PROJECT})
option(CROW_BUILD_TESTS "Build the tests in the project" ${CROW_IS_MAIN_PROJECT})
option(CROW_AMALGAMATE "Combine all headers into one" OFF)
option(CROW_INSTALL "Add install step for Crow" ON )
#####################################
# Define CMake Module Imports
#####################################
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/dependencies.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/compiler_options.cmake)
#####################################
# Define project-wide imports
#####################################
# this can be alternatively (and as recommended way) done with target_include_directories()
if(BUILD_EXAMPLES OR BUILD_TESTING)
set(PROJECT_INCLUDE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/include
)
include_directories("${PROJECT_INCLUDE_DIR}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}") # To include crow_all.h
endif()
option(CROW_ENABLE_SSL "Enable SSL capabilities (OpenSSL)" OFF)
option(CROW_ENABLE_COMPRESSION "Enable compression capabilities (ZLIB)" OFF)
#####################################
# Define Targets
#####################################
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/scripts/merge_all.py
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/include/crow/*.h ${CMAKE_CURRENT_SOURCE_DIR}/include/crow/middlewares/*.h
add_library(Crow INTERFACE)
add_library(Crow::Crow ALIAS Crow)
target_include_directories(Crow
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# Amalgamation
add_custom_target(amalgamation ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h)
find_package(Boost 1.64 COMPONENTS system date_time REQUIRED)
find_package(Threads REQUIRED)
target_link_libraries(Crow
INTERFACE
Boost::boost Boost::system Boost::date_time
Threads::Threads
)
if(CROW_ENABLE_COMPRESSION)
find_package(ZLIB REQUIRED)
target_link_libraries(Crow INTERFACE ZLIB::ZLIB)
target_compile_definitions(Crow INTERFACE CROW_ENABLE_COMPRESSION)
endif()
if(CROW_ENABLE_SSL)
find_package(OpenSSL REQUIRED)
target_link_libraries(Crow INTERFACE OpenSSL::SSL)
target_compile_definitions(Crow INTERFACE CROW_ENABLE_SSL)
endif()
if(CROW_AMALGAMATE)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/scripts/merge_all.py
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/include/crow/*.h ${CMAKE_CURRENT_SOURCE_DIR}/include/crow/middlewares/*.h
)
add_custom_target(crow_amalgamated ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h)
endif()
# Examples
if(BUILD_EXAMPLES)
if(CROW_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
# Tests
if (NOT MSVC AND BUILD_TESTING)
if(NOT MSVC AND CROW_BUILD_TESTS)
if(NOT CROW_ENABLE_COMPRESSION)
message(STATUS "Compression tests are omitted. (Configure with CROW_ENABLE_COMPRESSION=ON to enable them)")
endif()
if(NOT CROW_ENABLE_SSL)
message(STATUS "SSL tests are omitted. (Configure with CROW_ENABLE_SSL=ON to enable them)")
else()
add_test(NAME ssl_test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tests/ssl/ssltest)
endif()
add_subdirectory(tests)
enable_testing()
add_test(NAME crow_test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tests/unittest)
@ -74,10 +110,35 @@ endif()
#####################################
# Install Files
#####################################
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h DESTINATION include)
if(CROW_INSTALL)
install(TARGETS Crow EXPORT CrowTargets)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include)
install(EXPORT CrowTargets
FILE CrowTargets.cmake
NAMESPACE Crow::
DESTINATION lib/cmake/Crow
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/CrowConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/CrowConfig.cmake"
INSTALL_DESTINATION lib/cmake/Crow
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/CrowConfig.cmake"
DESTINATION lib/cmake/Crow
)
endif()
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_NAME "Crow")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "CrowCpp")
set(CPACK_PACKAGE_VENDOR "CrowCpp")
set(CPACK_PACKAGE_DESCRIPTION "A Fast and Easy to use C++ microframework for the web.")
set(CPACK_PACKAGE_HOMEPAGE_URL "https://crowcpp.org")
set(CPACK_DEBIAN_PACKAGE_DEBUG OFF)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
include(CPack)

View File

@ -1,3 +1,5 @@
BSD 3-Clause License
Copyright (c) 2014-2017, ipkn
2020-2021, CrowCpp
All rights reserved.
@ -27,4 +29,4 @@ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Crow logo and other graphic material (excluding third party logos) used are under Copyright (c) 2021, Farook Al-Sammarraie (The-EDev), All rights reserved.
The Crow logo and other graphic material (excluding third party logos) used are under exclusive Copyright (c) 2021, Farook Al-Sammarraie (The-EDev), All rights reserved.

View File

@ -5,7 +5,7 @@
<a href="https://cloud.drone.io/CrowCpp/Crow"><img src="https://cloud.drone.io/api/badges/CrowCpp/Crow/status.svg" alt="Build Status"></a>
<a href="https://coveralls.io/github/CrowCpp/Crow?branch=master"><img src="https://coveralls.io/repos/github/CrowCpp/Crow/badge.svg?branch=master" alt="Coverage Status"></a>
<a href="https://crowcpp.org"><img src="https://img.shields.io/badge/-Documentation-informational" alt="Documentation"></a>
<a href="https://gitter.im/crowfork/community?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge"><img src="https://badges.gitter.im/crowfork/community.svg" alt="Gitter"></a>
<a href="https://gitter.im/crowfork/community?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge"><img src="https://img.shields.io/gitter/room/crowfork/community?color=8DDEC5&logo=gitter" alt="Gitter"></a>
<a href="https://opencollective.com/crow"><img alt="Open Collective" src="https://img.shields.io/opencollective/all/crow?label=Support%20Crow&logo=opencollective"></a>
</p>

37
cmake/CrowConfig.cmake.in Normal file
View File

@ -0,0 +1,37 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Boost 1.64 COMPONENTS system date_time)
find_dependency(Threads)
if(CROW_ENABLE_COMPRESSION)
find_dependency(ZLIB)
endif()
if(CROW_ENABLE_SSL)
find_dependency(OpenSSL)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/CrowTargets.cmake")
check_required_components("@PROJECT_NAME@")
get_target_property(_CROW_ILL Crow::Crow INTERFACE_LINK_LIBRARIES)
get_target_property(_CROW_ICD Crow::Crow INTERFACE_COMPILE_DEFINITIONS)
list(REMOVE_ITEM _CROW_ILL "ZLIB::ZLIB" "OpenSSL::SSL")
list(REMOVE_ITEM _CROW_ICD "CROW_ENABLE_SSL" "CROW_ENABLE_COMPRESSION")
if(CROW_ENABLE_COMPRESSION)
list(APPEND _CROW_ILL "ZLIB::ZLIB")
list(APPEND _CROW_ICD "CROW_ENABLE_COMPRESSION")
endif()
if(CROW_ENABLE_SSL)
list(APPEND _CROW_ILL "OpenSSL::SSL")
list(APPEND _CROW_ICD "CROW_ENABLE_SSL")
endif()
set_target_properties(Crow::Crow PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "${_CROW_ICD}"
INTERFACE_LINK_LIBRARIES "${_CROW_ILL}"
)

View File

@ -1,38 +0,0 @@
# - Find Tcmalloc
# Find the native Tcmalloc library
#
# Tcmalloc_LIBRARIES - List of libraries when using Tcmalloc.
# Tcmalloc_FOUND - True if Tcmalloc found.
if (USE_TCMALLOC)
set(Tcmalloc_NAMES tcmalloc)
else ()
set(Tcmalloc_NAMES tcmalloc_minimal tcmalloc)
endif ()
find_library(Tcmalloc_LIBRARY NO_DEFAULT_PATH
NAMES ${Tcmalloc_NAMES}
PATHS ${HT_DEPENDENCY_LIB_DIR} /lib /usr/lib /usr/local/lib /opt/local/lib
)
if (Tcmalloc_LIBRARY)
set(Tcmalloc_FOUND TRUE)
set( Tcmalloc_LIBRARIES ${Tcmalloc_LIBRARY} )
else ()
set(Tcmalloc_FOUND FALSE)
set( Tcmalloc_LIBRARIES )
endif ()
if (Tcmalloc_FOUND)
message(STATUS "Found Tcmalloc: ${Tcmalloc_LIBRARY}")
else ()
message(STATUS "Not Found Tcmalloc: ${Tcmalloc_LIBRARY}")
if (Tcmalloc_FIND_REQUIRED)
message(STATUS "Looked for Tcmalloc libraries named ${Tcmalloc_NAMES}.")
message(FATAL_ERROR "Could NOT find Tcmalloc library")
endif ()
endif ()
mark_as_advanced(
Tcmalloc_LIBRARY
)

View File

@ -1,22 +1,24 @@
# Compiler options with hardening flags
if(MSVC)
list(APPEND compiler_options
/W4
/permissive-
$<$<CONFIG:RELEASE>:/O2 /Ob2>
$<$<CONFIG:MINSIZEREL>:/O1 /Ob1>
$<$<CONFIG:RELWITHDEBINFO>:/Zi /O2 /Ob1>
$<$<CONFIG:DEBUG>:/Zi /Ob0 /Od /RTC1>)
else(MSVC)
list(APPEND compiler_options
-Wall
-Wextra
-Wpedantic
$<$<CONFIG:RELEASE>:-O2>
$<$<CONFIG:DEBUG>:-O0 -g -p -pg>)
endif()
function(add_warnings_optimizations target_name)
if(MSVC)
target_compile_options(${target_name}
PRIVATE
/W4
/permissive-
$<$<CONFIG:RELEASE>:/O2 /Ob2>
$<$<CONFIG:MINSIZEREL>:/O1 /Ob1>
$<$<CONFIG:RELWITHDEBINFO>:/Zi /O2 /Ob1>
$<$<CONFIG:DEBUG>:/Zi /Ob0 /Od /RTC1>
)
else()
target_compile_options(${target_name}
PRIVATE
-Wall
-Wextra
-Wpedantic
$<$<CONFIG:RELEASE>:-O2>
$<$<CONFIG:DEBUG>:-O0 -g -p -pg>
)
endif()
endfunction()

View File

@ -1,35 +0,0 @@
# Dependencies
if(BUILD_EXAMPLES OR BUILD_TESTING)
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
message("Found ccache ${CCACHE_FOUND}")
message("Using ccache to speed up compilation")
set(ENV{CCACHE_CPP2} "yes")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)
find_package(Tcmalloc)
find_package(Threads)
if (MSVC)
set(Boost_USE_STATIC_LIBS ON)
find_package( Boost 1.64.0 COMPONENTS system thread regex REQUIRED )
else()
find_package( Boost 1.64.0 COMPONENTS system thread REQUIRED )
endif()
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIR})
endif()
endif()
if(BUILD_EXAMPLES)
# OpenSSL is needed at runtime dynamically by some examples
# if it isn't installed, the examples won't be built
find_package(OpenSSL)
if(OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
endif()

View File

@ -1,16 +1,12 @@
This page explains how to set Crow up for use with your project.
This page explains how to set Crow up for use with your project (***For versions 0.3+2 and lower***).
##Requirements
- C++ compiler with C++14 support.
- C++ compiler with C++11 support.
- Crow's CI uses g++-9.3 and clang-7.0 running on AMD64 (x86_64) and ARM64v8
- boost library (1.70 or later).
- boost library (1.64 or later).
- **(optional)** ZLib for HTTP Compression.
- **(optional)** CMake and Python3 to build tests and/or examples.
- **(optional)** Linking with jemalloc/tcmalloc is recommended for speed.
!!!note
While using Boost 1.70 or later is recommended, it may be possible to compile a Crow application with version 1.64
<br><br>
@ -22,6 +18,9 @@ This page explains how to set Crow up for use with your project.
###Ubuntu
`sudo apt-get install build-essential libboost-all-dev`
###Arch
`sudo pacman -S python boost boost-libs`
###Non Debian based GNU/Linux
Use your package manager to install the following:
- GCC and G++ (or Clang and Clang++)

View File

@ -0,0 +1,79 @@
Here's how you can install Crow on your favorite GNU/Linux distro.
# Getting Crow
## Requirements
- C++ compiler with at least C++11 support.
- boost library & development headers (1.64 or later).
- **(optional)** ZLib for HTTP Compression.
- **(optional)** OpenSSL for HTTPS support.
- **(optional)** CMake and Python3 to build tests and/or examples.
!!!note
Crow's CI uses `g++-9.3` and `clang-7.0` running on AMD64 (x86_64) and ARM64v8 architectures.
<br><br>
## Using a package Manager
You can install Crow on GNU/Linux as a pre-made package
=== "Debian/Ubuntu"
Simply download Crow's `.deb` file from the [release section](https://github.com/CrowCpp/Crow/releases/latest) and Install it.
=== "Arch"
Crow is available for Arch based distros through the AUR package `crow`.
<br><br>
## Release package
Crow provides an archive containing the framework and CMake files, just copy the `include` folder to `/usr/local/include` and `lib` folder to `/usr/local/lib`.<br><br>
You can also download the `crow_all.h` file and simply include that into your project.
<br><br>
## Installing from source
### Using CMake
1. Download Crow's source code (Either through github's UI or by using<br> `git clone https://github.com/CrowCpp/Crow.git`).
2. Run `mkdir build` inside of crow's source directory.
3. Navigate to the new "build" directory and run the following:<br>
`cmake .. -DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF`
4. Run `make install`.
!!!note
You can ignore `-DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF` if you want to build the Examples and Unit Tests.
<br>
### Manually
Crow can be installed manually on your Linux computer.
#### Multiple header files
=== "Project Only"
Copy Crow's `include` directory to your project's `include` directory.
=== "System wide"
Copy Crow's `include` directory to the `/usr/local/include` directory.
#### Single header (crow_all.h)
!!!warning
`crow_all.h` is recommended only for small, possibly single source file projects, and ideally should not be installed on your system.
navigate to the `scripts` directory and run `./merge_all.py ../include crow_all.h`. This will generate a `crow_all.h` file that you can use in your projects.
!!!note
You can also include or exclude middlewares from your `crow_all.h` by using `-i` or `-e` followed by the middleware header file names separated by a comma (e.g. `merge_all.py ../include crow_all.h -e cookie_parser` to exclude the cookie parser middleware).
# Compiling your project
## Using CMake
In order to get your CMake project to work with Crow, all you need are the following lines in your CMakeLists.txt:
```
find_package(Crow)
target_link_libraries(your_project PUBLIC Crow::Crow)
```
From there CMake should handle compiling and linking your project.
## Directly using a compiler
All you need to do is run the following command:
```
g++ main.cpp -lpthread
```
You can use arguments like `-DCROW_ENABLE_DEBUG`, `-DCROW_ENABLE_COMPRESSION -lz` for HTTP Compression, or `-DCROW_ENABLE_SSL -lssl` for HTTPS support, or even replace g++ with clang++.
!!!warning
If you're using a version of boost prior to 1.69, you'll need to add the argument `-lboost_system` in order for you Crow application to compile correctly.

View File

@ -0,0 +1,57 @@
Here's how you can install Crow on your Mac.
# Getting Crow
## From a [release](https://github.com/CrowCpp/Crow/releases)
### Archive
Crow provides an archive containing the framework and CMake files, You will only need the `include` folder inside that archive.
### Single header file
You can also download the `crow_all.h` file which replaces the `include` folder.
## From Source
To get Crow from source, you only need to download the repository (as a `.zip` or through `git clone https://github.com/CrowCpp/Crow.git`).
### include folder
Once you've downloaded Crow's source code, you only need to take the `include` folder.
### Single header file
You can generate your own single header file by using navigating to the `scripts` folder with your terminal and running the following command:
```
python3 merge_all.py ../include crow_all.h
```
This will generate a `crow_all.h` file which you can use in the following steps
!!!warning
`crow_all.h` is recommended only for small, possibly single source file projects. For larger projects, it is advised to use the multi-header version.
# Setting up your Crow project
## Using XCode
1. Download and install [Homebrew](https://brew.sh).
2. Run `brew install boost` in your terminal.
3. Create a new XCode project (macOS -> Command Line Tool).
4. Change the following project settings:
=== "Multiple Headers"
1. Add header search paths for crow's include folder and boost's folder (`/usr/local/include`, `/usr/local/Cellar/boost/include`, and where you placed Crow's `include` folder)
2. Add linker flags (`-lpthread` and `-lboost_system` if you're running an old version of boost)
=== "Single Header"
1. Place `crow_all.h` inside your project folder and add it to the project in XCode (you need to use the File -> )
2. Add header search paths for boost's folder (`/usr/local/include`, and `/usr/local/Cellar/boost/include`)
3. Add linker flags (`-lpthread` and `-lboost_system` if you're running an old version of boost)
5. Write your Crow application in `main.cpp` (something like the Hello World example will work).
6. Press `▶` to compile and run your Crow application.
# Building Crow's tests/examples
1. Download and install [Homebrew](https://brew.sh).
2. Run `brew install cmake boost` in your terminal.
3. Get Crow's source code (the entire source code).
3. Run the following Commands:
1. `mkdir build`
2. `cd build`
3. `cmake ..`
4. `make -j12`
!!!note
You can add options like `-DCROW_ENABLE_SSL`, `-DCROW_ENABLE_COMPRESSION`, or `-DCROW_AMALGAMATE` to `3.c` to build their tests/examples.

View File

@ -0,0 +1,22 @@
Here's how you can install Crow on your Windows machine.
# Getting and Compiling Crow
## Using A package manager
### VCPKG
Crow can be simply installed through VCPKG using the command `vcpkg install crow`
## Manually (source or release)
### Microsoft Visual Studio 2019 and VCPKG
The following guide will use `example_with_all.cpp` as the Crow application for demonstration purposes. VCPKG will be used only to install Crow's dependencies.
1. Generate `crow_all.h` by navigating to the `scripts` folder and running `python3 merge_all.py ..\include crow_all.h`.
2. `git clone https://github.com/microsoft/vcpkg.git`
3. `.\vcpkg\bootstrap-vcpkg.bat`
4. `.\vcpkg\vcpkg integrate install`
5. Create empty Visual Studio project.
6. In solution explorer, right click the name of your project then click `Open Folder in File Explorer`.
7. Copy `crow_all.h`, `example_with_all.cpp`, `vcpkg.json` to opened folder.
8. Add `crow_all.h` to `Header Files` and `example_with_all.cpp` to `Source Files`.
9. In solution explorer, right click the name of your project then click `Properties`.
10. Under `vcpkg`, set `Use Vcpkg Manifest` to `Yes` and `Additional Options` to `--feature-flags="versions"`.
11. Set `Debug/Release` and `x64/x86`.
12. Run.

View File

@ -82,3 +82,7 @@ instead of assigning a response code, you can use the `crow::status` enum, for e
##Catchall routes
**Introduced in: `v0.3`**<br><br>
By default, any request that Crow can't find a route for will return a simple 404 response. You can change that to return a default route using the `CROW_CATCHALL_ROUTE(app)` macro. Defining it is identical to a normal route, even when it comes to the `const crow::request&` and `crow::response&` parameters being optional.
!!!note
For versions higher than 0.3 (excluding patches), Catchall routes handle 404 and 405 responses. The default response will contain the code 404 or 405.

View File

@ -90,7 +90,7 @@ code{
.dcard{
width: 10rem;
height: 15rem;
height: 14rem;
margin-inline: 0.5rem;
display: inline-block;
transition: transform 0.3s;
@ -119,6 +119,9 @@ code{
font-size: 0.75rem;
margin: 0.1rem 0px;
text-align: center;
display: block;
min-height: 50px;
overflow: hidden;
}
</style>
@ -207,6 +210,16 @@ code{
<h3 style="text-align:center;">Crow is provided free of charge courtesy of everyone who is donating their money, time, and expertise to keep it going.<h3>
<h3 style="text-align:center;">Help us make something great!</h3>
<dev class="sbuttons">
<h2 style="text-align:center;">Sponsors</h2>
<object type="image/svg+xml" data="https://opencollective.com/crow/tiers/sponsor.svg?avatarHeight=128&button=false"></object><br>
<h2 style="text-align:center;">Boosters</h2>
<object type="image/svg+xml" data="https://opencollective.com/crow/tiers/booster.svg?avatarHeight=64&button=false"></object><br>
<h2 style="text-align:center;">Backers</h2>
<object type="image/svg+xml" data="https://opencollective.com/crow/tiers/backer.svg?avatarHeight=32&button=false"></object><br>
<h2 style="text-align:center;">Donators</h2>
<object type="image/svg+xml" data="https://opencollective.com/crow/tiers/donation.svg?avatarHeight=32&button=false"></object><br>
</dev>
<dev class="sbuttons">
<a href="https://opencollective.com/crow" title="Crow - OpenCollective" class="md-button crow-button">Fund Crow</a>
<a href="https://github.com/CrowCpp/Crow" title="Crow - OpenCollective" class="md-button crow-button">Develop Crow</a>
@ -231,7 +244,7 @@ code{
<a href="https://aur.archlinux.org/packages/crow">
<img class="dcard__image" src="/assets/pkg_logos/arch.png">
<p class="dcard__title">AUR</p>
<p class="dcard__description">for Arch based systems</p>
<p class="dcard__description">for Arch Linux based systems</p>
</a>
</div>
@ -276,7 +289,42 @@ code{
{% endblock %}
{% block site_nav %}{% endblock %}
<!-- Navigation -->
{% block site_nav %}
<!-- Main navigation -->
{% if nav %}
<div
class="md-sidebar md-sidebar--primary"
data-md-component="sidebar"
data-md-type="navigation"
hidden
>
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
{% include "partials/nav.html" %}
</div>
</div>
</div>
{% endif %}
<!-- Table of contents -->
{% if page.toc and not "toc.integrate" in features %}
<div
class="md-sidebar md-sidebar--secondary"
data-md-component="sidebar"
data-md-type="toc"
hidden
>
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
{% include "partials/toc.html" %}
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block footer %}
<footer class="md-footer">
@ -294,6 +342,8 @@ code{
{{ extracopyright }}
</div>
<a style="margin: auto .6rem; font-size: .64rem;" href="/privacy_policy.html">Privacy Policy</a>
<!-- Social links -->
{% include "partials/social.html" %}
</div>

View File

@ -0,0 +1,103 @@
<!--
Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
{% import "partials/language.html" as lang with context %}
<!-- Footer -->
<footer class="md-footer">
<!-- Link to previous and/or next page -->
{% if page.previous_page or page.next_page %}
<nav
class="md-footer__inner md-grid"
aria-label="{{ lang.t('footer.title') }}"
>
<!-- Link to previous page -->
{% if page.previous_page %}
{% set direction = lang.t("footer.previous") %}
<a
href="{{ page.previous_page.url | url }}"
class="md-footer__link md-footer__link--prev"
aria-label="{{ direction }}: {{ page.previous_page.title | e }}"
rel="prev"
>
<div class="md-footer__button md-icon">
{% include ".icons/material/arrow-left.svg" %}
</div>
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
{{ direction }}
</span>
{{ page.previous_page.title }}
</div>
</div>
</a>
{% endif %}
<!-- Link to next page -->
{% if page.next_page %}
{% set direction = lang.t("footer.next") %}
<a
href="{{ page.next_page.url | url }}"
class="md-footer__link md-footer__link--next"
aria-label="{{ direction }}: {{ page.next_page.title | e }}"
rel="next"
>
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
{{ direction }}
</span>
{{ page.next_page.title }}
</div>
</div>
<div class="md-footer__button md-icon">
{% include ".icons/material/arrow-right.svg" %}
</div>
</a>
{% endif %}
</nav>
{% endif %}
<!-- Further information -->
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<!-- Copyright and theme information -->
<div class="md-footer-copyright">
{% if config.copyright %}
<div class="md-footer-copyright__highlight">
{{ config.copyright }}
</div>
{% endif %}
{{ extracopyright }}
</div>
<a style="margin: auto .6rem; font-size: .64rem;" href="/privacy_policy.html">Privacy Policy</a>
<!-- Social links -->
{% include "partials/social.html" %}
</div>
</div>
</footer>

View File

@ -0,0 +1,19 @@
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="{{config.extra.analytics.link}}";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '{{config.extra.analytics.id}}']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<noscript>
<img referrerpolicy="no-referrer-when-downgrade" src="https://thee.dev/matomo/matomo.php?idsite=1&amp;rec=1&amp;action_name={{ page.title }}" style="border:0" alt="" />
</noscript>
<!-- End Matomo Code -->

View File

@ -0,0 +1,37 @@
{% extends "main.html" %}
{% block content %}
<h1>Privacy Policy for CrowCpp</h1>
<p>If you have additional questions or require more information about our Privacy Policy, do not hesitate to contact us.</p>
<p>This Privacy Policy applies only to our online activities and is valid for visitors to our website with regards to the information that they shared and/or collect in CrowCpp. This policy is not applicable to any information collected offline or via channels other than this website.</p>
<h2>Consent</h2>
<p>By using our website, you hereby consent to our Privacy Policy and agree to its terms.</p>
<h2>Log Files</h2>
<p>CrowCpp follows a standard procedure of using log files. These files log visitors when they visit websites. All hosting companies do this and a part of hosting services' analytics. The information collected by log files include internet protocol (IP) addresses, browser type, Internet Service Provider (ISP), date and time stamp, referring/exit pages, and possibly the number of clicks. These are not linked to any information that is personally identifiable. The purpose of the information is for analyzing trends, administering the site, tracking users' movement on the website.</p>
<h2>Other information we collect</h2>
<p>If you contact us directly, we may receive information about you such as your name, email address, phone number, the contents of the message and/or attachments you may send us, and any other information you may choose to provide.</p>
<h2>How we use your information</h2>
<p>We use the information we collect in various ways, including to:</p>
<ul>
<li>Provide, operate, and maintain our website</li>
<li>Improve or expand our website</li>
<li>Understand and analyze how you use our website</li>
<li>Find and prevent fraud</li>
</ul>
<h2>Children's Information</h2>
<p>CrowCpp does not knowingly collect any Personal Identifiable Information from children under the age of 13. If you think that your child provided this kind of information on our website, we strongly encourage you to contact us immediately and we will do our best efforts to promptly remove such information from our records.</p>
{% endblock %}
{% block site_nav %}{% endblock %}

View File

@ -4,28 +4,43 @@
--md-accent-fg-color: #122027;
--md-typeset-a-color: var(--md-accent-fg-color) !important;
--md-default-bg-color: #e5f2f8;
--md-code-bg-color: #2e3639 !important;
--md-code-bg-color: #cfcfcf !important;
--md-code-hl-comment-color: var(--md-code-fg-color) !important;
--md-code-hl-generic-color: var(--md-code-fg-color) !important;
--md-code-hl-variable-color: var(--md-code-fg-color) !important;
--md-code-fg-color: #fff !important;
--md-code-hl-punctuation-color: #fff !important;
}
.md-typeset code {
background-color: #2e3639;
color: #afafaf;
background-color: #cfcfcf;
color: #1d1d1d;
padding: 0.2rem;
}
.highlight .c, .highlight .c1, .highlight .ch, .highlight .cm, .highlight .cs, .highlight .sd {
color: #606060 !important;
}
.linenos {
background-color: #2e3639 !important;
color: #afafaf !important;
background-color: #cfcfcf !important;
color: #1d1d1d !important;
}
.highlighttable .linenodiv pre {
background-color: #cfcfcf !important;
color: #1d1d1d !important;
}
.highlight .p {
color: #bbb;
color: #1d1d1d;
}
.highlight .o {
color: #afafaf;
color: #1d1d1d;
}
.highlight .n {
color: #afafaf;
color: #1d1d1d;
}

View File

@ -1,91 +1,86 @@
cmake_minimum_required(VERSION 3.15)
project (crow_examples)
project(crow_examples)
# Define Required libraries
list(APPEND REQUIRED_LIBRARIES
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
z
)
include(${CMAKE_SOURCE_DIR}/cmake/compiler_options.cmake)
if (MSVC)
add_executable(example_vs example_vs.cpp)
target_compile_options(example_vs PRIVATE "${compiler_options}")
target_link_libraries(example_vs )
else ()
add_executable(helloworld helloworld.cpp)
target_compile_options(helloworld PRIVATE "${compiler_options}")
target_link_libraries(helloworld PUBLIC ${REQUIRED_LIBRARIES})
add_executable(helloworld helloworld.cpp)
add_warnings_optimizations(helloworld)
target_link_libraries(helloworld PUBLIC Crow::Crow)
# If compression is enabled, the example will be built
if(CROW_ENABLE_COMPRESSION)
add_executable(example_compression example_compression.cpp)
target_compile_options(example_compression PRIVATE "${compiler_options}")
target_link_libraries(example_compression ${REQUIRED_LIBRARIES})
# If OpenSSL is not found, the example won't be built
if (OPENSSL_FOUND)
add_executable(example_ssl ssl/example_ssl.cpp)
target_compile_options(example_ssl PRIVATE "${compiler_options}")
target_link_libraries(example_ssl PUBLIC ${REQUIRED_LIBRARIES} ${OPENSSL_LIBRARIES})
else()
message(STATUS "example_ssl Example deactivated - OpenSSL was not found")
endif()
add_executable(example_websocket websocket/example_ws.cpp)
target_compile_options(example_websocket PRIVATE "${compiler_options}")
target_link_libraries(example_websocket )
target_link_libraries(example_websocket PUBLIC ${REQUIRED_LIBRARIES})
add_custom_command(OUTPUT ws.html
COMMAND ${CMAKE_COMMAND} -E
copy ${PROJECT_SOURCE_DIR}/websocket/templates/ws.html ${CMAKE_CURRENT_BINARY_DIR}/templates/ws.html
DEPENDS ${PROJECT_SOURCE_DIR}/websocket/templates/ws.html
)
add_custom_target(example_ws_copy ALL DEPENDS ws.html)
add_executable(basic_example example.cpp)
target_compile_options(basic_example PRIVATE "${compiler_options}")
target_link_libraries(basic_example PUBLIC ${REQUIRED_LIBRARIES})
if (Tcmalloc_FOUND)
target_link_libraries(basic_example PRIVATE ${Tcmalloc_LIBRARIES})
endif(Tcmalloc_FOUND)
add_executable(example_with_all example_with_all.cpp)
add_dependencies(example_with_all amalgamation)
target_compile_options(example_with_all PRIVATE "${compiler_options}")
target_link_libraries(example_with_all PUBLIC ${REQUIRED_LIBRARIES})
add_custom_command(OUTPUT example_test.py
COMMAND ${CMAKE_COMMAND} -E
copy ${PROJECT_SOURCE_DIR}/example_test.py ${CMAKE_CURRENT_BINARY_DIR}/example_test.py
DEPENDS ${PROJECT_SOURCE_DIR}/example_test.py
)
add_custom_target(example_copy ALL DEPENDS example_test.py)
add_executable(example_chat example_chat.cpp)
target_compile_options(example_chat PRIVATE "${compiler_options}")
target_link_libraries(example_chat PUBLIC ${REQUIRED_LIBRARIES})
add_executable(example_static_file example_static_file.cpp)
target_compile_options(example_static_file PRIVATE "${compiler_options}")
target_link_libraries(example_static_file PUBLIC ${REQUIRED_LIBRARIES})
add_executable(example_catchall example_catchall.cpp)
target_compile_options(example_catchall PRIVATE "${compiler_options}")
target_link_libraries(example_catchall PUBLIC ${REQUIRED_LIBRARIES})
add_executable(example_json_map example_json_map.cpp)
target_compile_options(example_json_map PRIVATE "${compiler_options}")
target_link_libraries(example_json_map PUBLIC ${REQUIRED_LIBRARIES})
add_executable(example_blueprint example_blueprint.cpp)
target_compile_options(example_blueprint PRIVATE "${compiler_options}")
target_link_libraries(example_blueprint PUBLIC ${REQUIRED_LIBRARIES})
add_custom_command(OUTPUT example_chat.html
COMMAND ${CMAKE_COMMAND} -E
copy ${PROJECT_SOURCE_DIR}/example_chat.html ${CMAKE_CURRENT_BINARY_DIR}/example_chat.html
DEPENDS ${PROJECT_SOURCE_DIR}/example_chat.html
)
add_custom_target(example_chat_copy ALL DEPENDS example_chat.html)
add_warnings_optimizations(example_compression)
target_link_libraries(example_compression Crow::Crow)
else()
message(STATUS "example_compression example deactivated")
endif()
# If SSL is enabled, the example will be built
if(CROW_ENABLE_SSL)
add_executable(example_ssl ssl/example_ssl.cpp)
add_warnings_optimizations(example_ssl)
target_link_libraries(example_ssl PUBLIC Crow::Crow)
else()
message(STATUS "example_ssl example deactivated")
endif()
add_executable(example_websocket websocket/example_ws.cpp)
add_warnings_optimizations(example_websocket)
target_link_libraries(example_websocket PUBLIC Crow::Crow)
add_custom_command(OUTPUT ws.html
COMMAND ${CMAKE_COMMAND} -E
copy ${PROJECT_SOURCE_DIR}/websocket/templates/ws.html ${CMAKE_CURRENT_BINARY_DIR}/templates/ws.html
DEPENDS ${PROJECT_SOURCE_DIR}/websocket/templates/ws.html
)
add_custom_target(example_ws_copy ALL DEPENDS ws.html)
add_executable(basic_example example.cpp)
add_warnings_optimizations(basic_example)
target_link_libraries(basic_example PUBLIC Crow::Crow)
add_custom_command(OUTPUT example_test.py
COMMAND ${CMAKE_COMMAND} -E
copy ${PROJECT_SOURCE_DIR}/example_test.py ${CMAKE_CURRENT_BINARY_DIR}/example_test.py
DEPENDS ${PROJECT_SOURCE_DIR}/example_test.py
)
add_custom_target(example_copy ALL DEPENDS example_test.py)
if(CROW_AMALGAMATE)
add_executable(example_with_all example_with_all.cpp)
add_dependencies(example_with_all crow_amalgamated)
add_warnings_optimizations(example_with_all)
target_link_libraries(example_with_all PUBLIC Crow::Crow)
target_include_directories(example_with_all PUBLIC ${CMAKE_BINARY_DIR})
endif()
add_executable(example_chat example_chat.cpp)
add_warnings_optimizations(example_chat)
target_link_libraries(example_chat PUBLIC Crow::Crow)
add_custom_command(OUTPUT example_chat.html
COMMAND ${CMAKE_COMMAND} -E
copy ${PROJECT_SOURCE_DIR}/example_chat.html ${CMAKE_CURRENT_BINARY_DIR}/example_chat.html
DEPENDS ${PROJECT_SOURCE_DIR}/example_chat.html
)
add_custom_target(example_chat_copy ALL DEPENDS example_chat.html)
add_executable(example_static_file example_static_file.cpp)
add_warnings_optimizations(example_static_file)
target_link_libraries(example_static_file PUBLIC Crow::Crow)
add_executable(example_catchall example_catchall.cpp)
add_warnings_optimizations(example_catchall)
target_link_libraries(example_catchall PUBLIC Crow::Crow)
add_executable(example_json_map example_json_map.cpp)
add_warnings_optimizations(example_json_map)
target_link_libraries(example_json_map PUBLIC Crow::Crow)
add_executable(example_blueprint example_blueprint.cpp)
add_warnings_optimizations(example_blueprint)
target_link_libraries(example_blueprint PUBLIC Crow::Crow)
if(MSVC)
add_executable(example_vs example_vs.cpp)
add_warnings_optimizations(example_vs)
target_link_libraries(example_vs Crow::Crow)
endif()

View File

@ -10,7 +10,7 @@ class ExampleLogHandler : public crow::ILogHandler {
}
};
struct ExampleMiddleware
struct ExampleMiddleware
{
std::string message;
@ -75,10 +75,10 @@ int main()
return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
{"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
{"third", std::int64_t(54)}, /* stores a 64-bit int hence a std::int64_t. */
{"fourth", std::uint64_t(54)}, /* stores a 64-bit unsigned int hence a std::uint64_t. */
{"fifth", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"sixth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence json::type::Null . */
@ -161,7 +161,7 @@ int main()
// To get a simple string from the url params
// To see it in action /params?foo='blabla'
os << "Params: " << req.url_params << "\n\n";
os << "Params: " << req.url_params << "\n\n";
os << "The key 'foo' was " << (req.url_params.get("foo") == nullptr ? "not " : "") << "found.\n";
// To get a double from the request
@ -188,7 +188,7 @@ int main()
}
return crow::response{os.str()};
});
});
CROW_ROUTE(app, "/large")
([]{

View File

@ -31,5 +31,5 @@ int main()
bp.register_blueprint(sub_bp);
app.register_blueprint(bp);
app.loglevel(crow::LogLevel::DEBUG).port(18080).run();
app.loglevel(crow::LogLevel::Debug).port(18080).run();
}

View File

@ -1,5 +1,4 @@
#define CROW_MAIN
#define CROW_ENABLE_COMPRESSION
#include "crow.h"
#include "crow/compression.h"

View File

@ -1,4 +1,3 @@
#define CROW_ENABLE_SSL
#define CROW_MAIN
#include "crow.h"

View File

@ -52,10 +52,9 @@ namespace crow
public:
///This crow application
using self_t = Crow;
#ifndef CROW_ENABLE_SSL
///The HTTP server
using server_t = Server<Crow, SocketAdaptor, Middlewares...>;
#else
#ifdef CROW_ENABLE_SSL
///An HTTP server that runs on SSL with an SSLAdaptor
using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>;
#endif
@ -187,14 +186,19 @@ namespace crow
self_t& use_compression(compression::algorithm algorithm)
{
comp_algorithm_ = algorithm;
compression_used_ = true;
return *this;
}
compression::algorithm compression_algorithm()
{
return comp_algorithm_;
}
bool compression_used() const
{
return compression_used_;
}
#endif
///A wrapper for `validate()` in the router
@ -255,22 +259,18 @@ namespace crow
ssl_server_->run();
}
else
{
CROW_LOG_CRITICAL << "SSL context not defined, please define a certificate or SSL context.";
}
#else
server_ = std::move(std::unique_ptr<server_t>(new server_t(this, bindaddr_, port_, server_name_, &middlewares_, concurrency_, nullptr)));
server_->set_tick_function(tick_interval_, tick_function_);
server_->signal_clear();
for (auto snum : signals_)
{
server_->signal_add(snum);
}
notify_server_start();
server_->run();
#endif
{
server_ = std::move(std::unique_ptr<server_t>(new server_t(this, bindaddr_, port_, server_name_, &middlewares_, concurrency_, nullptr)));
server_->set_tick_function(tick_interval_, tick_function_);
server_->signal_clear();
for (auto snum : signals_)
{
server_->signal_add(snum);
}
notify_server_start();
server_->run();
}
}
///Stop the server
@ -284,16 +284,14 @@ namespace crow
}
}
else
#endif
{
CROW_LOG_CRITICAL << "SSL context not defined, please define a certificate or SSL context.";
}
#else
if (server_) {
server_->stop();
}
}
}
#endif
}
void debug_print()
{
CROW_LOG_DEBUG << "Routing:";
@ -404,6 +402,7 @@ namespace crow
#ifdef CROW_ENABLE_COMPRESSION
compression::algorithm comp_algorithm_;
bool compression_used_{false};
#endif
std::chrono::milliseconds tick_interval_;
@ -413,9 +412,9 @@ namespace crow
#ifdef CROW_ENABLE_SSL
std::unique_ptr<ssl_server_t> ssl_server_;
#else
std::unique_ptr<server_t> server_;
#endif
std::unique_ptr<server_t> server_;
std::vector<int> signals_{SIGINT, SIGTERM};
bool server_started_{false};

View File

@ -237,6 +237,7 @@ namespace crow
}
else
{
CROW_LOG_ERROR << "Could not start adaptor: " << ec.message();
check_destroy();
}
});
@ -358,27 +359,29 @@ namespace crow
(*middlewares_, ctx_, req_, res);
}
#ifdef CROW_ENABLE_COMPRESSION
std::string accept_encoding = req_.get_header_value("Accept-Encoding");
if (!accept_encoding.empty() && res.compressed)
{
switch (handler_->compression_algorithm())
if (handler_->compression_used()) {
std::string accept_encoding = req_.get_header_value("Accept-Encoding");
if (!accept_encoding.empty() && res.compressed)
{
case compression::DEFLATE:
if (accept_encoding.find("deflate") != std::string::npos)
{
res.body = compression::compress_string(res.body, compression::algorithm::DEFLATE);
res.set_header("Content-Encoding", "deflate");
}
break;
case compression::GZIP:
if (accept_encoding.find("gzip") != std::string::npos)
{
res.body = compression::compress_string(res.body, compression::algorithm::GZIP);
res.set_header("Content-Encoding", "gzip");
}
break;
default:
break;
switch (handler_->compression_algorithm())
{
case compression::DEFLATE:
if (accept_encoding.find("deflate") != std::string::npos)
{
res.body = compression::compress_string(res.body, compression::algorithm::DEFLATE);
res.set_header("Content-Encoding", "deflate");
}
break;
case compression::GZIP:
if (accept_encoding.find("gzip") != std::string::npos)
{
res.body = compression::compress_string(res.body, compression::algorithm::GZIP);
res.set_header("Content-Encoding", "gzip");
}
break;
default:
break;
}
}
}
#endif

View File

@ -23,7 +23,7 @@ namespace crow
using namespace boost;
using tcp = asio::ip::tcp;
template <typename Handler, typename Adaptor, typename ... Middlewares>
template <typename Handler, typename Adaptor = SocketAdaptor, typename ... Middlewares>
class Server
{
public:

View File

@ -49,13 +49,12 @@ namespace crow
}
virtual void handle(const request&, response&, const routing_params&) = 0;
#ifndef CROW_ENABLE_SSL
virtual void handle_upgrade(const request&, response& res, SocketAdaptor&&)
{
res = response(404);
res.end();
}
#else
#ifdef CROW_ENABLE_SSL
virtual void handle_upgrade(const request&, response& res, SSLAdaptor&&)
{
res = response(404);
@ -400,12 +399,12 @@ namespace crow
res = response(404);
res.end();
}
#ifndef CROW_ENABLE_SSL
void handle_upgrade(const request& req, response&, SocketAdaptor&& adaptor) override
{
new crow::websocket::Connection<SocketAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
}
#else
#ifdef CROW_ENABLE_SSL
void handle_upgrade(const request& req, response&, SSLAdaptor&& adaptor) override
{
new crow::websocket::Connection<SSLAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);

View File

@ -13,7 +13,7 @@ namespace crow
{
using namespace boost;
using tcp = asio::ip::tcp;
#ifndef CROW_ENABLE_SSL
///A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
struct SocketAdaptor
{
@ -83,7 +83,7 @@ namespace crow
tcp::socket socket_;
};
#else
#ifdef CROW_ENABLE_SSL
struct SSLAdaptor
{
using context = boost::asio::ssl::context;

View File

@ -16,11 +16,14 @@ theme:
logo: 'assets/favicon.svg'
icon:
repo: fontawesome/brands/github-square
static_templates:
- privacy_policy.html
custom_dir: docs/overrides
markdown_extensions:
- admonition
- pymdownx.highlight
- pymdownx.tabbed
- pymdownx.superfences
- pymdownx.inlinehilite
- pymdownx.keys
@ -28,7 +31,11 @@ markdown_extensions:
nav:
- Home: index.md
- Getting Started:
- Setup: getting_started/setup.md
- Setup:
- Linux: getting_started/setup/linux.md
- MacOS: getting_started/setup/macos.md
- Windows: getting_started/setup/windows.md
- Legacy: getting_started/setup/legacy.md
- Your First Application: getting_started/your_first_application.md
- Guides:
- Different parts of Crow:
@ -53,6 +60,10 @@ nav:
- API Reference: 'reference/index.html'
extra:
analytics:
provider: matomo
id: 1
link: //thee.dev/matomo/
social:
- icon: fontawesome/brands/github
link: https://github.com/crowcpp/crow

23
scripts/PKGBUILD Normal file
View File

@ -0,0 +1,23 @@
# Maintainer: The-EDev <farook@the-e-dev.com>
pkgname=crow
pkgver=master
pkgrel=1
pkgdesc="A Fast and Easy to use C++ microframework for the web."
arch=(any)
url="https://crowcpp.org"
license=('custom:BSD-3-Clause')
depends=('boost>=1.64.0')
optdepends=('openssl: HTTPS support' 'zlib: HTTP compression support' 'cmake: Choose this if you plan on using CMake for your Crow project')
conflicts=("$pkgname-git")
changelog='changelog.md'
source=("https://github.com/CrowCpp/$pkgname/releases/download/v$pkgver/crow-v$pkgver.tar.gz")
md5sums=('SKIP')
sha256sums=('SKIP')
package() {
echo "installing to \"$pkgdir/usr/local/\""
mkdir -p "$pkgdir/usr/local/include"
mkdir -p "$pkgdir/usr/local/lib"
cp -r "include" "$pkgdir/usr/local"
cp -r "lib" "$pkgdir/usr/local"
}

View File

@ -5,17 +5,86 @@ import shutil
if len(sys.argv) != 2:
print("Usage: {} VERSION".format(sys.argv[0]))
print("Version should be similar to \"1.2+3\" (+3 is optional)")
sys.exit(1)
# Different color outputs (to distinguish errors from standard output)
def prGreen(skk): print("\033[36m-->\033[92m {}\033[00m" .format(skk))
def prRed(skk): print("\033[36m-->\033[91m {}\033[00m" .format(skk))
def prYellow(skk): print("\033[36m-->\033[93m {}\033[00m" .format(skk))
# Defining the different ways the version is represented
version = str(sys.argv[1])
versionNoPatch = version[0:3]
versionvcpkg = version.replace("+", ".")
# Defining the paths used
sourcePath = os.path.join(os.path.dirname(__file__), "..", "include", "crow")
releasePath = os.path.join(os.path.dirname(__file__), "..", "build_release")
releaseCodePath = os.path.join(os.path.dirname(__file__), "..", "build_release", "_CPack_Packages", "Linux")
releaseAURPath = os.path.join(os.path.dirname(__file__), "..", "build_release", "_CPack_Packages", "Linux", "AUR")
# Delete any existing release
if os.path.exists(releasePath):
prYellow("Detected existing release directory, overriding...")
shutil.rmtree(releasePath)
# Create the dir
prGreen("Creating new release directory...")
os.mkdir(releasePath)
os.chdir(sourcePath)
# Changing "master" version to <version_number>
prGreen("Applying new version to Crow server name...")
os.system("sed -i 's/char VERSION\\[\\] = \".*\";/char VERSION\\[\\] = \"{}\";/g' version.h".format(versionNoPatch))
prGreen("Applying new version to vcpkg...")
os.system("sed -i 's/\"version-string\": \".*\",/\"version\": \"{}\",/g' ../../vcpkg.json".format(versionvcpkg))
prGreen("Applying new version to PKGBUILD...")
os.system("sed -i 's/^pkgver=.*/pkgver={}/' ../../scripts/PKGBUILD".format(version))
os.system("sed -i 's/^pkgrel=.*/pkgrel=1/' ../../scripts/PKGBUILD".format(version))
# Running CMake to compile crow_all and the deb package
os.chdir(releasePath)
os.system("cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DCPACK_PACKAGE_FILE_NAME=\"crow-{}\" .. && make -j5".format(version))
os.system("sed -i 's/char VERSION\\[\\] = \"master\";/char VERSION\\[\\] = \"{}\";/g' crow_all.h".format(version))
prGreen("Compiling Release...")
os.system("cmake -DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF -DCROW_AMALGAMATE=ON -DCPACK_PACKAGE_VERSION={0} -DCPACK_PACKAGE_FILE_NAME=\"crow-{0}\" .. && make -j4".format(version))
prGreen("Compiling DEB package...")
os.system("cpack -R {}".format(version))
# Create standalone package from DEB data
prGreen("Compiling Standalone tar package...")
os.chdir(releaseCodePath)
os.system("tar -czf crow-v{0}.tar.gz -C DEB/crow-{0}/usr ./".format(version))
os.system("cp crow-v{0}.tar.gz {1}/crow-v{0}.tar.gz".format(version, releasePath))
# Getting the AUR package data
prGreen("Compiling AUR package...")
os.system("git clone ssh://aur@aur.archlinux.org/crow.git AUR")
# Updating the PKGBUILD in build dir, and adding the tarball for checksum calculations
prGreen("Updating AUR package...")
os.system("cp crow-v{0}.tar.gz AUR/crow-v{0}.tar.gz".format(version))
os.system("cp ../../../scripts/PKGBUILD AUR/PKGBUILD")
# Updating Checksums
os.chdir(releaseAURPath)
prGreen("Updating AUR package Checksums...")
md5 = os.popen("md5sum crow-v{}.tar.gz | cut -c -32".format(version)).read()[:-1]
sha256 = os.popen("sha256sum crow-v{}.tar.gz | cut -c -64".format(version)).read()[:-1]
os.system("sed -i \"s/^md5sums=(\'.*\')/md5sums=(\'{}\')/\" PKGBUILD".format(md5))
os.system("sed -i \"s/^sha256sums=(\'.*\')/sha256sums=(\'{}\')/\" PKGBUILD".format(sha256))
# Updating SRCINFO file
prGreen("Updating AUR SRCINFO...")
if(os.system("which makepkg &>/dev/null") == 0):
os.system("makepkg --printsrcinfo > .SRCINFO")
else:
prRed("makepkg not found, AUR SRCINFO cannot be updated.")
doneStr = "Release for Crow-{0} was made successfully. To publish the release please do the following:\n" \
"1. Commit the code changes to a separate branch (Recommended name is \"{1}\").\n" \
"2. Create a tag (Github release) from the branch.\n" \
"3. Upload the \"crow-{0}.deb\", \"crow-v{0}.tar.gz\" and \"crow_all.h\" files to the release.\n" \
"4. Update the changelog in \"{2}\".\n" \
"5. push the changes to AUR (using git and only if AUR update ran without errors)." \
"6. Open issues to update the pakcages in VCPKG and ConanCenter".format(version, versionNoPatch, releaseAURPath)
prYellow(doneStr)

View File

@ -1,19 +1,23 @@
cmake_minimum_required(VERSION 3.15)
project(crow_test)
include(${CMAKE_SOURCE_DIR}/cmake/compiler_options.cmake)
set(TEST_SRCS
unittest.cpp
)
add_executable(unittest ${TEST_SRCS})
target_link_libraries(unittest ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} z)
# set target compile options as defined in the cmake/compiler_options.cmake Module
target_compile_options(unittest PRIVATE ${compiler_options})
target_link_libraries(unittest Crow::Crow)
add_warnings_optimizations(unittest)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set_target_properties(unittest PROPERTIES COMPILE_FLAGS "--coverage -fprofile-arcs -ftest-coverage")
target_link_libraries(unittest gcov)
endif()
add_subdirectory(template)
if (CROW_ENABLE_SSL)
add_subdirectory(ssl)
endif()
add_subdirectory(img)

18
tests/ssl/CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.15)
project (crow_ssl_test)
include(${CMAKE_SOURCE_DIR}/cmake/compiler_options.cmake)
set(TEST_SRCS
ssltest.cpp
)
add_executable(ssltest ${TEST_SRCS})
target_link_libraries(ssltest Crow::Crow)
add_warnings_optimizations(ssltest)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set_target_properties(ssltest PROPERTIES COMPILE_FLAGS "--coverage -fprofile-arcs -ftest-coverage")
target_link_libraries(ssltest gcov)
endif()

88
tests/ssl/ssltest.cpp Normal file
View File

@ -0,0 +1,88 @@
#define CATCH_CONFIG_MAIN
#define CROW_LOG_LEVEL 0
#define CROW_MAIN
#include <thread>
#include "../catch.hpp"
#include "crow.h"
#define LOCALHOST_ADDRESS "127.0.0.1"
using namespace boost;
//TODO SSL test with .pem file
TEST_CASE("SSL")
{
static char buf[2048];
//static char buf2[2048];
std::system("openssl req -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out test.crt -keyout test.key -subj '/CN=127.0.0.1'");
//std::system("cat test.key > test.pem");
//std::system("cat test.crt >> test.pem");
crow::SimpleApp app;
//crow::SimpleApp app2;
CROW_ROUTE(app, "/")
([]() {
return "Hello world, I'm keycrt.";
});
/*
CROW_ROUTE(app2, "/")
([]() {
return "Hello world, I'm pem.";
});
*/
auto _ = async(std::launch::async, [&] { app.bindaddr(LOCALHOST_ADDRESS).port(45460).ssl_file("test.crt", "test.key").run(); });
//auto _1 = async(std::launch::async,[&] { app2.bindaddr(LOCALHOST_ADDRESS).port(45461).ssl_file("test.pem").run(); });
app.wait_for_server_start();
//app2.wait_for_server_start();
std::string sendmsg = "GET /\r\n\r\n";
asio::ssl::context ctx(asio::ssl::context::sslv23);
asio::io_service is;
{
asio::ssl::stream<asio::ip::tcp::socket> c(is, ctx);
c.lowest_layer().connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45460));
c.handshake(asio::ssl::stream_base::client);
c.write_some(asio::buffer(sendmsg));
size_t x = 0;
size_t y = 0;
while(x < 121){
y = c.read_some(asio::buffer(buf, 2048));
x+=y;
buf[y]='\0';
}
CHECK(std::string("Hello world, I'm keycrt.") == std::string(buf));
}
/*
asio::io_service is2;
{
std::cout << "started second one" << std::endl;
asio::ssl::stream<asio::ip::tcp::socket> c(is2, ctx);
c.lowest_layer().connect(asio::ip::tcp::endpoint(
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45461));
c.handshake(asio::ssl::stream_base::client);
c.write_some(asio::buffer(sendmsg));
size_t sz = c.read_some(asio::buffer(buf2, 2048));
CHECK("Hello world, I'm pem." == std::string(buf2).substr((sz - 21)));
}
*/
app.stop();
//app2.stop();
std::system("rm test.crt test.key" /*test.pem*/);
}

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.15)
project (template_test)
project(template_test)
set(PROJECT_INCLUDE_DIR
set(PROJECT_INCLUDE_DIR
${PROJECT_SOURCE_DIR}/include
)
@ -10,9 +10,10 @@ set(TEST_SRCS
)
add_executable(mustachetest ${TEST_SRCS})
target_compile_options(mustachetest PRIVATE "${compiler_options}")
target_link_libraries(mustachetest Crow::Crow)
add_warnings_optimizations(mustachetest)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set_target_properties(mustachetest PROPERTIES COMPILE_FLAGS "--coverage -fprofile-arcs -ftest-coverage")
target_link_libraries(mustachetest gcov)
endif()

View File

@ -1,5 +1,4 @@
#define CATCH_CONFIG_MAIN
#define CROW_ENABLE_COMPRESSION
#define CROW_ENABLE_DEBUG
#define CROW_LOG_LEVEL 0
#define CROW_MAIN
@ -1900,6 +1899,7 @@ TEST_CASE("websocket")
app.stop();
}
#ifdef CROW_ENABLE_COMPRESSION
TEST_CASE("zlib_compression")
{
static char buf_deflate[2048];
@ -2094,6 +2094,7 @@ TEST_CASE("zlib_compression")
app_deflate.stop();
app_gzip.stop();
}
#endif
TEST_CASE("catchall")
{