mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Merge branch 'master'
Conflicts: CMakeLists.txt examples/CMakeLists.txt include/crow/http_connection.h tests/CMakeLists.txt
This commit is contained in:
commit
78ee97124b
3
.gitignore
vendored
3
.gitignore
vendored
@ -47,3 +47,6 @@ html/
|
||||
*.cxxflags
|
||||
*.files
|
||||
*.includes
|
||||
|
||||
#VS-Code
|
||||
.vscode
|
104
CMakeLists.txt
104
CMakeLists.txt
@ -1,71 +1,77 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project (crow_all)
|
||||
#####################################
|
||||
# Define Project-Wide Settings
|
||||
#####################################
|
||||
cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR)
|
||||
|
||||
# Define the Project Name and Description
|
||||
project (crow_all LANGUAGES CXX)
|
||||
|
||||
# Define the module path
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||
|
||||
find_package(Tcmalloc)
|
||||
find_package(Threads)
|
||||
find_package(OpenSSL)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
|
||||
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)
|
||||
# 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")
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
set(Boost_USE_STATIC_LIBS "On")
|
||||
find_package( Boost 1.52 COMPONENTS system thread regex REQUIRED )
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14 -pedantic -Wextra")
|
||||
find_package( Boost 1.52 COMPONENTS system thread REQUIRED )
|
||||
#####################################
|
||||
# Define Options
|
||||
#####################################
|
||||
option(BUILD_EXAMPLES "Builds the examples in the project" ON)
|
||||
option(BUILD_TESTING "Builds the tests in the project" ON)
|
||||
|
||||
#####################################
|
||||
# Define CMake Module Imports
|
||||
#####################################
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/dependencies.cmake)
|
||||
include(${CMAKE_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_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
include_directories("${PROJECT_INCLUDE_DIR}")
|
||||
include_directories("${CMAKE_SOURCE_DIR}")
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}") # To include crow_all.h
|
||||
endif()
|
||||
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
|
||||
set(PROJECT_INCLUDE_DIR
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
#####################################
|
||||
# Define Targets
|
||||
#####################################
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
|
||||
COMMAND python ${CMAKE_SOURCE_DIR}/scripts/merge_all.py
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/include/*.h ${CMAKE_SOURCE_DIR}/include/crow/*.h ${CMAKE_SOURCE_DIR}/include/crow/middlewares/*.h
|
||||
)
|
||||
|
||||
include_directories("${PROJECT_INCLUDE_DIR}")
|
||||
include_directories("${PROJECT_SOURCE_DIR}")
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}") # To include crow_all.h
|
||||
# Amalgamation
|
||||
add_custom_target(amalgamation ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h)
|
||||
|
||||
add_subdirectory(examples)
|
||||
# Examples
|
||||
if(BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
else()
|
||||
# Tests
|
||||
if (NOT MSVC AND BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME crow_test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tests/unittest)
|
||||
add_test(NAME template_test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tests/template/test.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/tests/template)
|
||||
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
|
||||
COMMAND python ${PROJECT_SOURCE_DIR}/scripts/merge_all.py
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/crow_all.h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${PROJECT_SOURCE_DIR}/include/*.h ${PROJECT_SOURCE_DIR}/include/crow/*.h ${PROJECT_SOURCE_DIR}/include/crow/middlewares/*.h
|
||||
)
|
||||
|
||||
add_custom_target(amalgamation ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h)
|
||||
endif()
|
||||
|
||||
#####################################
|
||||
# Install Files
|
||||
#####################################
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h DESTINATION include)
|
||||
|
22
cmake/compiler_options.cmake
Normal file
22
cmake/compiler_options.cmake
Normal file
@ -0,0 +1,22 @@
|
||||
# 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()
|
35
cmake/dependencies.cmake
Normal file
35
cmake/dependencies.cmake
Normal file
@ -0,0 +1,35 @@
|
||||
# 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()
|
@ -1 +1,61 @@
|
||||
***HELP NEEDED***
|
||||
You can set Crow up behind any HTTP proxy of your liking, but we will be focusing specifically on 2 of the most popular web server software solutions, Apache2 and Nginx.<br><br>
|
||||
|
||||
A reverse proxy allows you to use Crow without exposing it directly to the internet. It also allows you to, for example, have crow run on a certain specific domain name, subdomain, or even a path, such as `domain.abc/crow`.<br><br>
|
||||
|
||||
We advise that you set crow up behind some form of reverse proxy if you plan on running a production Crow server that isn't local.<br>
|
||||
|
||||
!!! warning "SSL"
|
||||
|
||||
When using a proxy, make sure that you **do not** compile Crow with SSL enabled. SSL should be handled by the proxy.
|
||||
|
||||
##Apache2
|
||||
|
||||
Assuming you have both Apache2 and the modules [proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html), [proxy_http](https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html), [proxy_html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_html.html) (if you plan on serving html pages), and [proxy_wstunnel](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html) (if you plan on using websockets). You will need to enable those modules, which you can do using the following commands:
|
||||
|
||||
```sh
|
||||
a2enmod proxy
|
||||
a2enmod proxy_http
|
||||
a2enmod proxy_html
|
||||
a2enmod proxy_wstunnel
|
||||
```
|
||||
|
||||
Next up you'll need to change your configuration (default is `/etc/apache2/sites-enabled/000-default.conf`) and add the following lines (replace `localhost` and `40080` with the address and port you defined for your Crow App):
|
||||
```
|
||||
ProxyPass / http://localhost:40080
|
||||
ProxyPassReverse / http://localhost:40080
|
||||
```
|
||||
If you want crow to run in a subdirectory (such as `domain.abc/crow`) you can use the `location` tag:
|
||||
```
|
||||
<Location "/crow">
|
||||
|
||||
ProxyPass http://localhost:40080
|
||||
|
||||
ProxyPassReverse http://localhost:40080
|
||||
|
||||
</Location>
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
If you're using an Arch Linux based OS. You will have to access `/etc/httpd/conf/httpd.conf` to enable modules and change configuration
|
||||
|
||||
##Nginx
|
||||
|
||||
Setting Nginx up is slightly simpler than Apache, all you need is the Nginx package itself. Once you've installed it, go to the configuration file (usually a `.conf` file located in `/etc/nginx`) and add the following lines to your server section (replace `localhost` and `40080` with the address and port you defined for your Crow App):
|
||||
|
||||
```
|
||||
location / {
|
||||
proxy_pass http://localhost:40080/;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
```
|
||||
Remember to remove or comment out any existing `location /` section.<br><br>
|
||||
|
||||
Alternatively, if you want to use a subdirectory, you can simply change the location parameter as such:
|
||||
|
||||
```
|
||||
location /crow/ {
|
||||
proxy_pass http://localhost:40080/;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
```
|
||||
|
@ -1,3 +1,36 @@
|
||||
https://www.howtogeek.com/687970/how-to-run-a-linux-program-at-startup-with-systemd/
|
||||
Using Systemd allows you to run any executable or script when the system starts. This can be useful when you don't want to re-run your Crow application every single time you restart your server.<br><br>
|
||||
|
||||
***HELP NEEDED***
|
||||
##Writing the Service Unit File
|
||||
In order to have Systemd recognize your application, you need to create a `.service` file that explains how Systemd should handle your program.<br><br>
|
||||
|
||||
To create a service file, you need to go to `/etc/systemd/system` and create an empty text file with the extension `.service`, the file name can be anything.<br><br>
|
||||
|
||||
Once the file is created, open it using your favorite text editor and add the following:
|
||||
|
||||
```sh
|
||||
[Unit]
|
||||
Description=My revolutionary Crow application
|
||||
|
||||
Wants=network.target
|
||||
After=syslog.target network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/absolute/path/to/your/executable
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
You will then need to give the correct permission, this can be done by using the following command (a `sudo` maybe required):
|
||||
|
||||
```sh
|
||||
chmod 640 /etc/systemd/system/crowthing.service
|
||||
```
|
||||
|
||||
And that's it! You can now use your `systemctl` controls to `enable`, `start`, `stop`, or `disable` your Crow application.<br><br>
|
||||
|
||||
If you're not familiar with Systemd, `systemctl enable crowthing.service` will allow your Crow application to run at startup, `start` will start it, and the rest is simple.
|
||||
|
77
docs/guides/testing.md
Normal file
77
docs/guides/testing.md
Normal file
@ -0,0 +1,77 @@
|
||||
Unit tests can be written in 2 ways for a Crow application.<br><br>
|
||||
|
||||
##The handler method
|
||||
Crow Allows users to handle requests that may not come from the network. This is done by calling the `handle(req, res)` method and providing a request and response objects. Which causes crow to identify and run the appropriate handler, returning the resulting response.
|
||||
|
||||
```cpp linenums="1"
|
||||
CROW_ROUTE(app, "/place")
|
||||
([] { return "hi"; });
|
||||
|
||||
app.validate(); //Used to make sure all the route handlers are in order.
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/place";
|
||||
|
||||
app.handle(req, res); //res will contain a code of 200, and a response body of "hi"
|
||||
}
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
This method is the simpler of the two and is usually all you really need to test your routes.
|
||||
|
||||
|
||||
!!! warning
|
||||
|
||||
This method does not send any data, nor does it run any post handle code, so things like static file serving (as far as sending the actual data) or compression cannot be tested using this method.
|
||||
|
||||
|
||||
##The client method
|
||||
This method involves creating a simple [ASIO](https://think-async.com/Asio/) client that sends the request and receives the response. It is considerably more complex than the earlier method, but it is both more realistic and includes post handle operations.
|
||||
|
||||
```cpp linenums="1"
|
||||
static char buf[2048];
|
||||
SimpleApp app;
|
||||
CROW_ROUTE(app, "/")([] { return "A"; });
|
||||
|
||||
auto _ = async(launch::async,[&] { app1.bindaddr("127.0.0.1").port(45451).run(); });
|
||||
app.wait_for_server_start();
|
||||
|
||||
std::string sendmsg = "GET /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n";
|
||||
asio::io_service is;
|
||||
{
|
||||
asio::ip::tcp::socket c(is);
|
||||
c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
|
||||
|
||||
c.send(asio::buffer(sendmsg));
|
||||
|
||||
size_t recved = c.receive(asio::buffer(buf, 2048));
|
||||
CHECK('A' == buf[recved - 1]); //This is specific to catch2 testing library, but it should give a general idea of how to read the response.
|
||||
}
|
||||
|
||||
app.stop(); //THIS MUST RUN
|
||||
}
|
||||
|
||||
```
|
||||
The first part is straightforward, create an app and add a route.<br>
|
||||
The second part is launching the app asynchronously and waiting until it starts.<br>
|
||||
The third is formulating our HTTP request string, the format is:
|
||||
```
|
||||
METHOD /
|
||||
Content-Length:123
|
||||
header1:value1
|
||||
header2:value2
|
||||
|
||||
BODY
|
||||
|
||||
```
|
||||
Next an `io_service` is created, then a TCP socket is created with the `io_service` and is connected to the application.<br>
|
||||
Then send the HTTP request string through the socket inside a buffer, and read the result into the buffer in `line 1`.<br>
|
||||
Finally check the result against the expected one.
|
||||
|
||||
!!! warning
|
||||
|
||||
Be absolutely sure that the line `app.stop()` runs, whether the test fails or succeedes. Not running it WILL CAUSE OTHER TESTS TO FAIL AND THE TEST TO HANG UNTIL THE PROCESS IS TERMINATED.
|
@ -1,76 +1,75 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project (crow_examples)
|
||||
|
||||
# Define Required libraries
|
||||
list(APPEND REQUIRED_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_executable(example_vs example_vs.cpp)
|
||||
target_link_libraries(example_vs ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_vs ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(example_vs ${ZLIB_LIBRARIES})
|
||||
target_compile_options(example_vs PRIVATE "${compiler_options}")
|
||||
target_link_libraries(example_vs )
|
||||
else ()
|
||||
add_executable(helloworld helloworld.cpp)
|
||||
target_link_libraries(helloworld ${Boost_LIBRARIES})
|
||||
target_link_libraries(helloworld ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(helloworld ${ZLIB_LIBRARIES})
|
||||
target_compile_options(helloworld PRIVATE "${compiler_options}")
|
||||
target_link_libraries(helloworld PUBLIC ${REQUIRED_LIBRARIES})
|
||||
|
||||
add_executable(example_static_file example_static_file.cpp)
|
||||
target_link_libraries(example_static_file ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_static_file ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(example_static_file ${ZLIB_LIBRARIES})
|
||||
add_executable(example_compression example_compression.cpp)
|
||||
target_compile_options(example_compression PRIVATE "${compiler_options}")
|
||||
target_link_libraries(example_compression ${REQUIRED_LIBRARIES})
|
||||
|
||||
add_executable(example_compression example_compression.cpp)
|
||||
target_link_libraries(example_compression ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_compression ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(example_compression ${ZLIB_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()
|
||||
|
||||
if (OPENSSL_FOUND)
|
||||
add_executable(example_ssl ssl/example_ssl.cpp)
|
||||
target_link_libraries(example_ssl ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_ssl ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES})
|
||||
target_link_libraries(example_ssl ${ZLIB_LIBRARIES})
|
||||
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(example_websocket websocket/example_ws.cpp)
|
||||
target_link_libraries(example_websocket ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_websocket ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES})
|
||||
target_link_libraries(example_websocket ${ZLIB_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})
|
||||
|
||||
add_executable(basic_example example.cpp)
|
||||
target_link_libraries(basic_example ${Boost_LIBRARIES})
|
||||
target_link_libraries(basic_example ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(basic_example ${ZLIB_LIBRARIES})
|
||||
if (Tcmalloc_FOUND)
|
||||
target_link_libraries(basic_example ${Tcmalloc_LIBRARIES})
|
||||
endif(Tcmalloc_FOUND)
|
||||
|
||||
if (Tcmalloc_FOUND)
|
||||
target_link_libraries(basic_example ${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_executable(example_with_all example_with_all.cpp)
|
||||
add_dependencies(example_with_all amalgamation)
|
||||
target_link_libraries(example_with_all ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_with_all ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(example_with_all ${ZLIB_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_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_chat example_chat.cpp)
|
||||
target_link_libraries(example_chat ${Boost_LIBRARIES})
|
||||
target_link_libraries(example_chat ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(example_chat ${ZLIB_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_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)
|
||||
|
||||
endif()
|
||||
|
@ -357,7 +357,6 @@ namespace crow
|
||||
(*middlewares_, ctx_, req_, res);
|
||||
}
|
||||
|
||||
|
||||
std::string accept_encoding = req_.get_header_value("Accept-Encoding");
|
||||
if (!accept_encoding.empty() && res.compressed)
|
||||
{
|
||||
@ -380,6 +379,17 @@ namespace crow
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//if there is a redirection with a partial URL, treat the URL as a route.
|
||||
std::string location = res.get_header_value("Location");
|
||||
if (!location.empty() && location.find("://", 0) == std::string::npos)
|
||||
{
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
location.insert(0, "https://" + req_.get_header_value("Host"));
|
||||
#else
|
||||
location.insert(0, "http://" + req_.get_header_value("Host"));
|
||||
#endif
|
||||
res.set_header("location", location);
|
||||
}
|
||||
|
||||
prepare_buffers();
|
||||
@ -415,8 +425,11 @@ namespace crow
|
||||
|
||||
{300, "HTTP/1.1 300 Multiple Choices\r\n"},
|
||||
{301, "HTTP/1.1 301 Moved Permanently\r\n"},
|
||||
{302, "HTTP/1.1 302 Moved Temporarily\r\n"},
|
||||
{302, "HTTP/1.1 302 Found\r\n"},
|
||||
{303, "HTTP/1.1 303 See Other\r\n"},
|
||||
{304, "HTTP/1.1 304 Not Modified\r\n"},
|
||||
{307, "HTTP/1.1 307 Temporary Redirect\r\n"},
|
||||
{308, "HTTP/1.1 308 Permanent Redirect\r\n"},
|
||||
|
||||
{400, "HTTP/1.1 400 Bad Request\r\n"},
|
||||
{401, "HTTP/1.1 401 Unauthorized\r\n"},
|
||||
|
@ -26,8 +26,8 @@ namespace crow
|
||||
struct request
|
||||
{
|
||||
HTTPMethod method;
|
||||
std::string raw_url; ///< The full URL containing the host.
|
||||
std::string url; ///< The Endpoint.
|
||||
std::string raw_url; ///< The full URL containing the `?` and URL parameters.
|
||||
std::string url; ///< The endpoint without any parameters.
|
||||
query_string url_params; ///< The parameters associated with the request. (everything after the `?`)
|
||||
ci_map headers;
|
||||
std::string body;
|
||||
|
@ -100,7 +100,37 @@ namespace crow
|
||||
completed_ = false;
|
||||
}
|
||||
|
||||
/// Return a "Temporary Redirect" response.
|
||||
///
|
||||
/// Location can either be a route or a full URL.
|
||||
void redirect(const std::string& location)
|
||||
{
|
||||
code = 307;
|
||||
set_header("Location", location);
|
||||
}
|
||||
|
||||
/// Return a "Permanent Redirect" response.
|
||||
///
|
||||
/// Location can either be a route or a full URL.
|
||||
void redirect_perm(const std::string& location)
|
||||
{
|
||||
code = 308;
|
||||
set_header("Location", location);
|
||||
}
|
||||
|
||||
/// Return a "Found (Moved Temporarily)" response.
|
||||
///
|
||||
/// Location can either be a route or a full URL.
|
||||
void moved(const std::string& location)
|
||||
{
|
||||
code = 302;
|
||||
set_header("Location", location);
|
||||
}
|
||||
|
||||
/// Return a "Moved Permanently" response.
|
||||
///
|
||||
/// Location can either be a route or a full URL.
|
||||
void moved_perm(const std::string& location)
|
||||
{
|
||||
code = 301;
|
||||
set_header("Location", location);
|
||||
|
@ -18,6 +18,7 @@ theme:
|
||||
repo: fontawesome/brands/github-square
|
||||
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
- pymdownx.highlight
|
||||
- pymdownx.superfences
|
||||
- pymdownx.inlinehilite
|
||||
@ -40,6 +41,7 @@ nav:
|
||||
- SSL: guides/ssl.md
|
||||
- Static Files: guides/static.md
|
||||
- Websockets: guides/websockets.md
|
||||
- Writing Tests: guides/testing.md
|
||||
- Server setup:
|
||||
- Proxies: guides/proxies.md
|
||||
- Systemd run on startup: guides/syste.md
|
||||
|
@ -6,10 +6,9 @@ set(TEST_SRCS
|
||||
)
|
||||
|
||||
add_executable(unittest ${TEST_SRCS})
|
||||
target_link_libraries(unittest ${Boost_LIBRARIES})
|
||||
target_link_libraries(unittest ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(unittest ${ZLIB_LIBRARIES})
|
||||
set_target_properties(unittest PROPERTIES COMPILE_FLAGS "-Wall -Werror -std=c++14")
|
||||
target_link_libraries(unittest ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES})
|
||||
# set target compile options as defined in the cmake/compiler_options.cmake Module
|
||||
target_compile_options(unittest PRIVATE ${compiler_options})
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set_target_properties(unittest PROPERTIES COMPILE_FLAGS "--coverage -fprofile-arcs -ftest-coverage")
|
||||
|
@ -10,8 +10,7 @@ set(TEST_SRCS
|
||||
)
|
||||
|
||||
add_executable(mustachetest ${TEST_SRCS})
|
||||
set_target_properties(mustachetest PROPERTIES COMPILE_FLAGS "-Wall -Werror -std=c++14")
|
||||
|
||||
target_compile_options(mustachetest PRIVATE "${compiler_options}")
|
||||
file(COPY DIRECTORY . DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILES_MATCHING PATTERN "*.json")
|
||||
|
||||
add_custom_command(OUTPUT test.py
|
||||
|
Loading…
Reference in New Issue
Block a user