Merge branch 'master' into ssl_test
|
@ -15,7 +15,7 @@ steps:
|
|||
|
||||
commands:
|
||||
- export DEBIAN_FRONTEND=noninteractive
|
||||
- export TRAVIS_BRANCH=$DRONE_SOURCE_BRANCH
|
||||
- export TRAVIS_BRANCH=$DRONE_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 openssl libssl-dev
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
open_collective: crow
|
|
@ -76,3 +76,9 @@ endif()
|
|||
# Install Files
|
||||
#####################################
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/crow_all.h DESTINATION include)
|
||||
|
||||
set(CPACK_GENERATOR "DEB")
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "CrowCpp")
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
|
||||
include(CPack)
|
||||
|
|
2
Doxyfile
|
@ -38,7 +38,7 @@ PROJECT_NAME = Crow
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.2
|
||||
PROJECT_NUMBER = 0.3
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
|
5
LICENSE
|
@ -1,4 +1,5 @@
|
|||
Copyright (c) 2014, ipkn
|
||||
Copyright (c) 2014-2017, ipkn
|
||||
2020-2021, CrowCpp
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -25,3 +26,5 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|||
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.
|
||||
|
|
23
README.md
|
@ -1,11 +1,12 @@
|
|||
<p align="center"><img src="https://crowcpp.org/assets/crowlogo.svg" width=600></p>
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/CrowCpp/Crow/master/docs/assets/crowlogo_dual_color.svg" width=600></p>
|
||||
|
||||
<h4 align="center">A Fast and Easy to use microframework for the web.</h4>
|
||||
<p align="center">
|
||||
<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.github.io/crow"><img src="https://img.shields.io/badge/-Documentation-informational" alt="Documentation"></a>
|
||||
<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&utm_medium=badge&utm_campaign=pr-badge"><img src="https://badges.gitter.im/crowfork/community.svg" 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>
|
||||
|
||||
|
||||
|
@ -29,12 +30,13 @@ Crow is a C++ microframework for running web services. It uses routing similar t
|
|||
- [HTTP/2 support](https://github.com/crowcpp/crow/issues/8)
|
||||
|
||||
## Documentation
|
||||
Available [here](https://crowcpp.github.io/crow).
|
||||
Available [here](https://crowcpp.org).
|
||||
|
||||
## Examples
|
||||
|
||||
#### Hello World
|
||||
```c++
|
||||
```cpp
|
||||
#define CROW_MAIN
|
||||
#include "crow.h"
|
||||
|
||||
int main()
|
||||
|
@ -97,12 +99,13 @@ CROW_ROUTE(app, "/add_json")
|
|||
More examples can be found [here](https://github.com/crowcpp/crow/tree/master/examples).
|
||||
|
||||
## Setting Up / Building
|
||||
Available [here](https://crowcpp.github.io/crow/getting_started/setup).
|
||||
Available [here](https://crowcpp.org/getting_started/setup).
|
||||
|
||||
## Disclaimer
|
||||
CrowCpp/Crow is a project based on ipkn/crow. Neither CrowCpp, it's members, or this project have been associated with, or endorsed or supported by ipkn (Jaeseung Ha) in any way. We do use ipkn/crow's source code under the BSD-3 clause license and sometimes refer to the public comments available on the github repository. But we do not in any way claim to be associated with or in contact with ipkn (Jaeseung Ha) regarding CrowCpp or CrowCpp/Crow
|
||||
|
||||
### Attributions
|
||||
|
||||
Crow uses the following libraries.
|
||||
## Attributions
|
||||
Crow has incorporated the following libraries into its source.
|
||||
|
||||
http-parser (used for converting http strings to crow::request objects)
|
||||
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="900"
|
||||
height="400"
|
||||
viewBox="0 0 238.12499 105.83333"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
sodipodi:docname="crowlogo_inverted.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
inkscape:export-filename="/home/farook/vaiossd/Pictures/CrowLogo.png"
|
||||
inkscape:export-xdpi="324.99619"
|
||||
inkscape:export-ydpi="324.99619"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="281.42857"
|
||||
inkscape:cy="511.42857"
|
||||
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"
|
||||
units="px"
|
||||
inkscape:pagecheckerboard="0" />
|
||||
<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" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(2.890729,-78.735456)">
|
||||
<path
|
||||
id="rect51232"
|
||||
style="stroke-width:1.621;stroke-linecap:round;stroke-linejoin:round;fill:#ffffff;fill-opacity:1"
|
||||
d="m 86.263122,129.89227 c -1.679885,0.94306 -0.970661,50.071 -0.970661,50.071 h 8.67359 c 0,0 -1.146978,-23.39877 0.97066,-22.01299 5.738329,3.75514 18.678879,22.04105 18.678879,22.04105 l 10.82099,0.0233 c 0,0 -22.33706,-23.42311 -21.33927,-25.78171 0.99777,-2.35858 13.45284,-3.56535 14.28699,-5.61353 0.83414,-2.04817 0.74681,-7.53026 0.0119,-9.332 -0.73488,-1.80175 -17.951097,-8.50923 -22.459538,-9.39514 -4.508449,-0.88592 -6.875855,-1.00922 -8.67359,0 z m 8.673589,7.89629 c 0.435027,-0.21177 12.515509,4.68197 12.527659,5.49714 0.0113,0.76226 -12.065069,5.41359 -12.527659,5.04327 -0.327731,-0.26235 -0.43502,-10.32863 0,-10.54041 z"
|
||||
sodipodi:nodetypes="sccscczzzzszssz" />
|
||||
<path
|
||||
id="path55748"
|
||||
style="stroke-width:1.50035;stroke-linecap:round;stroke-linejoin:round;fill:#ffffff;fill-opacity:1"
|
||||
d="m 214.40962,132.10711 c 0,0 -6.19646,30.36708 -7.43712,30.33831 -1.22676,-0.0284 -7.40908,-29.27248 -7.40908,-29.27248 l -7.84322,0.0207 c 0,0 -4.25108,28.63573 -6.44505,28.48646 -1.9928,-0.13558 -7.20545,-29.39322 -7.20545,-29.39322 l -7.79639,1.91192 11.03502,45.01483 7.88892,1.48481 c 0,0 5.4369,-26.82435 6.66418,-26.78989 1.22731,0.0345 7.42065,26.61016 7.42065,26.61016 l 7.88891,-1.4848 11.03501,-45.01483 z"
|
||||
sodipodi:nodetypes="csccscccczcccc" />
|
||||
<path
|
||||
id="rect53235"
|
||||
style="fill:none;stroke:#fefefe;stroke-width:8.65014;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 128.1657,156.63351 c 0.0252,15.02476 7.0482,20.22602 17.35625,20.23066 10.30804,0.005 17.61679,-6.50768 17.8414,-20.03302 0.2246,-13.52536 -8.11076,-20.48288 -17.43254,-20.41622 -9.32178,0.0666 -17.79031,5.1938 -17.76511,20.21858 z"
|
||||
sodipodi:nodetypes="zzzzz" />
|
||||
<path
|
||||
style="color:#000000;fill:#ffffff;stroke-width:0.669208;-inkscape-stroke:none;fill-opacity:1"
|
||||
d="m 75.361766,164.31848 c -1.522517,0.0929 -3.225106,0.23753 -5.059422,0.41007 -14.861309,1.39786 -38.370023,4.6261 -44.831721,-3.01508 -7.259264,-8.58431 -5.992766,-15.11802 -3.7379,-29.04552 2.254865,-13.92751 11.768175,-32.3183 23.453693,-33.61763 11.685519,-1.299327 24.289435,-0.14247 28.381026,1.21309 L 77.417321,85.791987 C 62.828148,82.27312 56.039475,80.867702 37.328615,83.440263 18.617756,86.012824 9.3053305,108.67011 6.7920712,129.55115 c -2.5132504,20.88098 -0.630659,37.59767 5.7039948,44.13904 6.334653,6.54136 43.941662,8.861 64.480651,5.0425 z"
|
||||
id="path830"
|
||||
sodipodi:nodetypes="csszzcczzzcc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.150696px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 52.770285,159.45785 -1.325495,1.13614 c 0,0 1.379598,1.29845 1.866513,1.86651 0.486919,0.56807 3.056762,4.95033 3.273169,5.70775 0.21641,0.75743 1.136142,0.91974 1.839463,1.7042 0.703326,0.78449 2.109969,1.59601 1.08204,2.40754 -1.027937,0.81154 0.973835,0.35167 0.919732,-0.91972 -0.05411,-1.2714 1.893562,2.40754 0.513964,2.89445 -1.379593,0.48692 0.703322,0.51397 0.973835,0.0541 0.270504,-0.45986 0.405763,-1.29844 0.297562,-2.21817 -0.108205,-0.91974 -1.514856,-2.62395 -1.839468,-2.9215 -0.324607,-0.29757 1.541906,-0.18936 2.05587,0.48691 0.513978,0.67627 0.568071,0.89268 0.189357,1.46075 -0.37871,0.56808 1.487803,-0.45986 0.59513,-1.3796 -0.892688,-0.91972 -0.216416,-0.83858 -1.460759,-1.43369 -1.244344,-0.59513 -1.379598,-0.97385 -2.43458,-0.91973 -1.054986,0.0541 -6.546333,-7.92594 -6.546333,-7.92594 z"
|
||||
id="path15574" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.150696px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 61.426586,156.42814 -1.568955,0.97384 3.597781,4.0306 c 0,0 1.866513,1.35254 1.487803,2.75918 -0.378714,1.40665 -1.352549,1.92063 -1.352549,1.92063 0,0 0.13525,0.24344 0.568067,0.24344 0.432817,0 0.973835,-1.40663 1.758317,-0.97382 0.784473,0.43282 1.893562,1.51484 2.082919,2.19112 0.189357,0.67628 0.05411,0.83858 0.162303,0.97383 0.108206,0.13526 0.676277,0.13526 0.595121,-0.43281 -0.08115,-0.56807 0.378714,-0.0271 0.486919,0.45986 0.10821,0.48692 0.459862,1.35255 0.405759,2.19113 -0.0541,0.83857 0.486919,1.65011 0.459875,0.43281 -0.02705,-1.21728 0.243455,-2.54278 -0.37871,-3.65187 -0.622174,-1.10909 -0.892687,-2.59688 0.08114,-1.62306 0.973839,0.97383 1.731268,1.08205 2.001776,1.78536 0.270509,0.70333 0.24346,0.86563 0.568067,0.86563 0.324612,0 0.135255,-0.97383 -0.459866,-1.65011 -0.595116,-0.67626 -0.622174,-1.35254 -2.326379,-2.21817 -1.704214,-0.86563 -2.623946,-1.73126 -4.436351,-3.38137 -1.812424,-1.65011 -3.73304,-4.89622 -3.73304,-4.89622 z"
|
||||
id="path15576" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.150696px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 55.533489,166.09236 c 0.531307,0.94733 0.967262,1.78287 1.050983,2.07589 0.21641,0.75743 1.136142,0.91974 1.839463,1.7042 0.703326,0.78449 2.109969,1.59601 1.08204,2.40754 -1.027937,0.81154 0.973835,0.35167 0.919732,-0.91972 -0.05411,-1.2714 1.893562,2.40754 0.513964,2.89445 -1.379593,0.48692 0.703322,0.51397 0.973835,0.0541 0.270504,-0.45986 0.405763,-1.29844 0.297562,-2.21817 -0.108205,-0.91974 -1.514856,-2.62395 -1.839468,-2.9215 -0.324607,-0.29757 1.541906,-0.18936 2.05587,0.48691 0.513978,0.67627 0.568071,0.89268 0.189357,1.46075 -0.37871,0.56808 1.487803,-0.45986 0.59513,-1.3796 -0.892688,-0.91972 -0.216416,-0.83858 -1.460759,-1.43369 -1.244344,-0.59513 -1.379598,-0.97384 -2.43458,-0.91973 -0.290776,0.015 -0.918584,-0.58052 -1.675534,-1.45097 z"
|
||||
id="path16765"
|
||||
sodipodi:nodetypes="cssssssssssssscc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.150696px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 65.263268,165.22329 c 0.194353,3.9e-4 0.291031,0.0149 0.484578,0.0788 0.564847,0.18634 2.110365,1.76478 2.252123,2.27108 0.189357,0.67628 0.05411,0.83858 0.162303,0.97383 0.108206,0.13526 0.676277,0.13526 0.595121,-0.43282 -0.08115,-0.56806 0.378714,-0.0271 0.486919,0.45987 0.10821,0.48691 0.459862,1.35254 0.405759,2.19113 -0.0541,0.83857 0.313763,1.62347 0.459875,0.43281 0.148298,-1.20852 0.243455,-2.54277 -0.37871,-3.65187 -0.622174,-1.10909 -0.892687,-2.59689 0.08114,-1.62306 0.973839,0.97383 1.731268,1.08204 2.001776,1.78536 0.270509,0.70333 0.24346,0.86563 0.568067,0.86563 0.324612,0 0.135255,-0.97383 -0.459866,-1.65011 -0.595116,-0.67626 -0.473424,-1.27723 -2.177629,-2.14286 z"
|
||||
id="path16767"
|
||||
sodipodi:nodetypes="csssssssssssscc" />
|
||||
<path
|
||||
id="path7288"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.14952px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 49.18396,111.42134 c -1.800635,-0.0245 -5.26385,0.56015 -5.867743,1.66729 -0.644159,1.18095 -0.155808,1.17068 -0.155808,1.17068 0,0 0.09733,-0.0339 0.187346,-0.0614 0.02378,-0.0261 0.02481,-0.0554 0.03436,-0.076 0.02875,-0.062 0.09717,-0.1904 0.336564,-0.33445 0.312033,-0.18776 0.872977,-0.3496 1.664461,-0.30102 h 2.41e-4 c 0.78943,0.0485 2.533815,0.30776 4.087014,0.56604 1.553342,0.25829 2.875385,0.47236 2.875385,0.47236 0.04495,0.006 0.143795,0.10749 0.08567,0.26878 -0.0058,0.0327 -0.06495,-0.002 -0.214412,-0.0993 -0.06614,-0.0229 -1.213381,-0.26531 -2.765708,-0.52344 -1.552327,-0.25813 -3.30239,-0.52923 -4.075718,-0.56439 -0.771201,-0.0351 -1.253838,0.11807 -1.525598,0.31868 -0.153775,0.11351 -0.228149,0.2138 -0.224063,0.25301 0.0041,0.0392 0.763976,0.84306 0.763976,0.84306 0,0 4.729649,0.87015 6.481561,1.60397 0.255147,0.10687 2.364992,3.0533 2.555296,4.88112 0.190027,1.82509 0.08874,3.0699 -0.662772,4.1435 -0.75152,1.07358 -3.006044,3.9722 -5.045868,5.26051 -2.03982,1.28832 -7.622632,22.653 -6.763757,24.37076 0.858876,1.71774 1.610367,0.1072 1.503004,1.1808 -0.107358,1.07358 -1.180964,5.15332 -1.39568,6.87108 -0.21472,1.71775 0.214756,6.01209 -0.107324,7.19305 -0.322074,1.18096 -1.39568,4.72366 -1.39568,4.72366 l 11.165447,0.53685 2.576478,-7.7299 c 0,0 2.68414,-7.40772 3.113569,-8.05188 0.429438,-0.64417 5.904818,-0.96623 8.374084,-2.14718 0.386184,-0.1847 2.247128,-2.12197 2.271453,-0.852 0.02145,1.12014 -0.80722,4.11567 -0.499567,4.18571 0.265174,0.0604 1.984492,-5.14965 2.216279,-4.73504 0.368307,0.65881 -0.329862,3.69047 0.01675,3.54411 0.292186,-0.12338 2.360611,-5.96434 2.758609,-6.6518 0.267772,-0.46251 1.352696,3.30086 1.803794,2.38725 0.297275,-0.60207 -0.01911,-6.23822 0.174166,-5.80208 0.343977,0.77626 0.716858,0.003 0.684425,-0.37704 -0.1192,-1.39704 0.503605,1.2942 0.632411,1.077 0.156555,-0.264 -0.06427,-2.07035 0.08261,-2.35477 0.09703,-0.18785 0.302823,0.0275 0.392109,-0.17652 0.07237,-0.16541 -0.230366,-2.42098 -0.160751,-2.57954 0.365525,-0.83251 1.0931,-1.05675 1.222458,-1.72942 0.276707,-1.43889 0.612145,-4.71323 -1.730598,-7.65294 -0.154852,-0.1943 -0.01998,-0.41678 -0.100969,-1.07512 -0.20216,-1.64276 -0.836217,-2.55634 -1.213983,-3.12299 -0.858876,-1.28831 -1.034214,-0.70998 -2.322527,-2.42773 -1.288308,-1.71774 -2.14702,-0.9661 -1.9323,-2.57648 0.03143,-0.23549 0.28671,-1.26106 0.146864,-2.26862 -0.06782,-0.48855 -0.633083,-1.13463 -0.588163,-1.37497 0.07731,-0.41364 0.992454,1.03201 0.945674,0.63288 -0.07976,-0.68054 -0.815421,-1.13673 -0.917901,-1.64563 -0.06656,-0.33058 0.88395,0.20012 0.657123,-0.0852 -0.664175,-0.83545 -1.153015,-1.72183 -1.39168,-2.40373 -0.751521,-2.14718 -3.361144,-6.81149 -6.259852,-7.67036 -2.898695,-0.85888 -3.921434,-0.55656 -6.548874,-0.4027 -0.509915,0.0299 -1.43137,0.31166 -1.666814,0.30455 -0.644036,-0.0194 -2.486166,-0.49098 -3.938503,-0.58981 -0.103926,-0.007 -0.216521,-0.0115 -0.336564,-0.0132 z"
|
||||
sodipodi:nodetypes="ssccssssscccssszcsssssssscccssssssssscsssssscsscssssssscssss" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.421764;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 56.347762,114.81929 c 0.161825,0.10884 0.335437,0.26186 0.591376,0.25596 0.255976,-0.006 0.976809,-0.26479 0.967991,-0.59138 -0.009,-0.32658 -0.194171,-0.60901 -0.408951,-0.70612 -0.214776,-0.0971 -0.550714,-0.0673 -0.724035,-0.0349 -0.173348,0.0322 -0.455781,0.26752 -0.544051,0.39991 -0.08826,0.13237 -0.04418,0.56783 0.11767,0.67669 z"
|
||||
id="path19231"
|
||||
sodipodi:nodetypes="scssccs" />
|
||||
<ellipse
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.260928;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="path871"
|
||||
cx="-10.937903"
|
||||
cy="127.09028"
|
||||
rx="0.50466883"
|
||||
ry="0.28456745"
|
||||
transform="rotate(-31.358267)" />
|
||||
<path
|
||||
style="fill:none;stroke:none;stroke-width:0.14952px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 44.389921,115.02116 c 0,0 4.831171,0.75152 6.119483,2.1472 1.288312,1.39567 2.791337,2.57662 2.57662,4.40172 -0.214721,1.82511 0.429438,3.00606 -0.322074,4.07967 -0.751517,1.07358 -3.006063,3.97228 -5.045887,5.26059 -2.039829,1.28831 -7.622516,22.65282 -6.763641,24.37057 0.858874,1.71774 1.610396,0.10735 1.503033,1.18095 -0.107358,1.07358 -1.180954,5.15325 -1.395671,6.87099 -0.214721,1.71775 0.214717,6.01212 -0.107362,7.19307 -0.322075,1.18096 -1.395667,4.72381 -1.395667,4.72381 l 11.165366,0.5368 2.57662,-7.72987 c 0,0 2.683983,-7.40778 3.11342,-8.05194 0.429438,-0.64417 5.904767,-0.96624 8.374029,-2.14719 0.386179,-0.1847 2.247326,-2.12188 2.271656,-0.85191 0.02145,1.12014 -1.801065,5.44911 -1.437061,5.54899 0.375712,0.1031 2.349547,-4.82589 2.581334,-4.41129 0.368312,0.65882 -0.247513,3.75415 0.248173,3.39069 0.738355,-0.5414 2.701532,-7.49811 3.099534,-8.18557 0.267767,-0.46251 1.352722,3.30089 1.803821,2.38728 0.297271,-0.60206 -0.01908,-6.23809 0.174191,-5.80195 0.343972,0.77626 0.716747,0.003 0.684315,-0.3771 -0.1192,-1.39703 0.503735,1.29404 0.63254,1.07683 0.15656,-0.264 -0.06434,-2.07033 0.08254,-2.35476 0.09702,-0.18785 0.302732,0.0277 0.392023,-0.17632 0.07237,-0.16542 -0.230316,-2.42104 -0.160696,-2.5796 0.36552,-0.83251 1.093075,-1.05669 1.222427,-1.72935 0.276712,-1.43889 0.612072,-4.7133 -1.730671,-7.65301 -0.154852,-0.1943 0.363352,-0.6248 0.303944,-0.85138 -0.584768,-2.23024 -0.879494,-3.38266 -1.257256,-3.9493 -0.85887,-1.28831 -1.39567,-0.10736 -2.683983,-1.8251 -1.288308,-1.71775 -2.147187,-0.96625 -1.932466,-2.57663 0.03143,-0.2355 0.286691,-1.26102 0.14685,-2.26858 -0.06782,-0.48855 -0.632868,-1.1346 -0.587947,-1.37494 0.07731,-0.41364 0.992317,1.03207 0.945533,0.63294 -0.07975,-0.68054 -0.815425,-1.13672 -0.917906,-1.64562 -0.06656,-0.33058 0.88397,0.20005 0.657148,-0.0853 -0.664175,-0.83544 -1.153003,-1.72174 -1.391667,-2.40363 -0.751521,-2.14719 -3.361098,-6.8116 -6.259802,-7.67048 -2.898699,-0.85887 -3.921467,-0.55646 -6.548911,-0.4026 -1.735895,0.10165 -3.548997,-0.14554 -5.605391,-0.28547 -1.662818,-0.11314 -5.559983,0.47335 -6.204137,1.6543 -0.644159,1.18096 -0.156005,1.1706 -0.156005,1.1706 0,0 0.264793,-0.0941 0.322635,-0.0949 0.275738,-0.004 0.906961,0.85675 0.906961,0.85675 z"
|
||||
id="path3379"
|
||||
sodipodi:nodetypes="csssssssscccsssssssssssssssssssssssssssssscsc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="150mm"
|
||||
height="150mm"
|
||||
viewBox="0 0 150 150"
|
||||
version="1.1"
|
||||
id="svg2098"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
sodipodi:docname="fast_icon.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview2100"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.73673542"
|
||||
inkscape:cx="236.85572"
|
||||
inkscape:cy="257.89448"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1007"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
width="150mm" />
|
||||
<defs
|
||||
id="defs2095" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-31.274158,-78.140537)">
|
||||
<circle
|
||||
style="fill:none;fill-opacity:1;stroke:#122027;stroke-width:6.46499;stroke-linecap:round;stroke-opacity:1"
|
||||
id="path7742"
|
||||
cx="106.62331"
|
||||
cy="153.48967"
|
||||
r="70" />
|
||||
<circle
|
||||
style="fill:#343434;fill-opacity:1;stroke:none;stroke-width:6.46499;stroke-linecap:round;stroke-opacity:1"
|
||||
id="path7840"
|
||||
cx="106.80286"
|
||||
cy="151.15532"
|
||||
r="10" />
|
||||
<path
|
||||
id="rect7980"
|
||||
style="fill:#343434;fill-opacity:1;stroke-width:6.46499;stroke-linecap:round"
|
||||
d="m 156.9346,153.30987 -50.40574,1.47566 -0.0786,-6.1047 z"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:transform-center-x="-24.979325"
|
||||
inkscape:transform-center-y="-0.23024" />
|
||||
<circle
|
||||
style="fill:#122027;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path9189"
|
||||
cx="56.373787"
|
||||
cy="185.78271"
|
||||
r="3" />
|
||||
<circle
|
||||
style="fill:#122027;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle9271"
|
||||
cx="46.658237"
|
||||
cy="154.20793"
|
||||
r="3" />
|
||||
<circle
|
||||
style="fill:#122027;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle9273"
|
||||
cx="53.132095"
|
||||
cy="125.30756"
|
||||
r="3" />
|
||||
<circle
|
||||
style="fill:#122027;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle9275"
|
||||
cx="73.13047"
|
||||
cy="102.3995"
|
||||
r="3" />
|
||||
<circle
|
||||
style="fill:#122027;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle9277"
|
||||
cx="106.98246"
|
||||
cy="92.060951"
|
||||
r="3" />
|
||||
<circle
|
||||
style="fill:#122027;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle9279"
|
||||
cx="-73.287689"
|
||||
cy="-160.29289"
|
||||
r="3"
|
||||
transform="rotate(150.48856)" />
|
||||
<path
|
||||
id="circle12049"
|
||||
style="fill:none;stroke:#ff4141;stroke-width:5.66447;stroke-linecap:round;stroke-opacity:1"
|
||||
d="m 163.0663,127.86979 c 3.88122,8.04831 5.15863,16.53521 5.15863,26.06886 0,12.05511 -3.478,23.2979 -9.48531,32.77966"
|
||||
sodipodi:nodetypes="csc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.5 KiB |
|
@ -1,19 +1,19 @@
|
|||
<?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)">
|
||||
sodipodi:docname="favicon.svg"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
|
@ -21,11 +21,11 @@
|
|||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="148.31628"
|
||||
inkscape:cy="216.73575"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="148.74496"
|
||||
inkscape:cy="185.86807"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
|
@ -34,7 +34,8 @@
|
|||
inkscape:window-height="1007"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="0" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
|
@ -43,7 +44,6 @@
|
|||
<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>
|
||||
|
@ -53,14 +53,50 @@
|
|||
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" />
|
||||
style="color:#000000;fill:#ffffff;stroke-width:0.633931;-inkscape-stroke:none;fill-opacity:1"
|
||||
d="m 131.60351,157.53369 c -1.44225,0.088 -3.05509,0.225 -4.79271,0.38845 -14.0779,1.32417 -36.347368,4.38223 -42.468437,-2.85614 -6.876591,-8.13179 -5.676856,-14.32107 -3.540856,-27.51438 2.136,-13.19332 11.147817,-30.61464 22.217343,-31.845476 11.06952,-1.230833 23.00902,-0.134959 26.88493,1.149142 l 3.64693,-13.70856 c -13.8201,-3.333369 -20.25092,-4.6647 -37.975455,-2.227752 -17.724509,2.436948 -26.546029,23.899856 -28.926801,43.680146 -2.380764,19.78024 -0.597414,35.6157 5.403308,41.81224 6.000721,6.19654 41.625298,8.3939 61.081568,4.77669 z"
|
||||
id="path830"
|
||||
sodipodi:nodetypes="csszzcczzzcc" />
|
||||
<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" />
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.142752px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 110.20292,152.92929 -1.25562,1.07624 c 0,0 1.30687,1.23 1.76812,1.76812 0.46125,0.53812 2.89562,4.68937 3.10062,5.40686 0.205,0.7175 1.07625,0.87126 1.7425,1.61437 0.66625,0.74313 1.99874,1.51187 1.025,2.28062 -0.97375,0.76876 0.9225,0.33314 0.87124,-0.87124 -0.0512,-1.20438 1.79375,2.28063 0.48688,2.74187 -1.30687,0.46125 0.66624,0.48687 0.92249,0.0512 0.25625,-0.43562 0.38438,-1.22999 0.28188,-2.10124 -0.1025,-0.87126 -1.435,-2.48563 -1.7425,-2.76749 -0.3075,-0.28189 1.46062,-0.17938 1.94749,0.46124 0.48689,0.64062 0.53813,0.84562 0.17938,1.38374 -0.35875,0.53814 1.40937,-0.43562 0.56376,-1.30687 -0.84563,-0.87124 -0.20501,-0.79437 -1.38376,-1.35811 -1.17875,-0.56376 -1.30687,-0.92251 -2.30624,-0.87125 -0.99937,0.0513 -6.20124,-7.50811 -6.20124,-7.50811 z"
|
||||
id="path15574" />
|
||||
<path
|
||||
style="fill:#fefefe;fill-opacity:1;stroke:none;stroke-width:0.142752px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 118.4029,150.05928 -1.48624,0.9225 3.40812,3.81813 c 0,0 1.76812,1.28124 1.40937,2.61373 -0.35875,1.3325 -1.28125,1.81938 -1.28125,1.81938 0,0 0.12812,0.23062 0.53812,0.23062 0.41,0 0.9225,-1.33249 1.66563,-0.92249 0.74312,0.41 1.79374,1.43498 1.97312,2.07561 0.17937,0.64063 0.0513,0.79438 0.15375,0.9225 0.1025,0.12813 0.64062,0.12813 0.56374,-0.41 -0.0769,-0.53812 0.35875,-0.0256 0.46126,0.43562 0.1025,0.46125 0.43562,1.28125 0.38436,2.07562 -0.0512,0.79437 0.46126,1.56313 0.43564,0.41 -0.0256,-1.15311 0.23062,-2.40873 -0.35875,-3.45936 -0.58937,-1.05063 -0.84563,-2.45999 0.0769,-1.5375 0.9225,0.92249 1.64,1.02501 1.89625,1.69124 0.25625,0.66626 0.23062,0.82 0.53812,0.82 0.3075,0 0.12812,-0.92249 -0.43562,-1.56313 -0.56375,-0.64061 -0.58938,-1.28124 -2.20375,-2.10123 -1.61437,-0.82 -2.48562,-1.64 -4.20249,-3.20312 -1.71688,-1.56312 -3.53625,-4.63812 -3.53625,-4.63812 z"
|
||||
id="path15576" />
|
||||
<path
|
||||
style="fill:#010101;fill-opacity:1;stroke:none;stroke-width:0.142752px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 112.82046,159.21405 c 0.5033,0.8974 0.91627,1.68889 0.99558,1.96646 0.205,0.7175 1.07625,0.87126 1.7425,1.61437 0.66625,0.74313 1.99874,1.51187 1.025,2.28062 -0.97375,0.76876 0.9225,0.33314 0.87124,-0.87124 -0.0512,-1.20438 1.79375,2.28063 0.48688,2.74187 -1.30687,0.46125 0.66624,0.48687 0.92249,0.0512 0.25625,-0.43562 0.38438,-1.22999 0.28188,-2.10124 -0.1025,-0.87126 -1.435,-2.48563 -1.7425,-2.76749 -0.3075,-0.28189 1.46062,-0.17938 1.94749,0.46124 0.48689,0.64062 0.53813,0.84562 0.17938,1.38374 -0.35875,0.53814 1.40937,-0.43562 0.56376,-1.30687 -0.84563,-0.87124 -0.20501,-0.79437 -1.38376,-1.35811 -1.17875,-0.56376 -1.30687,-0.92251 -2.30624,-0.87125 -0.27545,0.0142 -0.87016,-0.54991 -1.58721,-1.37448 z"
|
||||
id="path16765"
|
||||
sodipodi:nodetypes="cssssssssssssscc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.142752px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 122.03733,158.3908 c 0.18411,3.7e-4 0.27569,0.0141 0.45904,0.0746 0.53507,0.17652 1.99911,1.67175 2.1334,2.15136 0.17937,0.64063 0.0513,0.79438 0.15375,0.92249 0.1025,0.12814 0.64062,0.12814 0.56374,-0.40999 -0.0769,-0.53812 0.35875,-0.0256 0.46126,0.43562 0.1025,0.46124 0.43562,1.28124 0.38436,2.07562 -0.0512,0.79437 0.29723,1.53789 0.43564,0.41 0.14048,-1.14481 0.23062,-2.40873 -0.35875,-3.45936 -0.58937,-1.05063 -0.84563,-2.46 0.0769,-1.5375 0.9225,0.92249 1.64,1.025 1.89625,1.69124 0.25625,0.66626 0.23062,0.82 0.53812,0.82 0.3075,0 0.12812,-0.9225 -0.43562,-1.56313 -0.56375,-0.64061 -0.44847,-1.2099 -2.06284,-2.02989 z"
|
||||
id="path16767"
|
||||
sodipodi:nodetypes="csssssssssssscc" />
|
||||
<path
|
||||
id="path7288"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.141638px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 106.80565,107.42503 c -1.70572,-0.0232 -4.98637,0.53061 -5.55843,1.57939 -0.6102,1.1187 -0.14759,1.10896 -0.14759,1.10896 0,0 0.0922,-0.0321 0.17747,-0.0582 0.0225,-0.0247 0.0235,-0.0525 0.0326,-0.072 0.0272,-0.0588 0.0921,-0.18036 0.31882,-0.31681 0.29558,-0.17787 0.82696,-0.33118 1.57672,-0.28516 h 2.3e-4 c 0.74781,0.046 2.40024,0.29154 3.87156,0.5362 1.47146,0.24468 2.72381,0.44746 2.72381,0.44746 0.0426,0.005 0.13622,0.10183 0.0812,0.25462 -0.006,0.031 -0.0615,-0.001 -0.20311,-0.0941 -0.0626,-0.0217 -1.14942,-0.25133 -2.61991,-0.49585 -1.4705,-0.24452 -3.12831,-0.50133 -3.86087,-0.53463 -0.73055,-0.0332 -1.18774,0.11185 -1.44518,0.30187 -0.14567,0.10753 -0.21612,0.20254 -0.21225,0.23968 0.004,0.0371 0.7237,0.79861 0.7237,0.79861 0,0 4.48033,0.82429 6.13989,1.51942 0.2417,0.10124 2.24032,2.89235 2.42059,4.62381 0.18001,1.72889 0.0841,2.90807 -0.62783,3.92508 -0.71191,1.01699 -2.84758,3.7628 -4.77988,4.9832 -1.93229,1.22041 -7.220799,21.45885 -6.4072,23.08605 0.8136,1.62719 1.52548,0.10155 1.42377,1.11855 -0.1017,1.01699 -1.118707,4.88167 -1.322104,6.50887 -0.203401,1.6272 0.203435,5.69517 -0.101666,6.81387 -0.305096,1.1187 -1.322107,4.47465 -1.322107,4.47465 l 10.576857,0.50856 2.44066,-7.32243 c 0,0 2.54264,-7.01721 2.94944,-7.62742 0.4068,-0.61021 5.59354,-0.91529 7.93264,-2.03399 0.36583,-0.17496 2.12867,-2.01011 2.15171,-0.80709 0.0203,1.0611 -0.76466,3.89871 -0.47323,3.96507 0.2512,0.0572 1.87988,-4.87819 2.09945,-4.48544 0.34889,0.62408 -0.31248,3.49592 0.0159,3.35728 0.27679,-0.11687 2.23617,-5.64993 2.61319,-6.30114 0.25366,-0.43813 1.28139,3.12685 1.70871,2.2614 0.2816,-0.57033 -0.0181,-5.90937 0.16498,-5.49622 0.32585,0.73534 0.67907,0.003 0.64835,-0.35717 -0.11292,-1.32339 0.47706,1.22598 0.59907,1.02023 0.1483,-0.25009 -0.0609,-1.96121 0.0783,-2.23064 0.0919,-0.17795 0.28686,0.0261 0.37144,-0.16721 0.0686,-0.1567 -0.21823,-2.29336 -0.15228,-2.44356 0.34625,-0.78862 1.03548,-1.00105 1.15801,-1.63825 0.26212,-1.36304 0.57988,-4.46478 -1.63936,-7.24952 -0.14669,-0.18406 -0.0189,-0.39481 -0.0956,-1.01845 -0.1915,-1.55615 -0.79214,-2.42158 -1.14999,-2.95835 -0.8136,-1.2204 -0.97969,-0.67256 -2.20009,-2.29975 -1.2204,-1.6272 -2.03384,-0.91518 -1.83044,-2.44066 0.0298,-0.22309 0.27159,-1.19459 0.13912,-2.14904 -0.0642,-0.46279 -0.59971,-1.07482 -0.55716,-1.30249 0.0732,-0.39183 0.94014,0.97761 0.89582,0.59952 -0.0756,-0.64466 -0.77243,-1.07681 -0.86951,-1.55888 -0.0631,-0.31315 0.83735,0.18957 0.62248,-0.0807 -0.62916,-0.7914 -1.09223,-1.63106 -1.31831,-2.27701 -0.71191,-2.034 -3.18396,-6.45242 -5.92987,-7.26602 -2.74589,-0.8136 -3.71471,-0.52722 -6.20364,-0.38147 -0.48304,0.0283 -1.35592,0.29523 -1.57895,0.2885 -0.61009,-0.0184 -2.35511,-0.4651 -3.73089,-0.55872 -0.0984,-0.007 -0.2051,-0.0109 -0.31882,-0.0125 z"
|
||||
sodipodi:nodetypes="ssccssssscccssszcsssssssscccssssssssscsssssscsscssssssscssss" />
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.399531;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 113.59181,110.64385 c 0.15329,0.1031 0.31775,0.24805 0.5602,0.24247 0.24248,-0.005 0.92532,-0.25083 0.91696,-0.56021 -0.009,-0.30937 -0.18393,-0.57691 -0.38739,-0.6689 -0.20345,-0.092 -0.52168,-0.0638 -0.68587,-0.0331 -0.16421,0.0305 -0.43175,0.25342 -0.51537,0.37884 -0.0836,0.12539 -0.0418,0.53789 0.11147,0.64101 z"
|
||||
id="path19231"
|
||||
sodipodi:nodetypes="scssccs" />
|
||||
<ellipse
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.247173;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="path871"
|
||||
cx="40.080688"
|
||||
cy="153.32861"
|
||||
rx="0.47806513"
|
||||
ry="0.26956642"
|
||||
transform="rotate(-31.358267)" />
|
||||
<path
|
||||
style="fill:none;stroke:none;stroke-width:0.141638px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 102.26433,110.83508 c 0,0 4.57649,0.7119 5.79689,2.03401 1.2204,1.3221 2.64419,2.44079 2.44079,4.16968 -0.2034,1.7289 0.4068,2.8476 -0.30509,3.86461 -0.7119,1.01698 -2.8476,3.76288 -4.77989,4.98328 -1.9323,1.2204 -7.220698,21.45867 -6.407099,23.08587 0.813599,1.62719 1.525499,0.10169 1.423799,1.1187 -0.1017,1.01699 -1.118698,4.88159 -1.322096,6.50878 -0.203402,1.6272 0.203398,5.69519 -0.101703,6.81389 -0.305097,1.1187 -1.322093,4.47479 -1.322093,4.47479 l 10.576782,0.5085 2.44079,-7.32239 c 0,0 2.5425,-7.01728 2.9493,-7.62748 0.4068,-0.61021 5.59349,-0.9153 7.93259,-2.034 0.36582,-0.17496 2.12886,-2.01002 2.1519,-0.807 0.0203,1.06109 -1.70612,5.16186 -1.3613,5.25648 0.3559,0.0977 2.22569,-4.57149 2.44526,-4.17875 0.34889,0.62408 -0.23447,3.55624 0.23509,3.21194 0.69943,-0.51286 2.55912,-7.10284 2.93614,-7.75406 0.25365,-0.43813 1.28141,3.12689 1.70873,2.26144 0.2816,-0.57033 -0.0181,-5.90925 0.16501,-5.49611 0.32584,0.73534 0.67896,0.003 0.64824,-0.35721 -0.11292,-1.32339 0.47718,1.22581 0.5992,1.02006 0.1483,-0.25009 -0.0609,-1.9612 0.0782,-2.23063 0.0919,-0.17795 0.28677,0.0263 0.37136,-0.16703 0.0686,-0.15669 -0.21818,-2.29341 -0.15223,-2.44361 0.34625,-0.78862 1.03546,-1.00099 1.15799,-1.63819 0.26212,-1.36304 0.57981,-4.46484 -1.63944,-7.24958 -0.14669,-0.18406 0.3442,-0.59186 0.28792,-0.8065 -0.55394,-2.11267 -0.83313,-3.20434 -1.19098,-3.74111 -0.81359,-1.2204 -1.3221,-0.1017 -2.54249,-1.72889 -1.2204,-1.6272 -2.034,-0.91531 -1.8306,-2.4408 0.0298,-0.22308 0.27158,-1.19455 0.13911,-2.14899 -0.0642,-0.4628 -0.59951,-1.0748 -0.55695,-1.30247 0.0732,-0.39183 0.94,0.97767 0.89568,0.59958 -0.0755,-0.64466 -0.77244,-1.07679 -0.86951,-1.55887 -0.0631,-0.31315 0.83737,0.1895 0.6225,-0.0808 -0.62916,-0.79141 -1.09222,-1.63098 -1.3183,-2.27693 -0.71191,-2.034 -3.18392,-6.45253 -5.92982,-7.26612 -2.74589,-0.8136 -3.71474,-0.52713 -6.20368,-0.38138 -1.64439,0.0963 -3.36191,-0.13787 -5.3099,-0.27042 -1.57517,-0.10718 -5.26689,0.44839 -5.87709,1.56709 -0.6102,1.1187 -0.14778,1.10889 -0.14778,1.10889 0,0 0.25083,-0.0891 0.30563,-0.0899 0.2612,-0.004 0.85915,0.81159 0.85915,0.81159 z"
|
||||
id="path3379"
|
||||
sodipodi:nodetypes="csssssssscccsssssssssssssssssssssssssssssscsc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="130mm"
|
||||
height="130mm"
|
||||
viewBox="0 0 130 130"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
sodipodi:docname="header_icon.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.73673541"
|
||||
inkscape:cx="-10.180046"
|
||||
inkscape:cy="249.75045"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1007"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
height="130mm" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<rect
|
||||
x="286.39862"
|
||||
y="431.63394"
|
||||
width="213.10229"
|
||||
height="276.89725"
|
||||
id="rect12469" />
|
||||
<rect
|
||||
x="308.11603"
|
||||
y="465.56741"
|
||||
width="176.45412"
|
||||
height="267.39587"
|
||||
id="rect3773" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-55.42222,-82.637121)">
|
||||
<path
|
||||
id="path1009"
|
||||
style="fill:#122027;fill-opacity:1;stroke-width:8.47412"
|
||||
d="M 62 0 L 62 244.93359 L 62 489.86719 L 249.05273 489.86719 L 436.10547 489.86719 L 436.10547 302.15625 L 436.10547 114.44531 L 378.94141 57.222656 L 321.7793 0 L 191.88867 0 L 62 0 z M 228.81055 227.10352 L 246.87695 227.10352 L 246.87695 286.67383 C 251.17383 280.09831 256.2194 275.18294 262.01367 271.92773 C 267.87305 268.67253 274.61133 267.04492 282.22852 267.04492 C 294.79362 267.04492 304.29883 270.95117 310.74414 278.76367 C 317.18945 286.51107 320.41211 297.93685 320.41211 313.04102 L 320.41211 379.05664 L 302.44336 379.05664 L 302.44336 313.62695 C 302.44336 303.27539 300.42513 295.52799 296.38867 290.38477 C 292.35221 285.24154 286.29753 282.66992 278.22461 282.66992 C 268.52409 282.66992 260.87435 285.76237 255.27539 291.94727 C 249.67643 298.13216 246.87695 306.56315 246.87695 317.24023 L 246.87695 379.05664 L 228.81055 379.05664 L 228.81055 227.10352 z M 168.45898 354.25195 L 189.06445 354.25195 L 189.06445 379.05664 L 168.45898 379.05664 L 168.45898 354.25195 z "
|
||||
transform="matrix(0.26458333,0,0,0.26458333,55.42222,82.637121)" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
transform="scale(0.26458333)"
|
||||
id="text3771"
|
||||
style="font-style:normal;font-weight:normal;font-size:200px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect3773);fill:#ffffff;fill-opacity:1;stroke:none" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 216 KiB |
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="128mm"
|
||||
height="128mm"
|
||||
viewBox="0 0 128 128"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
sodipodi:docname="typesafe_icon.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.0419012"
|
||||
inkscape:cx="-37.911464"
|
||||
inkscape:cy="204.43397"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1007"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
height="128mm" />
|
||||
<defs
|
||||
id="defs2">
|
||||
<inkscape:path-effect
|
||||
effect="mirror_symmetry"
|
||||
start_point="83.49758,103.2497"
|
||||
end_point="83.677144,216.55502"
|
||||
center_point="83.587362,159.90236"
|
||||
id="path-effect1148"
|
||||
is_visible="true"
|
||||
lpeversion="1.1"
|
||||
mode="free"
|
||||
discard_orig_path="false"
|
||||
fuse_paths="true"
|
||||
oposite_fuse="false"
|
||||
split_items="false"
|
||||
split_open="false" />
|
||||
</defs>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-35.610134,-93.0589)">
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:#122027;stroke-width:6.465;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 83.489092,97.893689 C 61.657927,122.25262 42.116054,116.87646 39.272073,119.55834 c -2.61289,2.46396 6.066946,69.88504 44.404869,96.86893 38.252208,-27.10527 46.718298,-94.55352 44.097618,-97.00919 -2.85247,-2.67285 -22.37721,2.76522 -44.285468,-21.524391 z"
|
||||
id="path857"
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:original-d="m 83.677144,97.68319 c -21.906891,24.60036 -41.552926,19.18557 -44.405071,21.87515 -2.615268,2.4662 6.082752,70.00779 44.5096,96.94249"
|
||||
inkscape:path-effect="#path-effect1148"
|
||||
transform="translate(16.150228,0.25394282)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="202mm"
|
||||
height="202mm"
|
||||
viewBox="0 0 202 202"
|
||||
version="1.1"
|
||||
id="svg13908"
|
||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||
sodipodi:docname="websocket_icon.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview13910"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.73673541"
|
||||
inkscape:cx="158.13004"
|
||||
inkscape:cy="343.40687"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1007"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
width="201.77914mm" />
|
||||
<defs
|
||||
id="defs13905" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-4.4986958,-69.044219)">
|
||||
<path
|
||||
style="fill:#122027;stroke-width:0.0841212;fill-opacity:1"
|
||||
d="m 69.265523,230.77706 -14.111288,-14.11148 8.832818,-8.83251 8.832808,-8.83251 L 51.116516,177.2971 29.41317,155.59363 v -12.26062 -12.26062 h 12.534076 12.534076 v 7.08736 7.08737 l 9.169279,9.16899 9.169279,9.16899 13.396176,-13.39618 13.396175,-13.39617 -9.168982,-9.16928 -9.169,-9.16932 H 55.360589 29.44692 L 16.972808,105.92001 4.4986958,93.385901 H 48.103109 91.707532 l 3.746995,3.764422 c 2.060862,2.070436 11.842143,11.897187 21.736193,21.837197 l 17.9892,18.0727 -4.40824,4.40884 -4.40823,4.40882 8.60118,8.60149 8.60117,8.60148 v 17.74937 17.74937 l -17.49722,-17.49708 -17.49722,-17.49705 -4.45581,4.45833 -4.455823,4.45834 17.460153,17.51827 17.46015,17.51826 H 116.84371 99.107375 l -8.622061,-8.62237 -8.622051,-8.62235 -4.43771,4.43711 -4.437711,4.43712 10.452037,10.45228 10.452028,10.45229 h 43.721543 43.72154 l 10.28448,10.23153 c 5.65645,5.62734 11.2686,11.2109 12.47142,12.4079 l 2.18695,2.17636 H 144.82733 83.376811 Z M 156.184,182.57579 v -24.87875 l -10.45194,-10.4522 -10.45193,-10.45218 8.83245,-8.83275 c 4.85784,-4.85802 8.87197,-8.83278 8.92029,-8.83278 0.0483,0 6.41741,6.33451 14.15356,14.07664 l 14.06572,14.07661 v 30.08708 30.08708 H 168.71808 156.184 Z"
|
||||
id="path13999" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -3,21 +3,36 @@ This page explains how to set Crow up for use with your project.
|
|||
|
||||
##Requirements
|
||||
- C++ compiler with C++14 support.
|
||||
- Continuous Testing on g++-9.3 and clang-7.0, AMD64 (x86_64) and Arm64 v8
|
||||
- Crow's CI uses g++-9.3 and clang-7.0 running on AMD64 (x86_64) and ARM64v8
|
||||
- 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.
|
||||
- **(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>
|
||||
|
||||
##Installing Requirements
|
||||
!!! note
|
||||
|
||||
The Linux requirements are for developing and compiling a Crow application. Running a built application requires the actual libraries rather than just the development headers.
|
||||
|
||||
###Ubuntu
|
||||
`sudo apt-get install libboost-all-dev`
|
||||
`sudo apt-get install build-essential libboost-all-dev`
|
||||
|
||||
###Non Debian based GNU/Linux
|
||||
Use your package manager to install the following:
|
||||
- GCC and G++ (or Clang and Clang++)
|
||||
- Boost Development headers (sometimes part of the Boost package itself)
|
||||
|
||||
|
||||
###OSX
|
||||
`brew install boost`
|
||||
|
||||
###Windows
|
||||
Download boost from [here](https://www.boost.org/) and install it
|
||||
Microsoft Visual Studio 2019 (older versions not tested)
|
||||
|
||||
##Downloading
|
||||
Either run `git clone https://github.com/crowcpp/crow.git` or download `crow_all.h` from the releases section. You can also download a zip of the project on github.
|
||||
|
@ -29,7 +44,7 @@ Either run `git clone https://github.com/crowcpp/crow.git` or download `crow_all
|
|||
<br><br>
|
||||
|
||||
##Single header file
|
||||
If you've downloaded `crow_all.h`, you can skip to step 4.
|
||||
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`.
|
||||
|
@ -44,17 +59,30 @@ If you've downloaded `crow_all.h`, you can skip to step 4.
|
|||
To build a crow Project, do the following:
|
||||
|
||||
###GCC (G++)
|
||||
- Release: `g++ main.cpp -lpthread -lboost_system -lz`.
|
||||
- Debug: `g++ main.cpp -ggdb -lpthread -lboost_system -lz -D CROW_ENABLE_DEBUG`.
|
||||
- SSL: `g++ main.cpp -lssl -lcrypto -lpthread -lboost_system -lz -D CROW_ENABLE_SSL`.
|
||||
- Release: `g++ main.cpp -lpthread -lboost_system`.
|
||||
- Debug: `g++ main.cpp -ggdb -lpthread -lboost_system -DCROW_ENABLE_DEBUG`.
|
||||
- SSL: `g++ main.cpp -lssl -lcrypto -lpthread -lboost_system -DCROW_ENABLE_SSL`.
|
||||
|
||||
###Clang
|
||||
- Release: `clang++ main.cpp -lpthread -lboost_system -lz`.
|
||||
- Debug: `clang++ main.cpp -g -lpthread -lboost_system -lz -DCROW_ENABLE_DEBUG`.
|
||||
- SSL: `clang++ main.cpp -lssl -lcrypto -lpthread -lboost_system -lz -DCROW_ENABLE_SSL`.
|
||||
- Release: `clang++ main.cpp -lpthread -lboost_system`.
|
||||
- Debug: `clang++ main.cpp -g -lpthread -lboost_system -DCROW_ENABLE_DEBUG`.
|
||||
- SSL: `clang++ main.cpp -lssl -lcrypto -lpthread -lboost_system -DCROW_ENABLE_SSL`.
|
||||
|
||||
###Microsoft Visual Studio
|
||||
***Help needed***
|
||||
###Microsoft Visual Studio 2019
|
||||
The following guide will use `example_with_all.cpp` as the Crow application for demonstration purposes.
|
||||
|
||||
1. Generate `crow_all.h` following [Single header file](#single-header-file).
|
||||
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.
|
||||
|
||||
|
||||
##building via CMake
|
||||
|
@ -86,7 +114,9 @@ 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`.
|
||||
!!!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.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
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 #CROW_MAIN` then `#!cpp #include "crow.h"` or `#!cpp #include "crow_all.h"` if you're using the single header file.
|
||||
Starting with an empty `main.cpp` file, first add `#!cpp #define CROW_MAIN` then `#!cpp #include "crow.h"` or `#!cpp #include "crow_all.h"` if you're using the single header file.
|
||||
|
||||
!!! note
|
||||
|
||||
If you're using multiple C++ source files make sure to have `#CROW_MAIN` defined only in your main source file.
|
||||
If you're using multiple C++ source files make sure to have `CROW_MAIN` defined only in your main source file.
|
||||
|
||||
##2. App declaration
|
||||
Next Create a `main()` and declare a `#!cpp crow::SimpleApp` inside, your code should look like this
|
||||
|
@ -39,6 +39,7 @@ Please note that the `port()` and `multithreaded()` methods aren't needed, Thoug
|
|||
Once you've followed all the steps above, your code should look similar to this
|
||||
|
||||
``` cpp linenums="1"
|
||||
#define CROW_MAIN //let the compiler know this is your main cpp file
|
||||
#include "crow.h"
|
||||
//#include "crow_all.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
!!!Warning
|
||||
|
||||
This feature is currently only available on the "master" branch.
|
||||
|
||||
Crow supports flask style blueprints.<br>
|
||||
A blueprint is a limited app. It cannot handle networking. But it can handle routes.<br>
|
||||
Blueprints allow developers to compartmentalize their Crow applications, making them a lot more modular.<br><br>
|
||||
|
||||
In order for a blueprint to work, it has to be registered with a Crow app before the app is run. This can be done using `#!cpp app.register_blueprint(blueprint);`.<br><br>
|
||||
|
||||
Blueprints let you do the following:<br><br>
|
||||
|
||||
### Define Routes
|
||||
You can define routes in a blueprint, similarly to how `#!cpp CROW_ROUTE(app, "/xyz")` works, you can use `#!cpp CROW_BP_ROUTE(blueprint, "/xyz")` to define a blueprint route.
|
||||
|
||||
### Define a Prefix
|
||||
Blueprints can have a prefix assigned to them. This can be done when creating a new blueprint as in `#!cpp crow::blueprint bp("prefix");`. This prefix will be applied to all routes belonging to the blueprint. truning a route such as `/crow/rocks` into `/prefix/crow/rocks`.
|
||||
|
||||
!!!Warning
|
||||
|
||||
Unlike routes, blueprint prefixes should contain no slashes.
|
||||
|
||||
|
||||
### Use a custom Static directory
|
||||
Blueprints let you define a custom static directory (relative to your working directory). This can be done by initializing a blueprint as `#!cpp crow::blueprint bp("prefix", "custom_static");`. This does not have an effect on `#!cpp set_static_file_info()`, it's only for when you want direct access to a file.
|
||||
|
||||
!!!note
|
||||
|
||||
Currently changing which endpoint the blueprint uses isn't possible, so whatever you've set in `CROW_STATIC_ENDPOINT` (default is "static") will be used. Making your final route `/prefix/static/filename`.
|
||||
|
||||
|
||||
### Use a custom Templates directory
|
||||
Similar to static directories, You can set a custom templates directory (relative to your working directory). To do this you initialize the blueprint as `#!cpp crow::blueprint bp("prefix", "custom_static", "custom_templates");`. Any routes defined for the blueprint will use that directory when calling `#!cpp crow::mustache::load("filename.html")`.
|
||||
|
||||
!!!note
|
||||
|
||||
If you want to define a custom templates directory without defining a custom static directory, you can pass the static directory as an empty string. Making your constructor `#!cpp crow::blueprint bp("prefix", "", "custom_templates");`.
|
||||
|
||||
### Define a custom Catchall route
|
||||
You can define a custom catchall route for a blueprint by calling `#!cpp CROW_BP_CATCHALL_ROUTE(blueprint)`. This causes any requests with a URL starting with `/prefix` and no route found to call the blueprint's catchall route. if no catchall route is defined, Crow will default to either the parent blueprint or the app's catchall route.
|
||||
|
||||
### Register other Blueprints
|
||||
Blueprints can also register other blueprints. This is done through `#!cpp blueprint.register_blueprint(blueprint_2);`. The child blueprint's routes become `/prefix/prefix_2/abc/xyz`.
|
|
@ -0,0 +1,19 @@
|
|||
**Introduced in: `v0.3`**<br><br>
|
||||
Crow supports Zlib compression using Gzip or Deflate algorithms.
|
||||
|
||||
## HTTP Compression
|
||||
HTTP compression is by default disabled in crow. Do the following to enable it: <br>
|
||||
1. Add `#!cpp #define CROW_ENABLE_COMPRESSION` to the top of your main source file.
|
||||
2. Call `#!cpp use_compression(crow::compression::algorithm)` on your crow app.
|
||||
3. When compiling your application, make sure that ZLIB is included as a dependency. Either through `-lz` argument or `find_package(ZLIB)` in CMake.
|
||||
|
||||
!!! note
|
||||
|
||||
step 3 is not needed for MSVC since `vcpckg.json` already includes zlib as a dependency by default
|
||||
|
||||
For the compression algorim you can use `crow::compression::algorithm::DEFLATE` or `crow::compression::algorithm::GZIP`.<br>
|
||||
And now your HTTP responses will be compressed.
|
||||
|
||||
## Websocket Compression
|
||||
Crow currently does not support Websocket compression.<br>
|
||||
Feel free to discuss the subject with us on Github if you're feeling adventurous and want to try to implement it. We appreciate all the help.
|
|
@ -1,5 +1,19 @@
|
|||
Crow has built in support for JSON data.<br><br>
|
||||
|
||||
##type
|
||||
The types of values that `rvalue and 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 or crow::json::rvalue`.<br>
|
||||
This last type means that `rvalue or wvalue` can have keys.
|
||||
|
||||
##rvalue
|
||||
JSON read value, used for taking a JSON string and parsing it into `crow::json`.<br><br>
|
||||
|
||||
|
@ -11,19 +25,18 @@ For more info on read values go [here](/reference/classcrow_1_1json_1_1rvalue.ht
|
|||
#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>
|
||||
!!!note
|
||||
|
||||
- `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>
|
||||
setting a `wvalue` to object type can be 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.
|
||||
|
||||
A JSON wvalue can be returned directly inside a route handler, this will cause 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](../routes).<br><br>
|
||||
A `wvalue` can be treated as an object or even a list (setting a value by using `json[3] = 32` for example). Please note that this will remove the data in the value if it isn't of List type.<br><br>
|
||||
|
||||
An object type `wvalue` uses `std::unordered_map` by default, if you want to have your returned `wvalue` key value pairs be sorted (using `std::map`) you can add `#!cpp #define CROW_JSON_USE_MAP` to the top of your program.<br><br>
|
||||
|
||||
A JSON `wvalue` can be returned directly inside a route handler, this will cause 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](../routes).<br><br>
|
||||
|
||||
For more info on write values go [here](../../reference/classcrow_1_1json_1_1wvalue.html).
|
||||
|
||||
!!!note
|
||||
|
||||
Crow's json exceptions can be disabled by using the `#!cpp #define CROW_JSON_NO_ERROR_CHECK` macro. This should increase the program speed with the drawback of having unexpected behavious when used incorrectly (e.g. by attempting to parse an invalid json object).
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
**Introduced in: `v0.2`**<br><br>
|
||||
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>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
A query string is the part of the url that comes after a `?` character, it is usually formatted as `key=value&otherkey=othervalue`.
|
||||
<br><br>
|
||||
|
||||
Crow supports query strings through `crow::request::url_params`. The object is of type `crow::query_string` and can has the following functions:<br>
|
||||
##get(name)
|
||||
Returns the value (as char*) based on the given key (or name). Returns `nullptr` if the key is not found.
|
||||
##pop(name)
|
||||
**Introduced in: `v0.3`**<br><br>
|
||||
Works the same as `get`, but removes the returned value.
|
||||
!!! note
|
||||
|
||||
`crow::request::url_params` is a const value, therefore for pop (also pop_list and pop_dict) to work, a copy needs to be made.
|
||||
|
||||
##get_list(name)
|
||||
A url can be `http://example.com?key[]=value1&key[]=value2&key[]=value3`. Using `get_list("key")` on such a url returns an `std::vector<std::string>` containing `[value1, value2, value3]`.<br><br>
|
||||
|
||||
`#!cpp get_list("key", false)` can be used to parse `http://example.com?key=value1&key=value2&key=value3`
|
||||
##pop_list(name)
|
||||
**Introduced in: `v0.3`**<br><br>
|
||||
Works the same as `get_list` but removes all instances of values having the given key (`use_brackets` is also available here).
|
||||
##get_dict(name)
|
||||
Returns an `std::unordered_map<std::string, std::string>` from a query string such as `?key[sub_key1]=value1&key[sub_key2]=value2&key[sub_key3]=value3`.<br>
|
||||
The key in the map is what's in the brackets (`sub_key1` for example), and the value being what's after the `=` sign (`value1`). The name passed to the function is not part of the returned value.
|
||||
##pop_dict(name)
|
||||
**Introduced in: `v0.3`**<br><br>
|
||||
Works the same as `get_dict` but removing the values from the query string.
|
||||
!!!warning
|
||||
|
||||
if your query string contains both a list and dictionary with the same key, it is best to use `pop_list` before either `get_dict` or `pop_dict`, since a map cannot contain more than one value per key, each item in the list will override the previous and only the last will remain with an empty key.
|
||||
|
||||
<br><br>
|
||||
For more information take a look [here](../../reference/classcrow_1_1query__string.html).
|
|
@ -52,6 +52,7 @@ The main return type is `std::string`. although you could also return a `crow::j
|
|||
For more information on the specific constructors for a `crow::response` go [here](../../reference/structcrow_1_1response.html).
|
||||
|
||||
##Returning custom classes
|
||||
**Introduced in: `v0.3`**<br><br>
|
||||
If you have your own class you want to return (without converting it to string and returning that), you can use the `crow::returnable` class.<br>
|
||||
to use the returnable class, you only need your class to publicly extend `crow::returnable`, add a `dump()` method that returns your class as an `std::string`, and add a constructor that has a `Content-Type` header as a string argument.<br><br>
|
||||
|
||||
|
@ -73,4 +74,5 @@ class a : public crow::returnable
|
|||
```
|
||||
|
||||
##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.
|
||||
|
|
|
@ -7,4 +7,6 @@ To enable SSL, first your application needs to define either a `.crt` and `.key`
|
|||
|
||||
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.
|
||||
!!! warning
|
||||
|
||||
If you plan on using a proxy like Nginx or Apache2, **DO NOT** use SSL in crow, instead define it in your proxy and keep the connection between the proxy and Crow non-SSL.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
**Introduced in: `v0.2`**<br><br>
|
||||
A static file is any file that resides in the server's storage.
|
||||
|
||||
Crow supports returning Static files as responses in 2 ways.
|
||||
|
|
104
docs/index.md
|
@ -1,101 +1,3 @@
|
|||
#
|
||||
<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://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.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&utm_medium=badge&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/crowcpp/crow/issues/8)
|
||||
|
||||
## Documentation
|
||||
Available [here](https://crowcpp.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/crowcpp/crow/tree/master/examples).
|
||||
|
||||
## Setting Up / Building
|
||||
Available [here](https://crowcpp.github.io/crow/getting_started/setup).
|
||||
---
|
||||
template: home.html
|
||||
---
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
{% extends "main.html" %}
|
||||
|
||||
<!-- Render hero under tabs -->
|
||||
|
||||
<!-- Content -->
|
||||
{% block content %}
|
||||
<style>
|
||||
.clogo{
|
||||
margin-left: 15rem;
|
||||
margin-right: 15rem;
|
||||
width: 30rem;
|
||||
}
|
||||
|
||||
.ccard{
|
||||
border-style: solid;
|
||||
border-width: .1rem;
|
||||
border-color: #00000080;
|
||||
border-radius: 0.5rem;
|
||||
width: 10rem;
|
||||
height: 12rem;
|
||||
box-shadow: 2px 5px 5px #00000040;
|
||||
margin-inline: 2rem;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.ccard:hover{
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.ccard__image{
|
||||
max-width: 7.5rem;
|
||||
max-height: 7.5rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: solid;
|
||||
border-width: 0.1rem;
|
||||
border-image-slice: 1;
|
||||
border-image-source: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgb(0, 0, 0) 50%, rgba(0,0,0,0) 100%);
|
||||
}
|
||||
|
||||
.ccard__text{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.csection{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ssection{
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sdescription{
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50%;
|
||||
height: 14rem;
|
||||
}
|
||||
|
||||
.scontent{
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50%;
|
||||
height: 14rem;
|
||||
}
|
||||
.highlight{
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.sbuttons{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.crow-button{
|
||||
margin: 0rem 1rem;
|
||||
}
|
||||
|
||||
code{
|
||||
border-radius: 0.3rem !important;
|
||||
}
|
||||
|
||||
.dcard{
|
||||
width: 10rem;
|
||||
height: 15rem;
|
||||
margin-inline: 2rem;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.dcard:hover{
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.dcard__image{
|
||||
max-width: 7.5rem;
|
||||
max-height: 7.5rem;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.dcard__title{
|
||||
font-size: 1.25rem;
|
||||
margin: 0px 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dcard__description{
|
||||
font-size: 0.75rem;
|
||||
margin: 0.1rem 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
<img class="clogo" style="width:30rem" alt="logo" src="/assets/crowlogo_main_color.svg">
|
||||
|
||||
<h1 style="text-align:center;">A Fast and Easy to use microframework for the web.</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
<section class="csection">
|
||||
<div class="ccard">
|
||||
<img class="ccard__image" src= /assets/fast_icon.svg>
|
||||
<p class="ccard__text">Blazingly Fast</p>
|
||||
</div>
|
||||
<div class="ccard">
|
||||
<img class="ccard__image" src= /assets/header_icon.svg>
|
||||
<p class="ccard__text">Header Only</p>
|
||||
</div>
|
||||
<div class="ccard">
|
||||
<img class="ccard__image" src= /assets/typesafe_icon.svg>
|
||||
<p class="ccard__text">Typesafe handlers</p>
|
||||
</div>
|
||||
<div class="ccard">
|
||||
<img class="ccard__image" src= /assets/websocket_icon.svg>
|
||||
<p class="ccard__text">Websocket Support</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
<section class="ssection">
|
||||
<div class="sdescription">
|
||||
<h2 style="text-align: center;">Easy to get started</h3>
|
||||
</div>
|
||||
<div class="scontent">
|
||||
<div class="highlight"><pre id="__code_0"><span></span><button class="md-clipboard md-icon" title="Copy to clipboard" data-clipboard-target="#__code_0 > code"></button><code><span class="cp">#define CROW_MAIN</span>
|
||||
<span class="cp">#include</span> <span class="cpf">"crow.h"</span><span class="cp"></span>
|
||||
|
||||
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">crow</span><span class="o">::</span><span class="n">SimpleApp</span> <span class="n">app</span><span class="p">;</span>
|
||||
|
||||
<span class="cp">CROW_ROUTE</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="s">"/"</span><span class="p">)([](){</span>
|
||||
<span class="k">return</span> <span class="s">"Hello world"</span><span class="p">;</span>
|
||||
<span class="p">});</span>
|
||||
|
||||
<span class="n">app</span><span class="p">.</span><span class="n">port</span><span class="p">(</span><span class="mi">18080</span><span class="p">).</span><span class="n">run</span><span class="p">();</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="ssection">
|
||||
<div class="scontent">
|
||||
<div class="highlight"><pre id="__code_1"><span></span><button class="md-clipboard md-icon" title="Copy to clipboard" data-clipboard-target="#__code_1 > code"></button><code><span class="cp">CROW_ROUTE</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="s">"/json"</span><span class="p">)</span>
|
||||
<span class="p">([]{</span>
|
||||
<span class="n">crow</span><span class="o">::</span><span class="n">json</span><span class="o">::</span><span class="n">wvalue</span> <span class="n">x</span><span class="p">;</span>
|
||||
<span class="n">x</span><span class="p">[</span><span class="s">"message"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"Hello, World!"</span><span class="p">;</span>
|
||||
<span class="k">return</span> <span class="n">x</span><span class="p">;</span>
|
||||
<span class="p">});</span>
|
||||
</code></pre></div>
|
||||
</div>
|
||||
<div class="sdescription">
|
||||
<h2 style="text-align: center;">JSON Support Built-in</h3>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="ssection">
|
||||
<div class="sdescription">
|
||||
<h2 style="text-align: center;">URL parameter support as well!</h3>
|
||||
</div>
|
||||
<div class="scontent">
|
||||
<div class="highlight"><pre id="__code_2"><span></span><button class="md-clipboard md-icon" title="Copy to clipboard" data-clipboard-target="#__code_2 > code"></button><code><span class="cp">CROW_ROUTE</span><span class="p">(</span><span class="n">app</span><span class="p">,</span><span class="s">"/hello/<int>"</span><span class="p">)</span>
|
||||
<span class="p">([](</span><span class="kt">int</span> <span class="n">count</span><span class="p">){</span>
|
||||
<span class="k">return</span> <span class="n">crow</span><span class="o">::</span><span class="n">response</span><span class="p">(std::to_string(count));</span></span>
|
||||
<span class="p">});</span>
|
||||
</code></pre></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1 style="text-align:center;">Support Crow</h1>
|
||||
<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">
|
||||
<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>
|
||||
<a href="https://gitter.im/crowfork/community" title="Crow - OpenCollective" class="md-button crow-button">Chat with us</a>
|
||||
</dev>
|
||||
|
||||
<hr>
|
||||
<h1 style="text-align:center;">Get Crow</h1>
|
||||
<h3 style="text-align:center;">Crow is everywhere, you just need to grab it!<h3>
|
||||
|
||||
<section class="csection">
|
||||
|
||||
<div class="dcard">
|
||||
<a href="https://github.com/CrowCpp/Crow/releases/latest">
|
||||
<img class="dcard__image" src="/assets/pkg_logos/ubuntu.png">
|
||||
<p class="dcard__title">.deb file</p>
|
||||
<p class="dcard__description">for Ubuntu/Debian based systems</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="dcard">
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="dcard">
|
||||
<a href="https://vcpkg.io">
|
||||
<img class="dcard__image" src="/assets/pkg_logos/vcpkg.png">
|
||||
<p class="dcard__title">VCPKG</p>
|
||||
<p class="dcard__description">for Windows systems</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="dcard">
|
||||
<a href="https://conan.io/center/crowcpp-crow">
|
||||
<img class="dcard__image" src="/assets/pkg_logos/conan.png">
|
||||
<p class="dcard__title">Conan Center</p>
|
||||
<p class="dcard__description">for developers using the conan package manager</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="dcard">
|
||||
<a href="https://github.com/CrowCpp/Crow/releases/latest">
|
||||
<img class="dcard__image" src="/assets/pkg_logos/github.png">
|
||||
<p class="dcard__title">Header File</p>
|
||||
<p class="dcard__description">Download Crow directly from github</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<hr>
|
||||
<h1 style="text-align:center;">Learn Crow</h1>
|
||||
<h3 style="text-align:center;">The 1000 mile journey begins with a single step. Get started by installing Crow and building you first application. Or go through the guides if you're stuck somewhere.<h3>
|
||||
|
||||
<dev class="sbuttons">
|
||||
<a href="/getting_started/setup/" title="Get Started" class="md-button crow-button">Get Started</a>
|
||||
<a href="/guides/app/" title="Guides" class="md-button crow-button">Guides</a>
|
||||
<a href="/reference/index.html" title="API Reference" class="md-button crow-button">API Reference</a>
|
||||
</dev>
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block site_nav %}{% endblock %}
|
||||
{% block footer %}
|
||||
|
||||
<footer class="md-footer">
|
||||
<!-- 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>
|
||||
|
||||
<!-- Social links -->
|
||||
{% include "partials/social.html" %}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{% endblock %}
|
|
@ -0,0 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block extrahead %}
|
||||
<meta property="og:title" content="CrowCpp"/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="A Fast and Easy to use microframework for the web."/>
|
||||
<meta property="og:image" content="/assets/og_img.png" />
|
||||
<meta property="og:url" content="https://crowcpp.org">
|
||||
{% endblock %}
|
|
@ -0,0 +1,150 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- Header -->
|
||||
<header class="md-header" data-md-component="header">
|
||||
<nav
|
||||
class="md-header__inner md-grid"
|
||||
aria-label="{{ lang.t('header.title') }}"
|
||||
>
|
||||
|
||||
<!-- Link to home -->
|
||||
<a
|
||||
href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}"
|
||||
title="{{ config.site_name | e }}"
|
||||
class="md-header__button md-logo"
|
||||
aria-label="{{ config.site_name }}"
|
||||
data-md-component="logo"
|
||||
>
|
||||
{% include "partials/logo.html" %}
|
||||
</a>
|
||||
|
||||
<!-- Button to open drawer -->
|
||||
<label class="md-header__button md-icon" for="__drawer">
|
||||
{% include ".icons/material/menu" ~ ".svg" %}
|
||||
</label>
|
||||
|
||||
<!-- Header title -->
|
||||
<div class="md-header__title" data-md-component="header-title">
|
||||
<div class="md-header__ellipsis">
|
||||
<div class="md-header__topic">
|
||||
<span class="md-ellipsis">
|
||||
{{ config.site_name }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="md-header__topic" data-md-component="header-topic">
|
||||
<span class="md-ellipsis">
|
||||
{% if page and page.meta and page.meta.title %}
|
||||
{{ page.meta.title }}
|
||||
{% else %}
|
||||
{{ page.title }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Color palette -->
|
||||
{% if not config.theme.palette is mapping %}
|
||||
<form class="md-header__option" data-md-component="palette">
|
||||
{% for option in config.theme.palette %}
|
||||
{% set primary = option.primary | replace(" ", "-") | lower %}
|
||||
{% set accent = option.accent | replace(" ", "-") | lower %}
|
||||
<input
|
||||
class="md-option"
|
||||
data-md-color-media="{{ option.media }}"
|
||||
data-md-color-scheme="{{ option.scheme }}"
|
||||
data-md-color-primary="{{ primary }}"
|
||||
data-md-color-accent="{{ accent }}"
|
||||
{% if option.toggle %}
|
||||
aria-label="{{ option.toggle.name }}"
|
||||
{% else %}
|
||||
aria-hidden="true"
|
||||
{% endif %}
|
||||
type="radio"
|
||||
name="__palette"
|
||||
id="__palette_{{ loop.index }}"
|
||||
/>
|
||||
{% if option.toggle %}
|
||||
<label
|
||||
class="md-header__button md-icon"
|
||||
title="{{ option.toggle.name }}"
|
||||
for="__palette_{{ loop.index0 or loop.length }}"
|
||||
hidden
|
||||
>
|
||||
{% include ".icons/" ~ option.toggle.icon ~ ".svg" %}
|
||||
</label>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<!-- Site language selector -->
|
||||
{% if config.extra.alternate %}
|
||||
<div class="md-header__option"></form>
|
||||
<div class="md-select">
|
||||
{% set icon = config.theme.icon.alternate or "material/translate" %}
|
||||
<button
|
||||
class="md-header__button md-icon"
|
||||
aria-label="{{ lang.t('select.language.title') }}"
|
||||
>
|
||||
{% include ".icons/" ~ icon ~ ".svg" %}
|
||||
</button>
|
||||
<div class="md-select__inner">
|
||||
<ul class="md-select__list">
|
||||
{% for alt in config.extra.alternate %}
|
||||
<li class="md-select__item">
|
||||
<a
|
||||
href="{{ alt.link | url }}"
|
||||
hreflang="{{ alt.lang }}"
|
||||
class="md-select__link"
|
||||
>
|
||||
{{ alt.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Button to open search modal -->
|
||||
{% if "search" in config["plugins"] %}
|
||||
<label class="md-header__button md-icon" for="__search">
|
||||
{% include ".icons/material/magnify.svg" %}
|
||||
</label>
|
||||
|
||||
<!-- Search interface -->
|
||||
{% include "partials/search.html" %}
|
||||
{% endif %}
|
||||
|
||||
<div class="md-header__source">
|
||||
<a class="md-source" href="https://opencollective.com/crow" style="padding-left:2.4rem;"><img style="border-radius: 5px" alt="Open Collective" src="https://img.shields.io/opencollective/all/crow?label=Support%20Crow&color=important&labelColor=122027&logo=opencollective&style=for-the-badge"></a>
|
||||
</div>
|
||||
|
||||
<!-- Repository information -->
|
||||
{% if config.repo_url %}
|
||||
<div class="md-header__source">
|
||||
{% include "partials/source.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</nav>
|
||||
</header>
|
|
@ -1,6 +1,31 @@
|
|||
|
||||
:root {
|
||||
--md-primary-fg-color: #161616;
|
||||
--md-accent-fg-color: #396A97;
|
||||
--md-typeset-a-color: var(--md-accent-fg-color);
|
||||
--md-primary-fg-color: #24404f;
|
||||
--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-hl-punctuation-color: #fff !important;
|
||||
}
|
||||
|
||||
.md-typeset code {
|
||||
background-color: #2e3639;
|
||||
color: #afafaf;
|
||||
}
|
||||
|
||||
.linenos {
|
||||
background-color: #2e3639 !important;
|
||||
color: #afafaf !important;
|
||||
}
|
||||
|
||||
.highlight .p {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.highlight .o {
|
||||
color: #afafaf;
|
||||
}
|
||||
|
||||
.highlight .n {
|
||||
color: #afafaf;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.md-header__source {
|
||||
margin-left: 0px;
|
||||
width: autho;
|
||||
min-width: 9.6rem;
|
||||
}
|
||||
.code {
|
||||
border-radius: 5px;
|
||||
}
|
|
@ -65,9 +65,21 @@ else ()
|
|||
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
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#define CROW_MAIN
|
||||
#include "crow.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
crow::SimpleApp app;
|
||||
|
||||
crow::Blueprint bp("bp_prefix", "cstat", "ctemplate");
|
||||
|
||||
|
||||
crow::Blueprint sub_bp("bp2", "csstat", "cstemplate");
|
||||
|
||||
CROW_BP_ROUTE(sub_bp, "/")
|
||||
([]() {
|
||||
return "Hello world!";
|
||||
});
|
||||
|
||||
/* CROW_BP_ROUTE(bp, "/templatt")
|
||||
([]() {
|
||||
crow::mustache::context ctxdat;
|
||||
ctxdat["messg"] = "fifty five!!";
|
||||
|
||||
auto page = crow::mustache::load("indks.html");
|
||||
|
||||
return page.render(ctxdat);
|
||||
});
|
||||
*/
|
||||
CROW_BP_CATCHALL_ROUTE(sub_bp)([](){return "WRONG!!";});
|
||||
|
||||
|
||||
bp.register_blueprint(sub_bp);
|
||||
app.register_blueprint(bp);
|
||||
|
||||
app.loglevel(crow::LogLevel::DEBUG).port(18080).run();
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#define CROW_MAIN
|
||||
#define CROW_ENABLE_COMPRESSION
|
||||
#include "crow.h"
|
||||
#include "crow/compression.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#define CROW_MAIN
|
||||
#define CROW_JSON_USE_MAP
|
||||
#include "crow.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
crow::SimpleApp app;
|
||||
|
||||
// simple json response using a map
|
||||
// To see it in action enter {ip}:18080/json
|
||||
// it shoud show amessage before zmessage despite adding zmessage first.
|
||||
CROW_ROUTE(app, "/json")
|
||||
([]{
|
||||
crow::json::wvalue x;
|
||||
x["zmessage"] = "Hello, World!";
|
||||
x["amessage"] = "Hello, World2!";
|
||||
return x;
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/json-initializer-list-constructor")
|
||||
([] {
|
||||
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. */
|
||||
{"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 . */
|
||||
{"tenth", true} /* stores a bool hence json::type::True . */
|
||||
});
|
||||
});
|
||||
|
||||
// enables all log
|
||||
app.loglevel(crow::LogLevel::Debug);
|
||||
|
||||
app.port(18080)
|
||||
.multithreaded()
|
||||
.run();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
//#define CROW_STATIC_DRIECTORY "alternative_directory/"
|
||||
//#define CROW_STATIC_ENDPOINT "/alternative_endpoint/<path>"
|
||||
//#define CROW_DISABLE_STATIC_DIR
|
||||
#define CROW_MAIN
|
||||
#include "crow.h"
|
||||
|
||||
|
|
|
@ -44,31 +44,32 @@ int main()
|
|||
|
||||
app.get_middleware<ExampleMiddleware>().setMessage("hello");
|
||||
|
||||
app.route_dynamic("/")
|
||||
CROW_ROUTE(app, "/")
|
||||
.name("hello")
|
||||
([]{
|
||||
return "Hello World!";
|
||||
});
|
||||
|
||||
app.route_dynamic("/about")
|
||||
CROW_ROUTE(app, "/about")
|
||||
([](){
|
||||
return "About Crow example.";
|
||||
});
|
||||
|
||||
// a request to /path should be forwarded to /path/
|
||||
app.route_dynamic("/path/")
|
||||
CROW_ROUTE(app, "/path/")
|
||||
([](){
|
||||
return "Trailing slash test case..";
|
||||
});
|
||||
|
||||
// simple json response
|
||||
app.route_dynamic("/json")
|
||||
CROW_ROUTE(app, "/json")
|
||||
([]{
|
||||
crow::json::wvalue x;
|
||||
x["message"] = "Hello, World!";
|
||||
return x;
|
||||
});
|
||||
|
||||
app.route_dynamic("/hello/<int>")
|
||||
CROW_ROUTE(app, "/hello/<int>")
|
||||
([](int count){
|
||||
if (count > 100)
|
||||
return crow::response(400);
|
||||
|
@ -77,7 +78,7 @@ int main()
|
|||
return crow::response(os.str());
|
||||
});
|
||||
|
||||
app.route_dynamic("/add/<int>/<int>")
|
||||
CROW_ROUTE(app, "/add/<int>/<int>")
|
||||
([](crow::response& res, int a, int b){
|
||||
std::ostringstream os;
|
||||
os << a+b;
|
||||
|
@ -92,7 +93,7 @@ int main()
|
|||
//});
|
||||
|
||||
// more json example
|
||||
app.route_dynamic("/add_json")
|
||||
CROW_ROUTE(app, "/add_json")
|
||||
.methods(crow::HTTPMethod::Post)
|
||||
([](const crow::request& req){
|
||||
auto x = crow::json::load(req.body);
|
||||
|
|
|
@ -42,7 +42,7 @@ int main()
|
|||
return crow::response(os.str());
|
||||
});
|
||||
|
||||
// example which uses only response as a paramter wihtout
|
||||
// example which uses only response as a paramter without
|
||||
// request being a parameter.
|
||||
CROW_ROUTE(app,"/add/<int>/<int>")
|
||||
([](crow::response& res, int a, int b){
|
||||
|
|
|
@ -8,7 +8,7 @@ int main()
|
|||
{
|
||||
crow::SimpleApp app;
|
||||
|
||||
std::mutex mtx;;
|
||||
std::mutex mtx;
|
||||
std::unordered_set<crow::websocket::connection*> users;
|
||||
|
||||
CROW_ROUTE(app, "/ws")
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <thread>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "crow/version.h"
|
||||
#include "crow/settings.h"
|
||||
#include "crow/logging.h"
|
||||
#include "crow/utility.h"
|
||||
|
@ -18,15 +19,19 @@
|
|||
#include "crow/http_request.h"
|
||||
#include "crow/http_server.h"
|
||||
#include "crow/dumb_timer_queue.h"
|
||||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
#include "crow/compression.h"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CROW_MSVC_WORKAROUND
|
||||
#define CROW_ROUTE(app, url) app.route_dynamic(url)
|
||||
#define CROW_BP_ROUTE(blueprint, url) blueprint.new_rule_dynamic(url)
|
||||
#else
|
||||
#define CROW_ROUTE(app, url) app.route<crow::black_magic::get_parameter_tag(url)>(url)
|
||||
#define CROW_BP_ROUTE(blueprint, url) blueprint.new_rule_tagged<crow::black_magic::get_parameter_tag(url)>(url)
|
||||
#endif
|
||||
#define CROW_CATCHALL_ROUTE(app) app.catchall_route()
|
||||
#define CROW_BP_CATCHALL_ROUTE(blueprint) blueprint.catchall_rule()
|
||||
|
||||
namespace crow
|
||||
{
|
||||
|
@ -119,7 +124,7 @@ namespace crow
|
|||
return *this;
|
||||
}
|
||||
|
||||
///Set the server name (default Crow/0.2)
|
||||
///Set the server name
|
||||
self_t& server_name(std::string server_name)
|
||||
{
|
||||
server_name_ = server_name;
|
||||
|
@ -157,12 +162,18 @@ namespace crow
|
|||
/// crow::LogLevel::Warning (2)<br>
|
||||
/// crow::LogLevel::Error (3)<br>
|
||||
/// crow::LogLevel::Critical (4)<br>
|
||||
self_t& loglevel(crow::LogLevel level)
|
||||
self_t& loglevel(LogLevel level)
|
||||
{
|
||||
crow::logger::setLogLevel(level);
|
||||
return *this;
|
||||
}
|
||||
|
||||
self_t& register_blueprint(Blueprint& blueprint)
|
||||
{
|
||||
router_.register_blueprint(blueprint);
|
||||
return *this;
|
||||
}
|
||||
|
||||
///Set a custom duration and function to run on every tick
|
||||
template <typename Duration, typename Func>
|
||||
self_t& tick(Duration d, Func f) {
|
||||
|
@ -171,6 +182,7 @@ namespace crow
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
self_t& use_compression(compression::algorithm algorithm)
|
||||
{
|
||||
comp_algorithm_ = algorithm;
|
||||
|
@ -182,14 +194,41 @@ namespace crow
|
|||
{
|
||||
return comp_algorithm_;
|
||||
}
|
||||
|
||||
#endif
|
||||
///A wrapper for `validate()` in the router
|
||||
|
||||
///
|
||||
///Go through the rules, upgrade them if possible, and add them to the list of rules
|
||||
void validate()
|
||||
{
|
||||
router_.validate();
|
||||
if (!validated_)
|
||||
{
|
||||
|
||||
#ifndef CROW_DISABLE_STATIC_DIR
|
||||
route<crow::black_magic::get_parameter_tag(CROW_STATIC_ENDPOINT)>(CROW_STATIC_ENDPOINT)
|
||||
([](crow::response& res, std::string file_path_partial)
|
||||
{
|
||||
res.set_static_file_info(CROW_STATIC_DIRECTORY + file_path_partial);
|
||||
res.end();
|
||||
});
|
||||
|
||||
for (auto& bp : router_.blueprints())
|
||||
{
|
||||
if (!bp->static_dir().empty())
|
||||
{
|
||||
bp->new_rule_tagged<crow::black_magic::get_parameter_tag(CROW_STATIC_ENDPOINT)>(CROW_STATIC_ENDPOINT)
|
||||
([bp](crow::response& res, std::string file_path_partial)
|
||||
{
|
||||
res.set_static_file_info(bp->static_dir() + '/' + file_path_partial);
|
||||
res.end();
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
router_.validate();
|
||||
validated_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
///Notify anything using `wait_for_server_start()` to proceed
|
||||
|
@ -203,15 +242,8 @@ namespace crow
|
|||
///Run the server
|
||||
void run()
|
||||
{
|
||||
#ifndef CROW_DISABLE_STATIC_DIR
|
||||
route<crow::black_magic::get_parameter_tag(CROW_STATIC_ENDPOINT)>(CROW_STATIC_ENDPOINT)
|
||||
([](crow::response& res, std::string file_path_partial)
|
||||
{
|
||||
res.set_static_file_info(CROW_STATIC_DIRECTORY + file_path_partial);
|
||||
res.end();
|
||||
});
|
||||
|
||||
validate();
|
||||
#endif
|
||||
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
if (use_ssl_)
|
||||
|
@ -358,10 +390,14 @@ namespace crow
|
|||
private:
|
||||
uint16_t port_ = 80;
|
||||
uint16_t concurrency_ = 1;
|
||||
std::string server_name_ = "Crow/0.2";
|
||||
bool validated_ = false;
|
||||
std::string server_name_ = std::string("Crow/") + VERSION;
|
||||
std::string bindaddr_ = "0.0.0.0";
|
||||
Router router_;
|
||||
|
||||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
compression::algorithm comp_algorithm_;
|
||||
#endif
|
||||
|
||||
std::chrono::milliseconds tick_interval_;
|
||||
std::function<void()> tick_function_;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace crow
|
||||
{
|
||||
enum class HTTPMethod
|
||||
enum class HTTPMethod : char
|
||||
{
|
||||
#ifndef DELETE
|
||||
DELETE = 0,
|
||||
|
@ -69,7 +69,7 @@ namespace crow
|
|||
return "invalid";
|
||||
}
|
||||
|
||||
enum class ParamType
|
||||
enum class ParamType : char
|
||||
{
|
||||
INT,
|
||||
UINT,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <zlib.h>
|
||||
|
||||
// http://zlib.net/manual.html
|
||||
|
||||
namespace crow
|
||||
{
|
||||
namespace compression
|
||||
|
@ -95,3 +95,5 @@ namespace crow
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -263,7 +263,7 @@ namespace crow
|
|||
req_ = std::move(parser_.to_request());
|
||||
request& req = req_;
|
||||
|
||||
req.remoteIpAddress = adaptor_.remote_endpoint().address().to_string();
|
||||
req.remote_ip_address = adaptor_.remote_endpoint().address().to_string();
|
||||
|
||||
if (parser_.check_version(1, 0))
|
||||
{
|
||||
|
@ -357,7 +357,7 @@ namespace crow
|
|||
decltype(*middlewares_)>
|
||||
(*middlewares_, ctx_, req_, res);
|
||||
}
|
||||
|
||||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
std::string accept_encoding = req_.get_header_value("Accept-Encoding");
|
||||
if (!accept_encoding.empty() && res.compressed)
|
||||
{
|
||||
|
@ -381,7 +381,7 @@ namespace crow
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
//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)
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace crow
|
|||
query_string url_params; ///< The parameters associated with the request. (everything after the `?`)
|
||||
ci_map headers;
|
||||
std::string body;
|
||||
std::string remoteIpAddress; ///< The IP address from which the request was sent.
|
||||
std::string remote_ip_address; ///< The IP address from which the request was sent.
|
||||
|
||||
void* middleware_context{};
|
||||
boost::asio::io_service* io_service{};
|
||||
|
|
|
@ -28,7 +28,10 @@ namespace crow
|
|||
int code{200}; ///< The Status code for the response.
|
||||
std::string body; ///< The actual payload containing the response data.
|
||||
ci_map headers; ///< HTTP headers.
|
||||
|
||||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
bool compressed = true; ///< If compression is enabled and this is false, the individual response will not be compressed.
|
||||
#endif
|
||||
bool is_head_response = false; ///< Whether this is a response to a HEAD request.
|
||||
bool manual_length_header = false; ///< Whether Crow should automatically add a "Content-Length" header.
|
||||
|
||||
|
@ -84,6 +87,7 @@ namespace crow
|
|||
code = r.code;
|
||||
headers = std::move(r.headers);
|
||||
completed_ = r.completed_;
|
||||
file_info = std::move(r.file_info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -195,7 +199,9 @@ namespace crow
|
|||
void set_static_file_info(std::string path){
|
||||
file_info.path = path;
|
||||
file_info.statResult = stat(file_info.path.c_str(), &file_info.statbuf);
|
||||
#ifdef CROW_ENABLE_COMPRESSION
|
||||
compressed = false;
|
||||
#endif
|
||||
if (file_info.statResult == 0)
|
||||
{
|
||||
std::size_t last_dot = path.find_last_of(".");
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "crow/version.h"
|
||||
#include "crow/http_connection.h"
|
||||
#include "crow/logging.h"
|
||||
#include "crow/dumb_timer_queue.h"
|
||||
|
@ -26,7 +27,7 @@ namespace crow
|
|||
class Server
|
||||
{
|
||||
public:
|
||||
Server(Handler* handler, std::string bindaddr, uint16_t port, std::string server_name = "Crow/0.2", std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, typename Adaptor::context* adaptor_ctx = nullptr)
|
||||
Server(Handler* handler, std::string bindaddr, uint16_t port, std::string server_name = std::string("Crow/") + VERSION, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, typename Adaptor::context* adaptor_ctx = nullptr)
|
||||
: acceptor_(io_service_, tcp::endpoint(boost::asio::ip::address::from_string(bindaddr), port)),
|
||||
signals_(io_service_, SIGINT, SIGTERM),
|
||||
tick_timer_(io_service_),
|
||||
|
@ -121,7 +122,7 @@ namespace crow
|
|||
init_count ++;
|
||||
while(1)
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
if (io_service_pool_[i]->run() == 0)
|
||||
{
|
||||
|
@ -135,7 +136,7 @@ namespace crow
|
|||
}
|
||||
}));
|
||||
|
||||
if (tick_function_ && tick_interval_.count() > 0)
|
||||
if (tick_function_ && tick_interval_.count() > 0)
|
||||
{
|
||||
tick_timer_.expires_from_now(boost::posix_time::milliseconds(tick_interval_.count()));
|
||||
tick_timer_.async_wait([this](const boost::system::error_code& ec)
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
//#define CROW_JSON_NO_ERROR_CHECK
|
||||
//#define CROW_JSON_USE_MAP
|
||||
|
||||
#include <string>
|
||||
#ifdef CROW_JSON_USE_MAP
|
||||
#include <map>
|
||||
#else
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
@ -36,7 +41,7 @@ namespace crow
|
|||
inline void escape(const std::string& str, std::string& ret)
|
||||
{
|
||||
ret.reserve(ret.size() + str.size()+str.size()/4);
|
||||
for(unsigned char c:str)
|
||||
for(auto c:str)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
|
@ -295,6 +300,28 @@ namespace crow
|
|||
return static_cast<int>(i());
|
||||
}
|
||||
|
||||
///Return any json value (not object or list) as a string.
|
||||
explicit operator std::string() const
|
||||
{
|
||||
#ifndef CROW_JSON_NO_ERROR_CHECK
|
||||
if (t() == type::Object || t() == type::List)
|
||||
throw std::runtime_error("json type container");
|
||||
#endif
|
||||
switch (t())
|
||||
{
|
||||
case type::String:
|
||||
return std::string(s());
|
||||
case type::Null:
|
||||
return std::string("null");
|
||||
case type::True:
|
||||
return std::string("true");
|
||||
case type::False:
|
||||
return std::string("false");
|
||||
default:
|
||||
return std::string(start_, end_-start_);
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of the JSON value.
|
||||
type t() const
|
||||
{
|
||||
|
@ -382,6 +409,22 @@ namespace crow
|
|||
return detail::r_string{start_, end_};
|
||||
}
|
||||
|
||||
///The list or object value
|
||||
std::vector<rvalue> lo()
|
||||
{
|
||||
#ifndef CROW_JSON_NO_ERROR_CHECK
|
||||
if (t() != type::Object && t() != type::List)
|
||||
throw std::runtime_error("value is not a container");
|
||||
#endif
|
||||
std::vector<rvalue> ret;
|
||||
ret.reserve(lsize_);
|
||||
for (uint32_t i = 0; i<lsize_; i++)
|
||||
{
|
||||
ret.emplace_back(l_[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Convert escaped string character to their original form ("\\n" -> '\n').
|
||||
void unescape() const
|
||||
{
|
||||
|
@ -448,6 +491,7 @@ namespace crow
|
|||
}
|
||||
}
|
||||
|
||||
///Check if the json object has the passed string as a key.
|
||||
bool has(const char* str) const
|
||||
{
|
||||
return has(std::string(str));
|
||||
|
@ -590,6 +634,21 @@ namespace crow
|
|||
{
|
||||
return (option_&error_bit)!=0;
|
||||
}
|
||||
|
||||
std::vector<std::string> keys()
|
||||
{
|
||||
#ifndef CROW_JSON_NO_ERROR_CHECK
|
||||
if (t() != type::Object)
|
||||
throw std::runtime_error("value is not an object");
|
||||
#endif
|
||||
std::vector<std::string> ret;
|
||||
ret.reserve(lsize_);
|
||||
for (uint32_t i = 0; i<lsize_; i++)
|
||||
{
|
||||
ret.emplace_back(std::string(l_[i].key()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
bool is_cached() const
|
||||
{
|
||||
|
@ -1091,6 +1150,7 @@ namespace crow
|
|||
}
|
||||
|
||||
// TODO caching key to speed up (flyweight?)
|
||||
// I have no idea how flyweight could apply here, but maybe some speedup can happen if we stopped checking type since decode_string returns a string anyway
|
||||
auto key = t.s();
|
||||
|
||||
ws_skip();
|
||||
|
@ -1164,22 +1224,78 @@ namespace crow
|
|||
class wvalue : public returnable
|
||||
{
|
||||
friend class crow::mustache::template_t;
|
||||
|
||||
public:
|
||||
using object_type =
|
||||
#ifdef CROW_JSON_USE_MAP
|
||||
std::map<std::string, wvalue>;
|
||||
#else
|
||||
std::unordered_map<std::string, wvalue>;
|
||||
#endif
|
||||
|
||||
public:
|
||||
type t() const { return t_; }
|
||||
private:
|
||||
type t_{type::Null}; ///< The type of the value.
|
||||
num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_ is a number.
|
||||
union {
|
||||
union number {
|
||||
double d;
|
||||
int64_t si;
|
||||
uint64_t ui {};
|
||||
uint64_t ui;
|
||||
|
||||
public:
|
||||
constexpr number() noexcept : ui() {} /* default constructor initializes unsigned integer. */
|
||||
constexpr number(std::uint64_t value) noexcept : ui(value) {}
|
||||
constexpr number(std::int64_t value) noexcept : si(value) {}
|
||||
constexpr number(double value) noexcept : d(value) {}
|
||||
} num; ///< Value if type is a number.
|
||||
std::string s; ///< Value if type is a string.
|
||||
std::unique_ptr<std::vector<wvalue>> l; ///< Value if type is a list.
|
||||
#ifdef CROW_JSON_USE_MAP
|
||||
std::unique_ptr<std::map<std::string, wvalue>> o;
|
||||
#else
|
||||
std::unique_ptr<std::unordered_map<std::string, wvalue>> o; ///< Value if type is a JSON object.
|
||||
public:
|
||||
#endif
|
||||
|
||||
public:
|
||||
wvalue() : returnable("application/json") {}
|
||||
|
||||
wvalue(std::nullptr_t) : returnable("application/json"), t_(type::Null) {}
|
||||
|
||||
wvalue(bool value) : returnable("application/json"), t_(value ? type::True : type::False) {}
|
||||
|
||||
wvalue(std::uint8_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
|
||||
wvalue(std::uint16_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
|
||||
wvalue(std::uint32_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
|
||||
wvalue(std::uint64_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
|
||||
|
||||
wvalue(std::int8_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
|
||||
wvalue(std::int16_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
|
||||
wvalue(std::int32_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
|
||||
wvalue(std::int64_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
|
||||
|
||||
wvalue(float value) : returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
|
||||
wvalue(double value) : returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
|
||||
|
||||
wvalue(char const* value) : returnable("application/json"), t_(type::String), s(value) {}
|
||||
|
||||
wvalue(std::string const& value) : returnable("application/json"), t_(type::String), s(value) {}
|
||||
wvalue(std::string&& value) : returnable("application/json"), t_(type::String), s(std::move(value)) {}
|
||||
|
||||
wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list) : returnable("application/json"), t_(type::Object), o(new object_type(initializer_list)) {}
|
||||
|
||||
wvalue(object_type const& value) : returnable("application/json"), t_(type::Object), o(new object_type(value)) {}
|
||||
wvalue(object_type&& value) : returnable("application/json"), t_(type::Object), o(new object_type(std::move(value))) {}
|
||||
|
||||
wvalue(std::vector<wvalue>& r) : returnable("application/json")
|
||||
{
|
||||
t_ = type::List;
|
||||
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
|
||||
l->reserve(r.size());
|
||||
for(auto it = r.begin(); it != r.end(); ++it)
|
||||
l->emplace_back(*it);
|
||||
}
|
||||
|
||||
/// Create a write value from a read value (useful for editing JSON strings).
|
||||
wvalue(const rvalue& r) : returnable("application/json")
|
||||
{
|
||||
|
@ -1209,16 +1325,55 @@ namespace crow
|
|||
l->emplace_back(*it);
|
||||
return;
|
||||
case type::Object:
|
||||
o = std::unique_ptr<
|
||||
std::unordered_map<std::string, wvalue>
|
||||
>(
|
||||
new std::unordered_map<std::string, wvalue>{});
|
||||
#ifdef CROW_JSON_USE_MAP
|
||||
o = std::unique_ptr<std::map<std::string, wvalue>>(new std::map<std::string, wvalue>{});
|
||||
#else
|
||||
o = std::unique_ptr<std::unordered_map<std::string, wvalue>>(new std::unordered_map<std::string, wvalue>{});
|
||||
#endif
|
||||
for(auto it = r.begin(); it != r.end(); ++it)
|
||||
o->emplace(it->key(), *it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wvalue(const wvalue& r) : returnable("application/json")
|
||||
{
|
||||
t_ = r.t();
|
||||
switch(r.t())
|
||||
{
|
||||
case type::Null:
|
||||
case type::False:
|
||||
case type::True:
|
||||
return;
|
||||
case type::Number:
|
||||
nt = r.nt;
|
||||
if (nt == num_type::Floating_point)
|
||||
num.d = r.num.d;
|
||||
else if (nt == num_type::Signed_integer)
|
||||
num.si = r.num.si;
|
||||
else
|
||||
num.ui = r.num.ui;
|
||||
return;
|
||||
case type::String:
|
||||
s = r.s;
|
||||
return;
|
||||
case type::List:
|
||||
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
|
||||
l->reserve(r.size());
|
||||
for(auto it = r.l->begin(); it != r.l->end(); ++it)
|
||||
l->emplace_back(*it);
|
||||
return;
|
||||
case type::Object:
|
||||
#ifdef CROW_JSON_USE_MAP
|
||||
o = std::unique_ptr<std::map<std::string, wvalue>>(new std::map<std::string, wvalue>{});
|
||||
#else
|
||||
o = std::unique_ptr<std::unordered_map<std::string, wvalue>>(new std::unordered_map<std::string, wvalue>{});
|
||||
#endif
|
||||
o->insert(r.o->begin(), r.o->end());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wvalue(wvalue&& r) : returnable("application/json")
|
||||
{
|
||||
*this = std::move(r);
|
||||
|
@ -1394,6 +1549,42 @@ namespace crow
|
|||
return *this;
|
||||
}
|
||||
|
||||
wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
|
||||
{
|
||||
if (t_ != type::Object) {
|
||||
reset();
|
||||
t_ = type::Object;
|
||||
o = std::unique_ptr<object_type>(new object_type(initializer_list));
|
||||
} else {
|
||||
(*o) = initializer_list;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
wvalue& operator=(object_type const& value)
|
||||
{
|
||||
if (t_ != type::Object) {
|
||||
reset();
|
||||
t_ = type::Object;
|
||||
o = std::unique_ptr<object_type>(new object_type(value));
|
||||
} else {
|
||||
(*o) = value;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
wvalue& operator=(object_type&& value)
|
||||
{
|
||||
if (t_ != type::Object) {
|
||||
reset();
|
||||
t_ = type::Object;
|
||||
o = std::unique_ptr<object_type>(new object_type(std::move(value)));
|
||||
} else {
|
||||
(*o) = std::move(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
wvalue& operator[](unsigned index)
|
||||
{
|
||||
if (t_ != type::List)
|
||||
|
@ -1421,10 +1612,11 @@ namespace crow
|
|||
reset();
|
||||
t_ = type::Object;
|
||||
if (!o)
|
||||
o = std::unique_ptr<
|
||||
std::unordered_map<std::string, wvalue>
|
||||
>(
|
||||
new std::unordered_map<std::string, wvalue>{});
|
||||
#ifdef CROW_JSON_USE_MAP
|
||||
o = std::unique_ptr<std::map<std::string, wvalue>>(new std::map<std::string, wvalue>{});
|
||||
#else
|
||||
o = std::unique_ptr<std::unordered_map<std::string, wvalue>>(new std::unordered_map<std::string, wvalue>{});
|
||||
#endif
|
||||
return (*o)[str];
|
||||
}
|
||||
|
||||
|
@ -1440,6 +1632,15 @@ namespace crow
|
|||
return result;
|
||||
}
|
||||
|
||||
/// If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
|
||||
std::size_t size() const
|
||||
{
|
||||
if (t_ != type::List)
|
||||
return 1;
|
||||
return l->size();
|
||||
}
|
||||
|
||||
/// Returns an estimated size of the value in bytes.
|
||||
size_t estimate_length() const
|
||||
{
|
||||
switch(t_)
|
||||
|
@ -1482,14 +1683,14 @@ namespace crow
|
|||
|
||||
private:
|
||||
|
||||
inline void dump_string(const std::string& str, std::string& out)
|
||||
inline void dump_string(const std::string& str, std::string& out) const
|
||||
{
|
||||
out.push_back('"');
|
||||
escape(str, out);
|
||||
out.push_back('"');
|
||||
}
|
||||
|
||||
inline void dump_internal(const wvalue& v, std::string& out)
|
||||
inline void dump_internal(const wvalue& v, std::string& out) const
|
||||
{
|
||||
switch(v.t_)
|
||||
{
|
||||
|
@ -1565,7 +1766,7 @@ namespace crow
|
|||
}
|
||||
|
||||
public:
|
||||
std::string dump()
|
||||
std::string dump() const
|
||||
{
|
||||
std::string ret;
|
||||
ret.reserve(estimate_length());
|
||||
|
|
|
@ -14,11 +14,13 @@ namespace crow
|
|||
enum class LogLevel
|
||||
{
|
||||
#ifndef ERROR
|
||||
#ifndef DEBUG
|
||||
DEBUG = 0,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
CRITICAL,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Debug = 0,
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include "crow/http_request.h"
|
||||
#include "crow/http_response.h"
|
||||
|
||||
namespace crow
|
||||
{
|
||||
|
||||
struct UTF8
|
||||
{
|
||||
struct context
|
||||
{
|
||||
};
|
||||
|
||||
void before_handle(request& /*req*/, response& /*res*/, context& /*ctx*/)
|
||||
{
|
||||
}
|
||||
|
||||
void after_handle(request& /*req*/, response& res, context& ctx)
|
||||
{
|
||||
if (get_header_value(res.headers, "Content-Type").empty())
|
||||
{
|
||||
res.set_header("Content-Type", "text/plain; charset=utf-8");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -45,7 +45,7 @@ namespace crow
|
|||
}
|
||||
|
||||
///Represent all parts as a string (**does not include message headers**)
|
||||
std::string dump() override
|
||||
std::string dump() const override
|
||||
{
|
||||
std::stringstream str;
|
||||
std::string delimiter = dd + boundary;
|
||||
|
@ -60,7 +60,7 @@ namespace crow
|
|||
}
|
||||
|
||||
///Represent an individual part as a string
|
||||
std::string dump(int part_)
|
||||
std::string dump(int part_) const
|
||||
{
|
||||
std::stringstream str;
|
||||
part item = parts[part_];
|
||||
|
@ -92,7 +92,7 @@ namespace crow
|
|||
|
||||
private:
|
||||
|
||||
std::string get_boundary(const std::string& header)
|
||||
std::string get_boundary(const std::string& header) const
|
||||
{
|
||||
size_t found = header.find("boundary=");
|
||||
if (found)
|
||||
|
@ -181,14 +181,14 @@ namespace crow
|
|||
}
|
||||
}
|
||||
|
||||
inline std::string trim (std::string& string, const char& excess = '"')
|
||||
inline std::string trim (std::string& string, const char& excess = '"') const
|
||||
{
|
||||
if (string.length() > 1 && string[0] == excess && string[string.length()-1] == excess)
|
||||
return string.substr(1, string.length()-2);
|
||||
return string;
|
||||
}
|
||||
|
||||
inline std::string pad (std::string& string, const char& padding = '"')
|
||||
inline std::string pad (std::string& string, const char& padding = '"') const
|
||||
{
|
||||
return (padding + string + padding);
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ inline char * qs_k2v(const char * key, char * const * qs_kv, int qs_kv_size, int
|
|||
}
|
||||
#endif // _qsSORTING
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline boost::optional<std::pair<std::string, std::string>> qs_dict_name2kv(const char * dict_name, char * const * qs_kv, int qs_kv_size, int nth = 0)
|
||||
|
@ -362,16 +362,41 @@ namespace crow
|
|||
|
||||
}
|
||||
|
||||
/// Get a value from a name, used for `?name=value`.
|
||||
///
|
||||
/// Note: this method returns the value of the first occurrence of the key only, to return all occurrences, see \ref get_list().
|
||||
char* get (const std::string& name) const
|
||||
{
|
||||
char* ret = qs_k2v(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<char*> get_list (const std::string& name) const
|
||||
/// Works similar to \ref get() except it removes the item from the query string.
|
||||
char* pop (const std::string& name)
|
||||
{
|
||||
char* ret = get(name);
|
||||
if (ret != nullptr)
|
||||
{
|
||||
for (unsigned int i = 0; i<key_value_pairs_.size(); i++)
|
||||
{
|
||||
std::string str_item(key_value_pairs_[i]);
|
||||
if (str_item.substr(0, name.size()+1) == name+'=')
|
||||
{
|
||||
key_value_pairs_.erase(key_value_pairs_.begin()+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Returns a list of values, passed as `?name[]=value1&name[]=value2&...name[]=valuen` with n being the size of the list.
|
||||
///
|
||||
/// Note: Square brackets in the above example are controlled by `use_brackets` boolean (true by default). If set to false, the example becomes `?name=value1,name=value2...name=valuen`
|
||||
std::vector<char*> get_list (const std::string& name, bool use_brackets = true) const
|
||||
{
|
||||
std::vector<char*> ret;
|
||||
std::string plus = name + "[]";
|
||||
std::string plus = name + (use_brackets ? "[]" : "");
|
||||
char* element = nullptr;
|
||||
|
||||
int count = 0;
|
||||
|
@ -385,6 +410,29 @@ namespace crow
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Similar to \ref get_list() but it removes the
|
||||
std::vector<char*> pop_list (const std::string& name, bool use_brackets = true)
|
||||
{
|
||||
std::vector<char*> ret = get_list(name, use_brackets);
|
||||
if (!ret.empty())
|
||||
{
|
||||
for (unsigned int i = 0; i<key_value_pairs_.size(); i++)
|
||||
{
|
||||
std::string str_item(key_value_pairs_[i]);
|
||||
if ((use_brackets ? (str_item.substr(0, name.size()+3) == name+"[]=") : (str_item.substr(0, name.size()+1) == name+'=')))
|
||||
{
|
||||
key_value_pairs_.erase(key_value_pairs_.begin()+i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Works similar to \ref get_list() except the brackets are mandatory must not be empty.
|
||||
///
|
||||
/// For example calling `get_dict(yourname)` on `?yourname[sub1]=42&yourname[sub2]=84` would give a map containing `{sub1 : 42, sub2 : 84}`.
|
||||
///
|
||||
/// if your query string has both empty brackets and ones with a key inside, use pop_list() to get all the values without a key before running this method.
|
||||
std::unordered_map<std::string, std::string> get_dict (const std::string& name) const
|
||||
{
|
||||
std::unordered_map<std::string, std::string> ret;
|
||||
|
@ -400,6 +448,35 @@ namespace crow
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Works the same as \ref get_dict() but removes the values from the query string.
|
||||
std::unordered_map<std::string, std::string> pop_dict (const std::string& name)
|
||||
{
|
||||
std::unordered_map<std::string, std::string> ret = get_dict(name);
|
||||
if (!ret.empty())
|
||||
{
|
||||
for (unsigned int i = 0; i<key_value_pairs_.size(); i++)
|
||||
{
|
||||
std::string str_item(key_value_pairs_[i]);
|
||||
if (str_item.substr(0, name.size()+1) == name+'[')
|
||||
{
|
||||
key_value_pairs_.erase(key_value_pairs_.begin()+i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> keys() const
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
for (auto element: key_value_pairs_)
|
||||
{
|
||||
std::string str_element(element);
|
||||
ret.emplace_back(str_element.substr(0, str_element.find('=')));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string url_;
|
||||
std::vector<char*> key_value_pairs_;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace crow
|
|||
struct returnable
|
||||
{
|
||||
std::string content_type;
|
||||
virtual std::string dump() = 0;
|
||||
virtual std::string dump() const = 0;
|
||||
|
||||
returnable(std::string ctype) : content_type {ctype}
|
||||
{}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
namespace crow {
|
||||
|
||||
#ifdef CROW_MAIN
|
||||
char VERSION[] = "master";
|
||||
#else
|
||||
extern char VERSION[];
|
||||
#endif
|
||||
}
|
|
@ -194,7 +194,7 @@ namespace crow
|
|||
buf[0] += opcode;
|
||||
if (size < 126)
|
||||
{
|
||||
buf[1] += size;
|
||||
buf[1] += static_cast<char>(size);
|
||||
return {buf, buf+2};
|
||||
}
|
||||
else if (size < 0x10000)
|
||||
|
@ -408,10 +408,10 @@ namespace crow
|
|||
break;
|
||||
case WebSocketReadState::Payload:
|
||||
{
|
||||
size_t to_read = buffer_.size();
|
||||
auto to_read = static_cast<std::uint64_t>(buffer_.size());
|
||||
if (remaining_length_ < to_read)
|
||||
to_read = remaining_length_;
|
||||
adaptor_.socket().async_read_some( boost::asio::buffer(buffer_, to_read),
|
||||
adaptor_.socket().async_read_some(boost::asio::buffer(buffer_, static_cast<std::size_t>(to_read)),
|
||||
[this](const boost::system::error_code& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
is_reading = false;
|
||||
|
|
BIN
logo55.png
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
13
mkdocs.yml
|
@ -1,9 +1,9 @@
|
|||
site_name: Crow
|
||||
|
||||
# Repository
|
||||
repo_name: crowcpp/crow
|
||||
repo_url: https://github.com/crowcpp/crow
|
||||
site_url: https://crowcpp.github.io/crow
|
||||
repo_name: CrowCpp/Crow
|
||||
repo_url: https://github.com/CrowCpp/Crow
|
||||
site_url: https://crowcpp.org
|
||||
edit_uri: ""
|
||||
|
||||
theme:
|
||||
|
@ -16,6 +16,7 @@ theme:
|
|||
logo: 'assets/favicon.svg'
|
||||
icon:
|
||||
repo: fontawesome/brands/github-square
|
||||
custom_dir: docs/overrides
|
||||
|
||||
markdown_extensions:
|
||||
- admonition
|
||||
|
@ -37,9 +38,12 @@ nav:
|
|||
- JSON: guides/json.md
|
||||
- Templating (Mustache): guides/templating.md
|
||||
- Multipart: guides/multipart.md
|
||||
- Query Strings: guides/query-string.md
|
||||
- Middleware: guides/middleware.md
|
||||
- SSL: guides/ssl.md
|
||||
- Static Files: guides/static.md
|
||||
- Blueprints: guides/blueprints.md
|
||||
- Compression: guides/compression.md
|
||||
- Websockets: guides/websockets.md
|
||||
- Writing Tests: guides/testing.md
|
||||
- Server setup:
|
||||
|
@ -58,5 +62,6 @@ extra:
|
|||
extra_css:
|
||||
- 'stylesheets/colors.css'
|
||||
- 'stylesheets/latofonts.css'
|
||||
- 'stylesheets/extra.css'
|
||||
|
||||
copyright: 'Copyright © 2020 Farook Al-Sammarraie'
|
||||
copyright: 'Copyright © 2020-2021 CrowCpp'
|
||||
|
|
|
@ -18,6 +18,8 @@ output_path = sys.argv[2]
|
|||
|
||||
middlewares = [x.rsplit(sep, 1)[-1][:-2] for x in glob(pt.join(header_path, ('crow'+sep+'middlewares'+sep+'*.h*')))]
|
||||
|
||||
with open(header_path+'/../LICENSE', 'r') as file:
|
||||
lsc = '/*' + file.read() + '*/'
|
||||
|
||||
middlewares_actual = []
|
||||
if len(sys.argv) > 3:
|
||||
|
@ -83,7 +85,7 @@ for x in edges:
|
|||
assert order.index(x) < order.index(y), 'cyclic include detected'
|
||||
|
||||
print(order)
|
||||
build = []
|
||||
build = [lsc]
|
||||
for header in order:
|
||||
d = open(pt.join(header_path, header)).read()
|
||||
build.append(re_depends.sub(lambda x: '\n', d))
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: {} VERSION".format(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
version = str(sys.argv[1])
|
||||
|
||||
releasePath = os.path.join(os.path.dirname(__file__), "..", "build_release")
|
||||
|
||||
if os.path.exists(releasePath):
|
||||
shutil.rmtree(releasePath)
|
||||
|
||||
os.mkdir(releasePath)
|
||||
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/constexpr char VERSION\\[\\] = \"master\";/constexpr char VERSION\\[\\] = \"{}\";/g' crow_all.h".format(version))
|
||||
os.system("cpack")
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 41 KiB |
|
@ -1,4 +1,5 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#define CROW_ENABLE_COMPRESSION
|
||||
#define CROW_LOG_LEVEL 0
|
||||
#define CROW_MAIN
|
||||
#include <sys/stat.h>
|
||||
|
@ -665,6 +666,24 @@ TEST_CASE("json_read_unescaping")
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("json_read_string")
|
||||
{
|
||||
auto x = json::load(R"({"message": 53})");
|
||||
int y (x["message"]);
|
||||
std::string z(x["message"]);
|
||||
CHECK(53 == y);
|
||||
CHECK("53" == z);
|
||||
}
|
||||
|
||||
TEST_CASE("json_read_container")
|
||||
{
|
||||
auto x = json::load(R"({"first": 53, "second": "55", "third": [5,6,7,8,3,2,1,4]})");
|
||||
CHECK(std::vector<std::string>({"first", "second", "third"}) == x.keys());
|
||||
CHECK(53 == int(x.lo()[0]));
|
||||
CHECK("55" == std::string(x.lo()[1]));
|
||||
CHECK (8 == int(x.lo()[2].lo()[3]));
|
||||
}
|
||||
|
||||
TEST_CASE("json_write")
|
||||
{
|
||||
json::wvalue x;
|
||||
|
@ -700,11 +719,12 @@ TEST_CASE("json_write")
|
|||
CHECK(R"({"scores":[1,2,3]})" == y.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json_copy_r_to_w_to_r")
|
||||
TEST_CASE("json_copy_r_to_w_to_w_to_r")
|
||||
{
|
||||
json::rvalue r = json::load(
|
||||
R"({"smallint":2,"bigint":2147483647,"fp":23.43,"fpsc":2.343e1,"str":"a string","trueval":true,"falseval":false,"nullval":null,"listval":[1,2,"foo","bar"],"obj":{"member":23,"other":"baz"}})");
|
||||
json::wvalue w{r};
|
||||
json::wvalue v{r};
|
||||
json::wvalue w(v);
|
||||
json::rvalue x =
|
||||
json::load(w.dump()); // why no copy-ctor wvalue -> rvalue?
|
||||
CHECK(2 == x["smallint"]);
|
||||
|
@ -726,6 +746,294 @@ TEST_CASE("json_copy_r_to_w_to_r")
|
|||
CHECK("other" == x["obj"]["other"].key());
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(bool)") {
|
||||
CHECK(json::wvalue(true).t() == json::type::True);
|
||||
CHECK(json::wvalue(false).t() == json::type::False);
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::uint8_t)") {
|
||||
std::uint8_t i = 42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::uint16_t)") {
|
||||
std::uint16_t i = 42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::uint32_t)") {
|
||||
std::uint32_t i = 42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::uint64_t)") {
|
||||
std::uint64_t i = 42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::int8_t)") {
|
||||
std::int8_t i = -42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "-42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::int16_t)") {
|
||||
std::int16_t i = -42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "-42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::int32_t)") {
|
||||
std::int32_t i = -42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "-42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::int64_t)") {
|
||||
std::int64_t i = -42;
|
||||
json::wvalue value = i;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "-42");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(float)") {
|
||||
float f = 4.2;
|
||||
json::wvalue value = f;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "4.2");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(double)") {
|
||||
double d = 4.2;
|
||||
json::wvalue value = d;
|
||||
|
||||
CHECK(value.t() == json::type::Number);
|
||||
CHECK(value.dump() == "4.2");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(char const*)") {
|
||||
char const* str = "Hello world!";
|
||||
json::wvalue value = str;
|
||||
|
||||
CHECK(value.t() == json::type::String);
|
||||
CHECK(value.dump() == "\"Hello world!\"");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::string const&)") {
|
||||
std::string str = "Hello world!";
|
||||
json::wvalue value = str;
|
||||
|
||||
CHECK(value.t() == json::type::String);
|
||||
CHECK(value.dump() == "\"Hello world!\"");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::string&&)") {
|
||||
std::string str = "Hello world!";
|
||||
json::wvalue value = std::move(str);
|
||||
|
||||
CHECK(value.t() == json::type::String);
|
||||
CHECK(value.dump() == "\"Hello world!\"");
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::initializer_list<std::pair<std::string const, json::wvalue>>)") {
|
||||
json::wvalue integer, number, truth, lie, null;
|
||||
integer = 2147483647;
|
||||
number = 23.43;
|
||||
truth = true;
|
||||
lie = false;
|
||||
|
||||
/* initializer-list constructor. */
|
||||
json::wvalue value({
|
||||
{"integer", integer},
|
||||
{"number", number},
|
||||
{"truth", truth},
|
||||
{"lie", lie},
|
||||
{"null", null}
|
||||
});
|
||||
|
||||
CHECK(value["integer"].dump() == integer.dump());
|
||||
CHECK(value["number"].dump() == number.dump());
|
||||
CHECK(value["truth"].dump() == truth.dump());
|
||||
CHECK(value["lie"].dump() == lie.dump());
|
||||
CHECK(value["null"].dump() == null.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::[unordered_]map<std::string, json::wvalue> const&)") {
|
||||
json::wvalue integer, number, truth, lie, null;
|
||||
integer = 2147483647;
|
||||
number = 23.43;
|
||||
truth = true;
|
||||
lie = false;
|
||||
|
||||
json::wvalue::object_type map({
|
||||
{"integer", integer},
|
||||
{"number", number},
|
||||
{"truth", truth},
|
||||
{"lie", lie},
|
||||
{"null", null}
|
||||
});
|
||||
|
||||
json::wvalue value(map); /* copy-constructor. */
|
||||
|
||||
CHECK(value["integer"].dump() == integer.dump());
|
||||
CHECK(value["number"].dump() == number.dump());
|
||||
CHECK(value["truth"].dump() == truth.dump());
|
||||
CHECK(value["lie"].dump() == lie.dump());
|
||||
CHECK(value["null"].dump() == null.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::wvalue(std::[unordered_]map<std::string, json::wvalue>&&)") {
|
||||
json::wvalue integer, number, truth, lie, null;
|
||||
integer = 2147483647;
|
||||
number = 23.43;
|
||||
truth = true;
|
||||
lie = false;
|
||||
|
||||
json::wvalue::object_type map = {{
|
||||
{"integer", integer},
|
||||
{"number", number},
|
||||
{"truth", truth},
|
||||
{"lie", lie},
|
||||
{"null", null}
|
||||
}};
|
||||
|
||||
json::wvalue value(std::move(map)); /* move constructor. */
|
||||
// json::wvalue value = std::move(map); /* move constructor. */
|
||||
|
||||
CHECK(value["integer"].dump() == integer.dump());
|
||||
CHECK(value["number"].dump() == number.dump());
|
||||
CHECK(value["truth"].dump() == truth.dump());
|
||||
CHECK(value["lie"].dump() == lie.dump());
|
||||
CHECK(value["null"].dump() == null.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::operator=(std::initializer_list<std::pair<std::string const, json::wvalue>>)") {
|
||||
json::wvalue integer, number, truth, lie, null;
|
||||
integer = 2147483647;
|
||||
number = 23.43;
|
||||
truth = true;
|
||||
lie = false;
|
||||
|
||||
json::wvalue value;
|
||||
/* initializer-list assignment. */
|
||||
value = {
|
||||
{"integer", integer},
|
||||
{"number", number},
|
||||
{"truth", truth},
|
||||
{"lie", lie},
|
||||
{"null", null}
|
||||
};
|
||||
|
||||
CHECK(value["integer"].dump() == integer.dump());
|
||||
CHECK(value["number"].dump() == number.dump());
|
||||
CHECK(value["truth"].dump() == truth.dump());
|
||||
CHECK(value["lie"].dump() == lie.dump());
|
||||
CHECK(value["null"].dump() == null.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::operator=(std::[unordered_]map<std::string, json::wvalue> const&)") {
|
||||
json::wvalue integer, number, truth, lie, null;
|
||||
integer = 2147483647;
|
||||
number = 23.43;
|
||||
truth = true;
|
||||
lie = false;
|
||||
|
||||
json::wvalue::object_type map({
|
||||
{"integer", integer},
|
||||
{"number", number},
|
||||
{"truth", truth},
|
||||
{"lie", lie},
|
||||
{"null", null}
|
||||
});
|
||||
|
||||
json::wvalue value;
|
||||
value = map; /* copy assignment. */
|
||||
|
||||
CHECK(value["integer"].dump() == integer.dump());
|
||||
CHECK(value["number"].dump() == number.dump());
|
||||
CHECK(value["truth"].dump() == truth.dump());
|
||||
CHECK(value["lie"].dump() == lie.dump());
|
||||
CHECK(value["null"].dump() == null.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json::wvalue::operator=(std::[unordered_]map<std::string, json::wvalue>&&)") {
|
||||
json::wvalue integer, number, truth, lie, null;
|
||||
integer = 2147483647;
|
||||
number = 23.43;
|
||||
truth = true;
|
||||
lie = false;
|
||||
|
||||
json::wvalue::object_type map({
|
||||
{"integer", integer},
|
||||
{"number", number},
|
||||
{"truth", truth},
|
||||
{"lie", lie},
|
||||
{"null", null}
|
||||
});
|
||||
|
||||
json::wvalue value;
|
||||
value = std::move(map); /* move assignment. */
|
||||
|
||||
CHECK(value["integer"].dump() == integer.dump());
|
||||
CHECK(value["number"].dump() == number.dump());
|
||||
CHECK(value["truth"].dump() == truth.dump());
|
||||
CHECK(value["lie"].dump() == lie.dump());
|
||||
CHECK(value["null"].dump() == null.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("json_vector")
|
||||
{//TODO probably make constructors for the same values as = operator
|
||||
json::wvalue a;
|
||||
json::wvalue b;
|
||||
json::wvalue c;
|
||||
json::wvalue d;
|
||||
json::wvalue e;
|
||||
json::wvalue f;
|
||||
json::wvalue g;
|
||||
json::wvalue h;
|
||||
a = 5;
|
||||
b = 6;
|
||||
c = 7;
|
||||
d = 8;
|
||||
e = 4;
|
||||
f = 3;
|
||||
g = 2;
|
||||
h = 1;
|
||||
std::vector<json::wvalue> nums;
|
||||
nums.emplace_back(a);
|
||||
nums.emplace_back(b);
|
||||
nums.emplace_back(c);
|
||||
nums.emplace_back(d);
|
||||
nums.emplace_back(e);
|
||||
nums.emplace_back(f);
|
||||
nums.emplace_back(g);
|
||||
nums.emplace_back(h);
|
||||
json::wvalue x(nums);
|
||||
|
||||
CHECK(8 == x.size());
|
||||
CHECK("[5,6,7,8,4,3,2,1]" == x.dump());
|
||||
}
|
||||
|
||||
TEST_CASE("template_basic")
|
||||
{
|
||||
auto t = crow::mustache::compile(R"---(attack of {{name}})---");
|
||||
|
@ -1130,9 +1438,15 @@ TEST_CASE("simple_url_params")
|
|||
c.receive(asio::buffer(buf, 2048));
|
||||
c.close();
|
||||
|
||||
CHECK(string(last_url_params.get("hello")) == "world");
|
||||
CHECK(string(last_url_params.get("left")) == "right");
|
||||
CHECK(string(last_url_params.get("up")) == "down");
|
||||
query_string mutable_params(last_url_params);
|
||||
|
||||
CHECK(string(mutable_params.get("hello")) == "world");
|
||||
CHECK(string(mutable_params.get("left")) == "right");
|
||||
CHECK(string(mutable_params.get("up")) == "down");
|
||||
|
||||
std::string z = mutable_params.pop("left");
|
||||
CHECK(z == "right");
|
||||
CHECK(mutable_params.get("left") == nullptr);
|
||||
}
|
||||
// check multiple value, multiple types
|
||||
sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n";
|
||||
|
@ -1165,8 +1479,7 @@ TEST_CASE("simple_url_params")
|
|||
CHECK(string(last_url_params.get_list("tmnt")[0]) == "leonardo");
|
||||
}
|
||||
// check multiple array value
|
||||
sendmsg =
|
||||
"GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n";
|
||||
sendmsg = "GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n";
|
||||
{
|
||||
asio::ip::tcp::socket c(is);
|
||||
|
||||
|
@ -1180,6 +1493,25 @@ TEST_CASE("simple_url_params")
|
|||
CHECK(string(last_url_params.get_list("tmnt")[0]) == "leonardo");
|
||||
CHECK(string(last_url_params.get_list("tmnt")[1]) == "donatello");
|
||||
CHECK(string(last_url_params.get_list("tmnt")[2]) == "raphael");
|
||||
CHECK(last_url_params.pop_list("tmnt").size() == 3);
|
||||
CHECK(last_url_params.get_list("tmnt").size() == 0);
|
||||
}
|
||||
// check dictionary value
|
||||
sendmsg = "GET /params?kees[one]=vee1&kees[two]=vee2&kees[three]=vee3\r\n\r\n";
|
||||
{
|
||||
asio::ip::tcp::socket c(is);
|
||||
|
||||
c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
|
||||
c.send(asio::buffer(sendmsg));
|
||||
c.receive(asio::buffer(buf, 2048));
|
||||
c.close();
|
||||
|
||||
CHECK(last_url_params.get_dict("kees").size() == 3);
|
||||
CHECK(string(last_url_params.get_dict("kees")["one"]) == "vee1");
|
||||
CHECK(string(last_url_params.get_dict("kees")["two"]) == "vee2");
|
||||
CHECK(string(last_url_params.get_dict("kees")["three"]) == "vee3");
|
||||
CHECK(last_url_params.pop_dict("kees").size() == 3);
|
||||
CHECK(last_url_params.get_dict("kees").size() == 0);
|
||||
}
|
||||
app.stop();
|
||||
}
|
||||
|
@ -1341,14 +1673,15 @@ TEST_CASE("stream_response")
|
|||
|
||||
SimpleApp app;
|
||||
|
||||
CROW_ROUTE(app, "/test")
|
||||
([](const crow::request&, crow::response& res)
|
||||
{
|
||||
std::string keyword_ = "hello";
|
||||
std::string key_response;
|
||||
for (unsigned int i = 0; i<250000; i++)
|
||||
key_response += keyword_;
|
||||
|
||||
std::string keyword_ = "hello";
|
||||
std::string key_response;
|
||||
for (unsigned int i = 0; i<250000; i++)
|
||||
key_response += keyword_;
|
||||
|
||||
CROW_ROUTE(app, "/test")
|
||||
([&key_response](const crow::request&, crow::response& res)
|
||||
{
|
||||
res.body = key_response;
|
||||
res.end();
|
||||
});
|
||||
|
@ -1356,7 +1689,7 @@ TEST_CASE("stream_response")
|
|||
app.validate();
|
||||
|
||||
//running the test on a separate thread to allow the client to sleep
|
||||
std::thread runTest([&app](){
|
||||
std::thread runTest([&app, &key_response](){
|
||||
|
||||
auto _ = async(launch::async,
|
||||
[&] { app.bindaddr(LOCALHOST_ADDRESS).port(45451).run(); });
|
||||
|
@ -1370,9 +1703,6 @@ TEST_CASE("stream_response")
|
|||
{
|
||||
asio::streambuf b;
|
||||
|
||||
std::string keyword_ = "hello";
|
||||
std::string key_response;
|
||||
|
||||
asio::ip::tcp::socket c(is);
|
||||
c.connect(asio::ip::tcp::endpoint(
|
||||
asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
|
||||
|
@ -1382,10 +1712,6 @@ TEST_CASE("stream_response")
|
|||
static char buf[2048];
|
||||
c.receive(asio::buffer(buf, 2048));
|
||||
|
||||
//creating the string to compare against
|
||||
for (unsigned int i = 0; i<250000; i++)
|
||||
key_response += keyword_;
|
||||
|
||||
//"hello" is 5 bytes, (5*250000)/16384 = 76.2939
|
||||
for (unsigned int i = 0; i<76; i++)
|
||||
{
|
||||
|
@ -1810,3 +2136,115 @@ TEST_CASE("catchall")
|
|||
CHECK(404 == res.code);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("blueprint")
|
||||
{
|
||||
SimpleApp app;
|
||||
crow::Blueprint bp("bp_prefix", "cstat", "ctemplate");
|
||||
crow::Blueprint bp_not_sub("bp_prefix_second");
|
||||
crow::Blueprint sub_bp("bp2", "csstat", "cstemplate");
|
||||
crow::Blueprint sub_sub_bp("bp3");
|
||||
|
||||
CROW_BP_ROUTE(sub_bp, "/hello")
|
||||
([]() {
|
||||
return "Hello world!";
|
||||
});
|
||||
|
||||
CROW_BP_ROUTE(bp_not_sub, "/hello")
|
||||
([]() {
|
||||
return "Hello world!";
|
||||
});
|
||||
|
||||
CROW_BP_ROUTE(sub_sub_bp, "/hi")
|
||||
([]() {
|
||||
return "Hi world!";
|
||||
});
|
||||
|
||||
CROW_BP_CATCHALL_ROUTE(sub_bp)([](){return response(200, "WRONG!!");});
|
||||
|
||||
app. register_blueprint(bp);
|
||||
app. register_blueprint(bp_not_sub);
|
||||
bp. register_blueprint(sub_bp);
|
||||
sub_bp.register_blueprint(sub_sub_bp);
|
||||
|
||||
app.validate();
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix/bp2/hello";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK("Hello world!" == res.body);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix_second/hello";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK("Hello world!" == res.body);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix/bp2/bp3/hi";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK("Hi world!" == res.body);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix/nonexistent";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK(404 == res.code);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix_second/nonexistent";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK(404 == res.code);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix/bp2/nonexistent";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK(200 == res.code);
|
||||
CHECK("WRONG!!" == res.body);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/bp_prefix/bp2/bp3/nonexistent";
|
||||
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK(200 == res.code);
|
||||
CHECK("WRONG!!" == res.body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"name": "crow-examples",
|
||||
"version": "master",
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "boost-array",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-algorithm",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-asio",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-date-time",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-functional",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-lexical-cast",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-optional",
|
||||
"version>=": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "openssl-windows"
|
||||
},
|
||||
{
|
||||
"name": "zlib"
|
||||
}
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"name": "boost-array",
|
||||
"version": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-algorithm",
|
||||
"version": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-asio",
|
||||
"version-semver": "1.70.0-2"
|
||||
},
|
||||
{
|
||||
"name": "boost-date-time",
|
||||
"version": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-functional",
|
||||
"version": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-lexical-cast",
|
||||
"version": "1.70.0"
|
||||
},
|
||||
{
|
||||
"name": "boost-optional",
|
||||
"version": "1.70.0"
|
||||
}
|
||||
],
|
||||
"builtin-baseline": "44d94c2edbd44f0c01d66c2ad95eb6982a9a61bc"
|
||||
}
|