Changed documentation. a lot.

Added mkdocs documentation.
Altered doxygen generation (doxyfile and shell script) to work with mkdocs.
Removed the whole html folder thing for docs, now the files reside in the root gh-pages branch.
New readme.
This commit is contained in:
The-EDev 2020-11-28 17:28:47 +03:00
parent 896ec0621b
commit 23648445f3
27 changed files with 794 additions and 87 deletions

0
.gitmodules vendored
View File

View File

@ -30,14 +30,12 @@ addons:
packages:
- libboost-all-dev
- doxygen
- doxygen-doc
- doxygen-latex
- doxygen-gui
- mkdocs
- graphviz
before_install:
- if [ "$TRAVIS_COMPILER" == "gcc" -a "$TRAVIS_CPU_ARCH" == "amd64" ]; then export PUSH_COVERAGE=ON; fi
- if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" == "false" -a "$PUSH_COVERAGE" == "ON" ]; then export TRAVIS_BUILD_DOCS=ON; fi
- if [ "$TRAVIS_BRANCH" == "master" -a "$TRAVIS_PULL_REQUEST" == "false" -a "$PUSH_COVERAGE" == "ON" ]; then export TRAVIS_BUILD_DOCS=ON; pip install mkdocs-material; fi
install:
- if [ "$PUSH_COVERAGE" == "ON" ]; then pip install --user cpp-coveralls; fi

View File

@ -263,12 +263,6 @@ TAB_SIZE = 2
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
@ -990,7 +984,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = readme.md
USE_MDFILE_AS_MAINPAGE = README.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
@ -1119,7 +1113,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = html
HTML_OUTPUT = site/reference
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).

113
README.md
View File

@ -1,12 +1,39 @@
![Crow logo](https://pixeldrain.com/api/file/DMc7xYye)
<p align="center"><img src="https://pixeldrain.com/api/file/DMc7xYye" width=600></p>
Crow is a C++ microframework for web. (inspired by Python Flask)
<h4 align="center">A Fast and Easy to use microframework for the web.</h4>
<p align="center">
<a href="https://travis-ci.com/mrozigor/crow"><img src="https://travis-ci.com/mrozigor/crow.svg?branch=master" alt="Build Status"></a>
<a href="https://coveralls.io/github/mrozigor/crow?branch=master"><img src="https://coveralls.io/repos/github/mrozigor/crow/badge.svg?branch=master" alt="Coverage Status"></a>
<a href="https://mrozigor.github.io/crow"><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>
</p>
[![Build Status](https://travis-ci.com/mrozigor/crow.svg?branch=master)](https://travis-ci.com/mrozigor/crow)
[![Coverage Status](https://coveralls.io/repos/github/mrozigor/crow/badge.svg?branch=master)](https://coveralls.io/github/mrozigor/crow?branch=master)
[![Documentation](https://img.shields.io/badge/-Documentation-informational)](https://mrozigor.github.io/crow)
[![Gitter](https://badges.gitter.im/crowfork/community.svg)](https://gitter.im/crowfork/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
## Description
Crow is a C++ microframework for running web services. It uses routing similar to Python's Flask which makes it easy to use. It is also extremely fast, beating multiple existing C++ frameworks as well as non C++ frameworks.
### Features
- Easy Routing (similar to flask).
- Type-safe Handlers.
- Blazingly fast (see [this benchmark](https://github.com/ipkn/crow-benchmark) and [this benchmark](https://github.com/guteksan/REST-CPP-benchmark)).
- Built in JSON support.
- [Mustache](http://mustache.github.io/) based templating library (`crow::mustache`).
- Header only library (single header file available).
- Middleware support for extensions.
- HTTP/1.1 and Websocket support.
- Multi-part request and response support.
- Uses modern C++ (11/14)
### Still in development
- [HTTP/2 support](https://github.com/mrozigor/crow/issues/8)
## Documentation
Available [here](https://mrozigor.github.io/crow).
## Examples
#### Hello World
```c++
#include "crow.h"
@ -22,32 +49,8 @@ int main()
}
```
## Features
- Easy routing
- Similiar to Flask
- Type-safe Handlers (see Example)
- Very Fast
- ![Benchmark Result in one chart](https://docs.google.com/spreadsheets/d/1KidO9XpuwCRZ2p_JRDJj2aep61H8Sh_KDOhApizv4LE/pubchart?oid=2041467789&format=image)
- More data on [crow-benchmark](https://github.com/ipkn/crow-benchmark)
- Fast built-in JSON parser (crow::json)
- You can also use [json11](https://github.com/dropbox/json11) or [rapidjson](https://github.com/miloyip/rapidjson) for better speed or readability
- [Mustache](http://mustache.github.io/) based templating library (crow::mustache)
- Header only
- All-in-one header file available
- Middleware support
- Websocket support
## Still in development
- [Informational webpage](https://mrozigor.github.io/crow) (what is crow, guides, examples, etc..)
- [HTTP/2 support](https://github.com/mrozigor/crow/issues/8)
- ~~Built-in ORM~~
- Check [sqlpp11](https://github.com/rbock/sqlpp11) if you want one.
## Examples
#### JSON Response
```c++
```cpp
CROW_ROUTE(app, "/json")
([]{
crow::json::wvalue x;
@ -57,7 +60,7 @@ CROW_ROUTE(app, "/json")
```
#### Arguments
```c++
```cpp
CROW_ROUTE(app,"/hello/<int>")
([](int count){
if (count > 100)
@ -68,7 +71,7 @@ CROW_ROUTE(app,"/hello/<int>")
});
```
Handler arguments type check at compile time
```c++
```cpp
// Compile error with message "Handler type is mismatched with URL paramters"
CROW_ROUTE(app,"/another/<int>")
([](int a, int b){
@ -77,7 +80,7 @@ CROW_ROUTE(app,"/another/<int>")
```
#### Handling JSON Requests
```c++
```cpp
CROW_ROUTE(app, "/add_json")
.methods("POST"_method)
([](const crow::request& req){
@ -91,47 +94,17 @@ CROW_ROUTE(app, "/add_json")
});
```
## How to Build
More examples can be found [here](https://github.com/mrozigor/crow/tree/master/examples).
If you just want to use crow, generate `crow_all.h` (use script `scripts/merge_all.py`) and include it.
## Setting Up / Building
Available [here](https://mrozigor.github.io/crow/getting_started/setup).
### Requirements
- C++ compiler with good C++14 support.
- Tested on g++-9.3 and clang-7.0, AMD64 (x86_64) and Arm64 v8
- boost 1.7 library.
- (optional) CMake to build tests and/or examples.
- (optional) Linking with tcmalloc/jemalloc is recommended for speed.
### Building (Tests, Examples)
Out-of-source build with CMake is recommended.
```
mkdir build
cd build
cmake ..
make
```
You can run tests with following commands:
```
ctest
```
### Installing missing dependencies
#### Ubuntu
sudo apt-get install build-essential libtcmalloc-minimal4 && sudo ln -s /usr/lib/libtcmalloc_minimal.so.4 /usr/lib/libtcmalloc_minimal.so
#### OSX
brew install boost google-perftools
### Attributions
Crow uses the following libraries.
http-parser
http-parser (used for converting http strings to crow::request objects)
https://github.com/nodejs/http-parser
@ -160,7 +133,7 @@ Crow uses the following libraries.
IN THE SOFTWARE.
qs_parse
qs_parse (used for reading query string parameters)
https://github.com/bartgrantham/qs_parse
@ -175,7 +148,7 @@ Crow uses the following libraries.
all copies or substantial portions of the Software.
TinySHA1
TinySHA1 (used during the websocket handshake, not for security)
https://github.com/mohaps/TinySHA1

70
docs/assets/crowlogo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/assets/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

66
docs/assets/favicon.svg Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="95mm"
height="95mm"
viewBox="0 0 95 95"
version="1.1"
id="svg8"
sodipodi:docname="crowbirdlight.svg"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="148.31628"
inkscape:cy="216.73575"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-52.906909,-78.735456)">
<path
style="fill:#ffffff;stroke-width:0.0846667;fill-opacity:1"
d="m 71.571997,171.19568 c -3.572219,-2.5391 -6.958416,-4.99717 -7.297368,-5.29725 l -0.255219,-0.22595 0.463991,-1.397 c 0.255194,-0.76835 1.834897,-5.5499 3.510451,-10.62566 3.505253,-10.61849 6.335239,-19.079 8.227096,-24.59567 1.239876,-3.61549 1.312204,-3.86077 1.176445,-3.98957 -0.07956,-0.0755 -2.002027,-1.49736 -4.272152,-3.15973 -2.270126,-1.66237 -4.127501,-3.03677 -4.127501,-3.05422 0,-0.0174 0.447675,-0.17021 0.994834,-0.33945 4.886112,-1.51137 7.962219,-2.73416 9.445623,-3.75477 0.362819,-0.24963 0.387836,-0.2923 0.440626,-0.75162 0.254599,-2.21523 1.509656,-5.3475 3.28228,-8.19164 0.769332,-1.23437 1.327539,-1.89818 2.310037,-2.74704 1.807481,-1.56165 2.634149,-2.51067 2.87318,-3.298457 l 0.06174,-0.20349 -2.402627,0.0407 c -0.884406,-0.0983 -3.436624,1.252417 -4.036603,1.362387 -0.186563,0.0342 0.182778,-0.48865 0.827027,-0.8947 0.608067,-0.383237 2.967885,-1.868996 2.967885,-1.997926 0,-0.15087 -1.203166,0.2373 -2.304491,0.84657 -1.380268,0.763599 -2.708103,1.732686 -3.500379,2.442516 -0.395318,0.35418 -0.527363,0.47539 -0.576329,0.38396 -0.06369,-0.11892 1.312215,-2.814056 2.077584,-4.104836 0.984944,-1.661076 1.899268,-2.849086 2.965763,-3.853476 0.843653,-0.79454 1.169069,-1.00799 2.819519,-1.84946 0.6985,-0.35612 1.337903,-0.70012 1.420901,-0.76444 0.08299,-0.0643 0.438345,-0.85281 0.789669,-1.7522 0.762127,-1.95101 1.125034,-2.52632 2.402087,-3.80797 1.702596,-1.70871 3.541031,-2.68504 7.45234,-3.95765 2.632654,-0.85657 3.351464,-1.00385 5.868544,-1.20244 1.91219,-0.15087 2.39954,-0.16398 3.09033,-0.0831 3.13159,0.36649 5.80893,1.54633 9.04058,3.98397 0.85831,0.64742 1.46873,1.21026 2.54753,2.34895 0.78031,0.82364 1.59139,1.60837 1.80239,1.74385 0.48283,0.31002 1.36664,0.63352 2.66964,0.97715 2.19445,0.57872 3.18724,0.98741 4.488,1.84752 3.01295,1.99228 4.94472,5.175526 5.50942,9.078652 0.16952,1.17171 0.12699,3.48039 -0.0873,4.74136 -0.6988,4.11128 -2.69437,8.25567 -5.88294,12.21763 -2.65138,3.29447 -6.19099,6.58361 -9.38246,8.71852 -0.38426,0.25705 -1.69459,0.97024 -2.91184,1.58486 -2.34712,1.18513 -3.18189,1.65693 -3.57412,2.02002 -0.32252,0.29857 -4.7335,1.93493 -5.57734,3.13278 -1.4867,2.11039 -2.81695,9.84328 -3.87325,13.56096 l -0.86395,3.04071 1.60672,2.35209 c 0.88369,1.29365 3.39835,4.98099 5.58814,8.19409 5.88176,8.63041 5.30521,7.83167 5.65314,7.83167 0.16249,0 1.33262,-0.0797 2.60029,-0.17705 3.58462,-0.27535 5.36791,-0.16751 6.66165,0.4029 0.53171,0.23444 1.31143,0.79856 1.44267,1.04376 0.0828,0.15478 0.0726,0.16086 -0.13666,0.0813 -0.1244,-0.0473 -0.35049,-0.21254 -0.53149,-0.32585 -0.60447,-0.37843 -0.80593,-0.43812 -2.50665,-0.55585 -1.41918,0.003 -3.18867,0.13023 -3.62073,0.26008 -0.35615,0.10703 0.0151,0.17949 1.19163,0.23259 1.82677,0.0824 3.32001,0.3425 4.45473,0.77585 0.34294,0.13097 0.37119,0.21293 0.56494,0.52514 0.24967,0.40148 0.44912,0.77 0.6691,1.1632 0,0.0755 -0.31013,-0.0966 -0.93952,-0.52131 -0.50651,-0.34182 -0.66835,-0.3991 -1.73854,-0.61535 -4.11561,-0.83164 -9.67012,-0.84815 -12.8894,-0.0383 -0.60141,0.1513 -0.83385,0.17774 -0.96159,0.10937 -0.23979,-0.12833 -0.12667,-0.19934 0.78105,-0.49027 0.97335,-0.31197 2.06406,-0.85524 2.10087,-1.04641 0.0148,-0.0767 -0.88293,-1.46501 -1.99488,-3.08513 -1.11197,-1.62011 -2.98963,-4.35536 -4.17261,-6.07833 -1.18298,-1.72297 -3.10541,-4.52332 -4.27208,-6.223 l -2.121217,-3.09033 -0.561707,-0.0557 c -0.672863,-0.0668 -0.65693,-0.61032 -1.066759,-1.02015 -0.393624,-0.39363 -0.327565,-0.76458 -0.321727,-1.56889 0.0042,-0.58339 0.04272,-0.93417 0.237368,-2.88281 0.343284,-3.43671 0.648721,-11.14728 0.594721,-11.20128 -0.0118,-0.0119 -2.390554,0.778 -2.736553,0.88937 -4.142858,1.33368 -6.369262,1.9958 -6.719782,1.99843 -0.142629,0.001 -0.754625,0.0789 -1.359992,0.173 -0.605367,0.0941 -2.23724,0.3376 -3.626375,0.54116 -1.389143,0.20355 -2.545901,0.39029 -2.570573,0.41496 -0.02467,0.0247 -0.360833,1.771 -0.747034,3.88073 -0.386197,2.10973 -0.955554,5.16937 -1.26524,6.79921 -0.976296,5.13812 -2.064443,10.8145 -2.669894,13.92766 -0.548282,2.8192 -1.290101,6.64221 -1.872882,9.652 -0.288412,1.48953 -0.318055,1.60918 -0.398208,1.60737 -0.03179,-8.5e-4 -1.356829,-0.92465 -2.944538,-2.05317 z"
id="path26"
sodipodi:nodetypes="cscsssssscsssssccsssssssssssssscsssssscsssssscssscsssscscsccsssssssssccssscccsssssssccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:0.0846667"
d="m 103.24635,166.01478 c -4.1e-4,-0.0172 0.42481,-0.16375 0.94495,-0.32557 0.52013,-0.16182 0.99458,-0.31099 1.05432,-0.33149 0.0849,-0.0292 0.0862,-0.0768 0.006,-0.21787 -0.20866,-0.36832 -10.950188,-15.72058 -11.242607,-16.06842 -0.05962,-0.0709 -0.295982,-0.2506 -0.52525,-0.39928 -0.895092,-0.58043 -0.863337,-1.85618 -0.80318,-3.21042 0.02658,-0.59894 0.771215,-5.06795 1.491861,-9.39694 l 0.297644,-1.78798 c 0,0 -0.607552,-0.94689 3.600609,-2.41413 0.343222,-0.11967 0.633892,-0.20822 0.645912,-0.19675 0.012,0.0114 0.616817,1.86077 0.21254,4.03222 l -0.706969,3.79731 c 0,0 0,0 -0.417463,1.55135 -0.663151,2.46437 -0.798564,3.08375 -1.610943,5.38562 -0.439112,1.24422 -0.6823,2.26031 -0.70158,2.3144 -0.01927,0.0541 0.198595,0.47031 0.484162,0.92491 0.285576,0.4546 2.107625,3.3418 4.049014,6.41599 4.99398,7.90797 5.77721,9.08693 5.98879,9.01462 0.0719,-0.0245 0.36278,-0.14845 0.64644,-0.27532 0.58431,-0.2613 2.24506,-0.77345 3.30998,-1.02073 l 0.71353,-0.16568 0.42505,0.25623 0.42502,0.25623 -0.77419,0.0186 c -0.86578,0.0208 -1.566,0.15966 -1.70733,0.33853 -0.0785,0.0994 0.0348,0.1144 0.69539,0.0922 0.43405,-0.0144 1.19084,-0.0306 1.68176,-0.0354 l 0.89256,-0.009 0.33,0.29661 c 0.12162,0.10931 0.19804,0.18983 0.23555,0.25196 0.0376,0.0621 0.0362,0.10584 0.002,0.14154 -0.034,0.0357 -0.0753,0.053 -0.13356,0.0519 -0.0583,-0.002 -0.13345,-0.0211 -0.23537,-0.0598 -0.91405,-0.34638 -2.21414,-0.39029 -3.79182,-0.12849 -0.90397,0.15025 -2.41249,0.49222 -2.5411,0.57605 -0.0392,0.0255 -0.66947,0.11443 -1.40058,0.19738 -1.49048,0.16924 -1.54048,0.17343 -1.54153,0.1296 z"
id="path28"
sodipodi:nodetypes="sssssssscscscsssssssscccsscccsssscsscss" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,105 @@
This page explains how to set Crow up for use with your porject.
##Requirements
- C++ compiler with good C++14 support.
- Continuous Testing on g++-9.3 and clang-7.0, AMD64 (x86_64) and Arm64 v8
- C++11 should also work.
- boost library (1.70 or later).
- (optional) CMake and Python3 to build tests and/or examples.
- (optional) Linking with jemalloc/tcmalloc is recommended for speed.
<br><br>
##Installing Requirements
###Ubuntu
`sudo apt-get install libboost-all-dev`
###OSX
`brew install boost`
###Windows
Download boost from [here](https://www.boost.org/) and install it
##Downloading
Either run `git clone https://github.com/mrozigor/crow.git` or download `crow_all.h` from the releases section. You can also download a zip of the project on github.
##Includes folder
1. Copy the `/includes` folder to your project's root folder.
2. Add `#!cpp #include "path/to/includes/crow.h"` to your `.cpp` file.
3. For any middlewares, add `#!cpp #include "path/to/includes/middlewares/some_middleware.h"`.
<br><br>
##Single header file
If you've downloaded `crow_all.h`, you can skip to step 4.
1. Make sure you have python 3 installed.
2. Open a terminal (or `cmd.exe`) instance in `/path/to/crow/scripts`.
3. Run `python merge_all.py ../include crow_all.h` (replace `/` with `\` if you're on Windows).
4. Copy the `crow_all.h` file to where you put your libraries (if you don't know where this is, you can put it anywhere).
5. Add `#!cpp #include "path/to/crow_all.h"` to your `.cpp` file.
<br><br>
**Note**: All middlewares are included with the merged header file, if you would like to include or exclude middlewares use the `-e` or `-i` arguments.
<br><br>
##building via CLI
To build a crow Project, do the following:
###GCC (G++)
- Release: `g++ main.cpp -lpthread -lboost_system`.
- Debug: `g++ main.cpp -ggdb -lpthread -lboost_system -D CROW_ENABLE_DEBUG`.
- SSL: `g++ main.cpp -lssl -lpthread -lboost_system -D CROW_ENABLE_SSL`.
###Clang
- Release: `clang++ main.cpp -lpthread -lboost_system`.
- Debug: `clang++ main.cpp -g -lpthread -lboost_system -DCROW_ENABLE_DEBUG`.
- SSL: `clang++ main.cpp -lssl -lpthread -lboost_system -DCROW_ENABLE_SSL`.
###Microsoft Visual Studio
***Help needed***
##building via CMake
Add the following to your `CMakeLists.txt`:
``` cmake linenums="1"
find_package(Threads)
find_package(OpenSSL)
if(OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
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.70 COMPONENTS system thread regex REQUIRED )
else()
find_package( Boost 1.70 COMPONENTS system thread REQUIRED )
endif()
include_directories(${Boost_INCLUDE_DIR})
set(PROJECT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
include_directories("${PROJECT_INCLUDE_DIR}")
```
**Note**: The last 2 lines are unnecessary if you're using `crow_all.h`.
##Building Crow tests and examples
Out-of-source build with CMake is recommended.
```
mkdir build
cd build
cmake ..
make
```
Running Cmake will create `crow_all.h` file and place it in the build directory.
You can run tests with following commands:
```
ctest -V
```

View File

@ -0,0 +1,55 @@
This page shows how you can get started with a simple hello world application.
##1. Include
Starting with an empty `main.cpp` file, add `#!cpp #include "crow.h"` or `#!cpp #include "crow_all.h"` if you're using the single header file.
##2. App declaration
Next Create a `main()` and declare a `#!cpp crow::SimpleApp` inside, your code should look like this
``` cpp
int main()
{
crow::SimpleApp app;
}
```
The App (or SimpleApp) class organizes all the different parts of Crow and provides the developer (you) a simple interface to interact with these parts.
For more information, please go [here](/guides/app).
##3. Adding routes
Once you have your app, the next step is to add routes (or endpoints). You can do so with the `CROW_ROUTE` macro.
``` cpp
CROW_ROUTE(app, "/")([](){
return "Hello world";
});
```
For more details on routes, please go [here](/guides/routes).
#4. Running the app
Once you're happy with how you defined all your routes, you're going to want to instruct Crow to run your app. This is done using the `run()` method.
``` cpp
app.port(18080).multithreaded().run();
```
Please note that the `port()` and `multithreaded()` methods aren't needed, <del>we just put them there to confuse you.</del> Though not using `port()` will cause the default port (`80`) to be used.<br>
If you are using the default port, you can use `localhost` instead of `localhost:80` in your browser or client.<br>
##Putting it all together
Once you've followed all the steps above, your code should look similar to this
``` cpp linenums="1"
#include "crow.h"
//#include "crow_all.h"
int main()
{
crow::SimpleApp app; //define your crow application
//define your endpoint at the root directory
CROW_ROUTE(app, "/")([](){
return "Hello world";
});
//set the port, set the app to run on multiple threads, and run the app
app.port(18080).multithreaded().run();
}
```
After building and running your .cpp file, you should be able to access your endpoint at [http://localhost:18080](http://localhost:18080). Opening this URL in your browser will show a white screen with "Hello world" typed on it.

29
docs/guides/app.md Normal file
View File

@ -0,0 +1,29 @@
A Crow app defines an interface to allow the developer access to all the different parts of the framework, without having to manually deal with each one.<br><br>
An app allows access to the http server (for handling connections), router (for handling URLs and requests), Middlewares (for extending Crow), amoung many others.<br><br>
Crow has 2 different app types:
##SimpleApp
Has no middlewares.
##App&lt;m1, m2, ...&gt;
Has middlewares.
##Using the app
To use a Crow app, simply define `#!cpp crow::SimpleApp` or `#!cpp crow::App<m1, m2 ...>` if you're using middlewares.<br>
The methods of an app can be chained. That means that you can configure and run your app in the same code line.
``` cpp
app.bindaddr(192.168.1.2).port(443).ssl_file("certfile.crt","keyfile.key").multithreaded().run();
```
Or if you like your code neat
``` cpp
app.bindaddr(192.168.1.2)
.port(443)
.ssl_file("certfile.crt","keyfile.key")
.multithreaded()
.run();
```
<br><br>
For more info on middlewares, check out [this page](/guides/middleware).<br><br>
For more info on what functions are available to a Crow app, go [here](/reference/classcrow_1_1_crow.html).

29
docs/guides/json.md Normal file
View File

@ -0,0 +1,29 @@
Crow has built in support for JSON data.<br><br>
##rvalue
JSON read value, used for taking a JSON string and parsing it into `crow::json`.<br><br>
You can read individual items of the rvalue, but you cannot add items to it.<br>
To do that, you need to convert it to a `wvalue`, which can be done by simply writing `#!cpp crow::json::wvalue wval (rval);` (assuming `rval` is your `rvalue`).<br><br>
For more info on read values go [here](/reference/classcrow_1_1json_1_1rvalue.html).<br><br>
#wvalue
JSON write value, used for creating, editing and converting JSON to a string.<br><br>
The types of values that `wvalue` can take are as follows:<br>
- `False`: from type `bool`.
- `True`: from type `bool`.
- `Number`
- `Floating_point`: from type `double`.
- `Signed_integer`: from type `int`.
- `Unsigned_integer`: from type `unsigned int`.
- `String`: from type `std::string`.
- `List`: from type `std::vector`.
- `Object`: from type `crow::json::wvalue`.<br>
This last type means that `wvalue` can have keys, this is done by simply assigning a value to whatever string key you like, something like `#!cpp wval["key1"] = val1;`. Keep in mind that val1 can be any of the above types.<br><br>
A JSON wvalue can be returned directly inside a route handler, this will canse the `content-type` header to automatically be set to `Application/json` and the JSON value will be converted to string and placed in the response body. For more information go to [Routes](/guides/routes).<br><br>
For more info on write values go [here](/reference/classcrow_1_1json_1_1wvalue.html).

20
docs/guides/logging.md Normal file
View File

@ -0,0 +1,20 @@
Crow comes with a simple and easy to use logging system.<br><br>
##Setting up logging level
You can set up the level at which crow displays logs by using the app's `loglevel(crow::logLevel)` method.<br><br>
The available log levels are as follows (please not that setting a level will also display all logs below this level):
- Debug
- Info
- Warning
- Error
- Critical
<br><br>
To set a logLevel, just use `#!cpp app.loglevel(crow::logLevel::Warning)`, This will not show any debug or info logs. It will however still show error and critical logs.<br><br>
Please note that setting the Macro `CROW_ENABLE_DEBUG` during compilation will also set the log level to `Debug`.
##Writing a log
Writing a log is as simple as `#!cpp CROW_LOG_<LOG LEVEL> << "Hello";` (replace&lt;LOG LEVEL&gt; with the actual level in all caps, so you have `CROW_LOG_WARNING`).

29
docs/guides/middleware.md Normal file
View File

@ -0,0 +1,29 @@
Any middleware requires following 3 members:
##struct context
Storing data for the middleware; can be read from another middleware or handlers
##before_handle
Called before handling the request.<br>
If `res.end()` is called, the operation is halted. (`after_handle` will still be called)<br>
2 signatures:<br>
`#!cpp void before_handle(request& req, response& res, context& ctx)`
if you only need to access this middleware's context.
``` cpp
template <typename AllContext>
void before_handle(request& req, response& res, context& ctx, AllContext& all_ctx)
```
You can access other middlewares' context by calling `#!cpp all_ctx.template get<MW>()`<br>
`#!cpp ctx == all_ctx.template get<CurrentMiddleware>()`
##after_handle
Called after handling the request.<br>
`#!cpp void after_handle(request& req, response& res, context& ctx)`
``` cpp
template <typename AllContext>
void after_handle(request& req, response& res, context& ctx, AllContext& all_ctx)
```
<br><br>
This was pulled from `cookie_parser.h`. Further Editing required, possibly use parts of [@ipkn's wiki page](https://github.com/ipkn/crow/wiki/Middleware).

20
docs/guides/multipart.md Normal file
View File

@ -0,0 +1,20 @@
Multipart is a way of forming HTTP requests or responses to contain multiple distinct parts.<br>
Such an approach allows a request to contain multiple different pieces of data with potentially conflicting data types in a single response payload.<br>
It is typically used either in html forms, or when uploading multiple files.<br><br>
The structure of a multipart request is typically consistent of:<br>
- A Header: Typically `multipart/form-data;boundary=<boundary>`, This defines the HTTP message as being multipart, as well as defining the separator used to distinguish the different parts.<br>
- 1 or more parts:
- `--<boundary>`
- Part header: typically `content-disposition: mime/type; name="<fieldname>"` (`mime/type` should be replaced with the actual mime-type), can also contain a `filename` property (separated from the rest by a `;` and structured similarly to the `name` property)
- Value
- `--<boundary>--`<br><br>
Crow supports multipart requests and responses though `crow::multipart::message`.<br>
A message can be created either by defining the headers, boundary, and individual parts and using them to create the message. or simply by reading a `crow::request`.<br><br>
Once a multipart message has been made, the individual parts can be accessed throught `mpmes.parts`, `parts` is an `std::vector`, so accessing the individual parts should be straightforward.<br>
In order to access the individual part's name or filename, something like `#!cpp mpmes.parts[0].headers[0].params["name"]` sould do the trick.<br><br>
For more info on Multipart messages, go [here](/reference/namespacecrow_1_1multipart.html)

1
docs/guides/proxies.md Normal file
View File

@ -0,0 +1 @@
***HELP NEEDED***

46
docs/guides/routes.md Normal file
View File

@ -0,0 +1,46 @@
Routes define what happens when your client connects to a certain URL.<br>
##Macro
`CROW_ROUTE(app, url)`<br>
Can be replaced with `#!cpp app.route<crow::black_magick::get_parameter_tag(url)>(url)` or `#!cpp app.route_dynamic(url)` if you're using VS2013 or want runtime url evaluation. Although this usage is **NOT** recommended.
##App
Which app class to assign the route to.
##Path (URL)
Which relative path is assigned to the route.<br>
Using `/hello` means the client will need to access `http://example.com/hello` in order to access the route.<br>
A path can have parameters, for example `/hello/<int>` will allow a client to input an int into the url which will be in the handler (something like `http://example.com/hello/42`).<br>
Parameters can be `<int>`, `<uint>`, `<double>`, `<string>`, or `<path>`.<br>
It's worth nothing that the parameters also need to be defined in the handler, an example of using parameters would be to add 2 numbers based on input:
```cpp
CROW_ROUTE(app, "/add/<int>/<int>")
([](int a, int b)
{
return std::to_string(a+b);
});
```
you can see the first `<int>` is defined as `a` and the second as `b`. If you were to run this and call `http://example.com/add/1/2`, the result would be a page with `3`. Exciting!
##Handler
Basically a piece of code that gets executed whenever the client calls the associated route, usually in the form of a [lambda expression](https://en.cppreference.com/w/cpp/language/lambda). It can be as simple as `#!cpp ([](){return "Hello World"})`.<br><br>
###Request
Handlers can also use information from the request by adding it as a parameter `#!cpp ([](const crow::request& req){...})`.<br><br>
You can also access the url parameters in the handler using `#!cpp req.url_params.get("param_name");`. If the parameter doesn't exist, `nullptr` is returned.<br><br>
For more information on `crow::request` go [here](/reference/structcrow_1_1request.html).<br><br>
###Response
Crow also provides the ability to define a response in the parameters by using `#!cpp ([](const crow::request& req, crow::response& res){...})`.<br>
If you don't want to use the request you can write `#!cpp ([](const crow::request& , crow::response& res){...})`.<br>
Yes I know there's a pull request to make it as simple as `#!cpp ([](crow::response& res){...})`, but I can't test it and add it to the repository while writing this documentation.<br><br>
Please note that in order to return a response defined as a parameter you'll need to use `res.end();`.<br><br>
Alternatively, you can define the response in the body and return it (`#!cpp ([](){return crow::response()})`).<br>
For more information on `crow::response` go [here](/reference/structcrow_1_1response.html).<br><br>
###return statement
A `crow::response` is very strictly tied to a route. If you can have something in a response constructor, you can return it in a handler.<br><br>
The main return type is `std::string`. although you could also return a `crow::json::wvalue` directly. ***(Support for more data types including third party libraries is coming soon)***<br><br>
For more information on the specific constructors for a `crow::response` go [here](/reference/structcrow_1_1response.html).

10
docs/guides/ssl.md Normal file
View File

@ -0,0 +1,10 @@
Crow supports HTTPS though SSL or TLS.<br><br>
When mentioning SSL in this documentation, it is often a reference to openSSL, which includes TLS. Don't worry, we don't use obsolete security standards :)<br><br>
To enable SSL, first your application needs to define either a `.crt` and `.key` files, or a `.pem` file. Once you have your files, you can add them to your app like this:<br>
`#!cpp app.ssl_file("/path/to/cert.crt", "/path/to/keyfile.key")` or `#!cpp app.ssl_file("/path/to/pem_file.pem")`. Please note that this method can be part of the app method chain, which means it can be followed by `.run()` or any other method.<br><br>
You can also set your own SSL context (by using `boost::asio::ssl::context ctx`) and then applying it via the `#!cpp app.ssl(ctx)` method.<br><br>
**IMPORTANT NOTICE**: If you plan on using a proxy like Nginx or Apache2, **DO NOT** use SSL in crow, instead define it in your proxy instead and keep the connection between the proxy and Crow non-SSL.

14
docs/guides/static.md Normal file
View File

@ -0,0 +1,14 @@
A static file is any file that resides in the server's storage.
Crow supports returning Static files as responses in 2 ways.
##Implicit
Crow implicitly returns any static files placed in a `static` directory and any subdirectories, as long as the user calls the endpoint `/static/path/to/file`.<br><br>
The static folder or endpoint can be changed by defining the macros `CROW_STATIC_DRIECTORY "alternative_directory/"` and `CROW_STATIC_ENDPOINT "/alternative_endpoint/<path>"`.<br>
static directory changes the directory in the server's filesystem, while the endpoint changes the URL that the client needs to access.
##Explicit
You can directly return a static file by using the `crow::response` method `#!cpp response.set_static_file_info("path/to/file");`. The path is relative to the executable unless preceded by `/`, then it is an absolute path.<br>
Please keep in mind that using the `set_static_file_info` method does invalidate any data already in your response body.<br><br>
**Note**: Crow sets the `content-type` header automatically based on the file's extension, if an extension is unavailable or undefined, Crow uses `text/plain`, if you'd like to explicitly set a `content-type`, use `#!cpp response.set_header("content-type", "mime/type");` **AFTER** calling `set_static_file_info`.

1
docs/guides/syste.md Normal file
View File

@ -0,0 +1 @@
https://www.howtogeek.com/687970/how-to-run-a-linux-program-at-startup-with-systemd/

23
docs/guides/templating.md Normal file
View File

@ -0,0 +1,23 @@
Templating is when you return an html page with custom data. You can probably tell why that's useful.<br><br>
Crow supports [mustache](http://mustache.github.io) for templates through its own implementation `crow::mustache`.<br><br>
##Components of mustache
There are 2 components of a mustaceh template:
- Page
- Context
###Page
The HTML page (including the mustache tags). usually loaded into `crow::mustache::template_t` Needs to be placed in "templates" directory (relative to where the crow executable is).<br><br>
For more inforation on how to formulate a template, see [this mustache manual](http://mustache.github.io/mustache.5.html).
###Context
A JSON object containing the tags as keys and their values. `crow::mustache::context` is actually a [crow::json::wvalue](/guides/json#wvalue).
##Returning a template
To return a mustache template, you need to load a page using `#!cpp auto page = crow::mustache::load("path/to/template.html");`, keep in mind that the path is relative to the templates directory.<br>
You also need to set up the context by useing `#!cpp crow::mustache::context ctx;`. Then you need to assign the keys and values, this can be done the same way you assign values to a json write value (`ctx["key"] = value;`).<br>
With your context and page ready, just `#!cpp return page.render(ctx);`. This will use the context data to return a filled template.

31
docs/guides/websockets.md Normal file
View File

@ -0,0 +1,31 @@
Websockets are a way of connecting a client and a server without the request response nature of HTTP.<br><br>
To create a websocket in Crow, you need a websocket route.<br>
A websocket route differs from a normal route quite a bit. While it uses the same `CROW_ROUTE(app, "/url")` macro, that's about where the similarities end.<br>
A websocket route follows the macro with `.websocket()` which is then followed by a series of methods (with handlers inside) for each event. These are:
- `#!cpp onopen([&](crow::websocket::connection& conn){handler code goes here})`
- `#!cpp onaccept([&](const crow::request&){handler code goes here})` (This handler has to return bool)
- `#!cpp onmessage([&](crow::websocket::connection& conn, const std::string message, bool is_binary){handler code goes here})`
- `#!cpp onclose([&](crow::websocket::connection& conn, const std::string reason){handler code goes here})`
- `#!cpp onerror([&](crow::websocket::connection& conn){handler code goes here})`<br><br>
These event methods and their handlers can be chained. The full Route should look similar to this:
```cpp
CROW_ROUTE(app, "/ws")
.websocket()
.onopen([&](crow::websocket::connection& conn){
do_something();
})
.onclose([&](crow::websocket::connection& conn, const std::string& reason){
do_something();
})
.onmessage([&](crow::websocket::connection& /*conn*/, const std::string& data, bool is_binary){
if (is_binary)
do_something(data);
else
do_something_else(data);
});
```
<br><br>
For more info go [here](/reference/classcrow_1_1_web_socket_rule.html).

101
docs/index.md Normal file
View File

@ -0,0 +1,101 @@
#
<p align="center"><img src="assets/crowlogo.svg" width=600></p>
<h4 align="center">A Fast and Easy to use microframework for the web.</h4>
<p align="center">
<a href="https://travis-ci.com/mrozigor/crow"><img src="https://travis-ci.com/mrozigor/crow.svg?branch=master" alt="Build Status"></a>
<a href="https://coveralls.io/github/mrozigor/crow?branch=master"><img src="https://coveralls.io/repos/github/mrozigor/crow/badge.svg?branch=master" alt="Coverage Status"></a>
<a href="https://mrozigor.github.io/crow"><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>
</p>
## Description
Crow is a C++ microframework for running web services. It uses routing similar to Python's Flask which makes it easy to use. It is also extremely fast, beating multiple existing C++ frameworks as well as non C++ frameworks.
### Features
- Easy Routing (similar to flask).
- Type-safe Handlers.
- Blazingly fast (see [this benchmark](https://github.com/ipkn/crow-benchmark) and [this benchmark](https://github.com/guteksan/REST-CPP-benchmark)).
- Built in JSON support.
- [Mustache](http://mustache.github.io/) based templating library (`crow::mustache`).
- Header only library (single header file available).
- Middleware support for extensions.
- HTTP/1.1 and Websocket support.
- Multi-part request and response support.
- Uses modern C++ (11/14)
### Still in development
- [HTTP/2 support](https://github.com/mrozigor/crow/issues/8)
## Documentation
Available [here](https://mrozigor.github.io/crow).
## Examples
#### Hello World
```c++
#include "crow.h"
int main()
{
crow::SimpleApp app;
CROW_ROUTE(app, "/")([](){
return "Hello world";
});
app.port(18080).multithreaded().run();
}
```
#### JSON Response
```cpp
CROW_ROUTE(app, "/json")
([]{
crow::json::wvalue x;
x["message"] = "Hello, World!";
return x;
});
```
#### Arguments
```cpp
CROW_ROUTE(app,"/hello/<int>")
([](int count){
if (count > 100)
return crow::response(400);
std::ostringstream os;
os << count << " bottles of beer!";
return crow::response(os.str());
});
```
Handler arguments type check at compile time
```cpp
// Compile error with message "Handler type is mismatched with URL paramters"
CROW_ROUTE(app,"/another/<int>")
([](int a, int b){
return crow::response(500);
});
```
#### Handling JSON Requests
```cpp
CROW_ROUTE(app, "/add_json")
.methods("POST"_method)
([](const crow::request& req){
auto x = crow::json::load(req.body);
if (!x)
return crow::response(400);
int sum = x["a"].i()+x["b"].i();
std::ostringstream os;
os << sum;
return crow::response{os.str()};
});
```
More examples can be found [here](https://github.com/mrozigor/crow/tree/master/examples).
## Setting Up / Building
Available [here](https://mrozigor.github.io/crow/getting_started/setup).

Binary file not shown.

View File

@ -0,0 +1,6 @@
:root {
--md-primary-fg-color: #161616;
--md-accent-fg-color: #396A97;
--md-typeset-a-color: var(--md-accent-fg-color);
}

View File

@ -0,0 +1,10 @@
/* Webfont: Lato-Medium */@font-face {
font-family: 'Lato';
src: url('Lato-Medium.ttf') format('truetype');
font-style: normal;
font-weight: normal;
text-rendering: optimizeLegibility;
}
body, input {
font-family: "Lato", -apple-system, Helvetica, Arial, sans-serif;
}

61
mkdocs.yml Normal file
View File

@ -0,0 +1,61 @@
site_name: Crow
# Repository
repo_name: mrozigor/crow
repo_url: https://github.com/mrozigor/crow
edit_uri: ""
theme:
name: material
palette:
- scheme: Crow
font: false
language: 'en'
features:
navigation.tabs
favicon: 'assets/favicon.svg'
logo: 'assets/favicon.svg'
icon:
repo: fontawesome/brands/github-square
markdown_extensions:
- pymdownx.highlight
- pymdownx.superfences
- pymdownx.inlinehilite
- pymdownx.keys
nav:
- Home: index.md
- Getting Started:
- Setup: getting_started/setup.md
- Your First Application: getting_started/your_first_application.md
- Guides:
- Different parts of Crow:
- App: guides/app.md
- Routes: guides/routes.md
- Logging: guides/logging.md
- JSON: guides/json.md
- Templating (Mustache): guides/templating.md
- Multipart: guides/multipart.md
- Middleware: guides/middleware.md
- SSL: guides/ssl.md
- Static Files: guides/static.md
- Websockets: guides/websockets.md
- Server setup:
- Proxies: guides/proxies.md
- Systemd run on startup: guides/syste.md
- API Reference:
- API Reference: '/reference/index.html'
extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/mrozigor/crow
- icon: fontawesome/brands/gitter
link: https://gitter.im/crowfork/community
extra_css:
- 'stylesheets/colors.css'
- 'stylesheets/latofonts.css'
copyright: 'Copyright &copy; 2020 Farook Al-Sammarraie'

View File

@ -60,9 +60,15 @@ git config user.email "travis@travis-ci.org"
# stayed the same and will only update the changed files. So the gh-pages branch
# can be safely cleaned, and it is sure that everything pushed later is the new
# documentation.
cp index.html ..
#cp index.html ..
rm -rf *
mv ../index.html .
#mv ../index.html .
# Copy the mkdocs documentation to the work directory and generate the mkdocs
# 'site' directory
cp ../../mkdocs.yml .
cp -r ../../docs .
mkdocs build
# Need to create a .nojekyll file to allow filenames starting with an underscore
# to be seen on the gh-pages site. Therefore creating an empty .nojekyll file.
@ -76,12 +82,21 @@ echo 'Generating Doxygen code documentation...'
# Redirect both stderr and stdout to the log file AND the console.
doxygen $DOXYFILE 2>&1 | tee doxygen.log
# Rename mkdocs' output folder to 'html' to retain compatibility with the
# existing index.html and the rest of this code.
# Also remove any remaining documentation files.
mv site/* .
rm -r site
rm mkdocs.yml
rm -r docs
################################################################################
##### Upload the documentation to the gh-pages branch of the repository. #####
# Only upload if Doxygen successfully created the documentation.
# Check this by verifying that the html directory and the file html/index.html
# both exist. This is a good indication that Doxygen did it's work.
if [ -d "html" ] && [ -f "html/index.html" ]; then
# Check this by verifying that the reference directory (for doxygen) and
# the file index.html (for mkdocs) both exist.
# This is a good indication that Doxygen and Mkdocs did their work.
if [ -d "reference" ] && [ -f "index.html" ]; then
echo 'Uploading documentation to the gh-pages branch...'
# Add everything in this directory (the Doxygen code documentation) to the