mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Merge pull request #372 from CrowCpp/doc_updates
Updated documentation in mkdocs and doxygen
This commit is contained in:
commit
90bd4b9494
13
Doxyfile
13
Doxyfile
@ -680,7 +680,7 @@ GENERATE_DEPRECATEDLIST= YES
|
||||
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||
# ... \endcond blocks.
|
||||
|
||||
ENABLED_SECTIONS = $(RAPIDJSON_SECTIONS)
|
||||
ENABLED_SECTIONS =
|
||||
|
||||
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
||||
# initial value of a variable or macro / define can have for it to appear in the
|
||||
@ -2129,14 +2129,7 @@ INCLUDE_FILE_PATTERNS =
|
||||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED = RAPIDJSON_DOXYGEN_RUNNING \
|
||||
"RAPIDJSON_NAMESPACE_BEGIN=namespace rapidjson {" \
|
||||
"RAPIDJSON_NAMESPACE_END=}" \
|
||||
RAPIDJSON_REMOVEFPTR_(x)=x \
|
||||
RAPIDJSON_ENABLEIF_RETURN(cond \
|
||||
"returntype)=RAPIDJSON_REMOVEFPTR_ returntype" \
|
||||
RAPIDJSON_DISABLEIF_RETURN(cond \
|
||||
"returntype)=RAPIDJSON_REMOVEFPTR_ returntype"
|
||||
PREDEFINED =
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
@ -2145,7 +2138,7 @@ PREDEFINED = RAPIDJSON_DOXYGEN_RUNNING \
|
||||
# definition found in the source code.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
EXPAND_AS_DEFINED = RAPIDJSON_NOEXCEPT
|
||||
EXPAND_AS_DEFINED =
|
||||
|
||||
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
||||
# remove all references to function-like macros that are alone on a line, have
|
||||
|
@ -1,4 +1,4 @@
|
||||
This page explains how to set Crow up for use with your project (***For versions 0.3+2 and lower***).
|
||||
This page explains how to set Crow up for use with your project (***For versions 0.3+4 and lower***).
|
||||
|
||||
|
||||
##Requirements
|
||||
@ -34,7 +34,7 @@ Use your package manager to install the following:
|
||||
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.
|
||||
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.
|
||||
|
||||
##Includes folder
|
||||
1. Copy the `/includes` folder to your project's root folder.
|
||||
@ -126,7 +126,7 @@ cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
Running Cmake will create `crow_all.h` file and place it in the build directory.<br>
|
||||
Running CMake will create `crow_all.h` file and place it in the build directory.<br>
|
||||
|
||||
You can run tests with following command:
|
||||
```
|
||||
|
@ -32,14 +32,20 @@ You can also download the `crow_all.h` file and simply include that into your pr
|
||||
<br><br>
|
||||
### Installing from source
|
||||
#### Using CMake
|
||||
1. Download Crow's source code (Either through github's UI or by using<br> `git clone https://github.com/CrowCpp/Crow.git`).
|
||||
1. Download Crow's source code (Either through Github's UI or by using<br> `git clone https://github.com/CrowCpp/Crow.git`).
|
||||
2. Run `mkdir build` inside of crow's source directory.
|
||||
3. Navigate to the new "build" directory and run the following:<br>
|
||||
`cmake .. -DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF`
|
||||
4. Run `make install`.
|
||||
!!!note
|
||||
|
||||
!!! note
|
||||
|
||||
You can ignore `-DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF` if you want to build the Examples and Unit Tests.
|
||||
|
||||
!!! note
|
||||
|
||||
You can uninstall Crow at a later time using `make uninstall`.
|
||||
|
||||
<br>
|
||||
#### Manually
|
||||
Crow can be installed manually on your Linux computer.
|
||||
@ -53,13 +59,15 @@ Crow can be installed manually on your Linux computer.
|
||||
Copy Crow's `include` directory to the `/usr/local/include` directory.
|
||||
|
||||
##### Single header (crow_all.h)
|
||||
!!!warning
|
||||
!!! warning
|
||||
|
||||
`crow_all.h` is recommended only for small, possibly single source file projects, and ideally should not be installed on your system.
|
||||
|
||||
navigate to the `scripts` directory and run `./merge_all.py ../include crow_all.h`. This will generate a `crow_all.h` file that you can use in your projects.
|
||||
!!!note
|
||||
!!! note
|
||||
|
||||
You can also include or exclude middlewares from your `crow_all.h` by using `-i` or `-e` followed by the middleware header file names separated by a comma (e.g. `merge_all.py ../include crow_all.h -e cookie_parser` to exclude the cookie parser middleware).
|
||||
|
||||
## Compiling your project
|
||||
### Using CMake
|
||||
In order to get your CMake project to work with Crow, all you need are the following lines in your CMakeLists.txt:
|
||||
@ -74,6 +82,6 @@ All you need to do is run the following command:
|
||||
g++ main.cpp -lpthread
|
||||
```
|
||||
You can use arguments like `-DCROW_ENABLE_DEBUG`, `-DCROW_ENABLE_COMPRESSION -lz` for HTTP Compression, or `-DCROW_ENABLE_SSL -lssl` for HTTPS support, or even replace g++ with clang++.
|
||||
!!!warning
|
||||
!!! warning
|
||||
|
||||
If you're using a version of boost prior to 1.69, you'll need to add the argument `-lboost_system` in order for you Crow application to compile correctly.
|
||||
|
@ -16,7 +16,7 @@ You can generate your own single header file by navigating to the `scripts` fold
|
||||
python3 merge_all.py ../include crow_all.h
|
||||
```
|
||||
This will generate a `crow_all.h` file which you can use in the following steps
|
||||
!!!warning
|
||||
!!! warning
|
||||
|
||||
`crow_all.h` is recommended only for small, possibly single source file projects. For larger projects, it is advised to use the multi-header version.
|
||||
|
||||
@ -44,7 +44,7 @@ This will generate a `crow_all.h` file which you can use in the following steps
|
||||
|
||||
|
||||
## Building Crow's tests/examples
|
||||
!!!note
|
||||
!!! note
|
||||
|
||||
This tutorial can be used for Crow projects built with CMake as well
|
||||
|
||||
@ -56,20 +56,20 @@ This will generate a `crow_all.h` file which you can use in the following steps
|
||||
2. `cd build`
|
||||
3. `cmake ..`
|
||||
4. `make -j12`
|
||||
!!!note
|
||||
!!! note
|
||||
|
||||
You can add options like `-DCROW_ENABLE_SSL`, `-DCROW_ENABLE_COMPRESSION`, or `-DCROW_AMALGAMATE` to `3.c` to build their tests/examples.
|
||||
You can add options like `-DCROW_ENABLE_SSL`, `-DCROW_ENABLE_COMPRESSION`, or `-DCROW_AMALGAMATE` to `cmake ..` to build their tests/examples.
|
||||
|
||||
## Compiling using a compiler directly
|
||||
All you need to do is run the following command:
|
||||
```
|
||||
g++ main.cpp -lpthread
|
||||
```
|
||||
!!!note
|
||||
!!! note
|
||||
|
||||
You'll need to install GCC via `brew install gcc`. the Clang compiler should be part of Xcode or Xcode command line tools.
|
||||
You'll need to install GCC via `brew install gcc`. the Clang compiler should be part of XCode or XCode command line tools.
|
||||
|
||||
You can use arguments like `-DCROW_ENABLE_DEBUG`, `-DCROW_ENABLE_COMPRESSION -lz` for HTTP Compression, or `-DCROW_ENABLE_SSL -lssl` for HTTPS support, or even replace g++ with clang++.
|
||||
!!!warning
|
||||
!!! warning
|
||||
|
||||
If you're using a version of boost prior to 1.69, you'll need to add the argument `-lboost_system` in order for you Crow application to compile correctly.
|
||||
|
7
docs/guides/CORS.md
Normal file
7
docs/guides/CORS.md
Normal file
@ -0,0 +1,7 @@
|
||||
Crow Allows a developer to set CORS policies by using the `CORSHandler` middleware.<br><br>
|
||||
|
||||
This middleware can be added to the app simply by defining a `#!cpp crow::App<crow::CORSHandler>`. This will use the default CORS rules globally<br><br>
|
||||
|
||||
The CORS rules can be modified by first getting the middleware via `#!cpp auto& cors = app.get_middleware<crow::CORSHandler>();`. The rules can be set per URL prefix using `prefix()`, per blueprint using `blueprint()`, or globally via `global()`. These will return a `CORSRules` object which contains the actual rules for the prefix, blueprint, or application. For more details go [here](../../reference/structcrow_1_1_c_o_r_s_handler.html).
|
||||
|
||||
`CORSRules` can be modified using the methods `origin()`, `methods()`, `headers()`, `max_age()`, `allow_credentials()`, or `ignore()`. For more details on these methods and what default values they take go [here](../../reference/structcrow_1_1_c_o_r_s_rules.html).
|
@ -1,5 +1,5 @@
|
||||
A Crow app defines an interface to allow the developer access to all the different parts of the framework, without having to manually deal with each one.<br><br>
|
||||
An app allows access to the http server (for handling connections), router (for handling URLs and requests), Middlewares (for extending Crow), among many others.<br><br>
|
||||
An app allows access to the HTTP server (for handling connections), router (for handling URLs and requests), Middlewares (for extending Crow), among many others.<br><br>
|
||||
|
||||
Crow has 2 different app types:
|
||||
|
||||
@ -23,6 +23,11 @@ app.bindaddr(192.168.1.2)
|
||||
.multithreaded()
|
||||
.run();
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
The `run()` method is blocking. To run a Crow app asynchronously `run_async()` should be used instead.
|
||||
|
||||
<br><br>
|
||||
|
||||
For more info on middlewares, check out [this page](../middleware).<br><br>
|
||||
|
@ -11,7 +11,7 @@ Every way boils down to the same basic flow:
|
||||
For the purposes of this tutorial, we will assume that the verification function is defined as `#!cpp bool verify(crow::request req, crow::response res)`
|
||||
|
||||
## Basic Auth
|
||||
Basic HTTP authentication requires the client to send the Username and Password as a single string, separated by a colon (':') and then encoded as base64. This data needs to be placed in the `Authorization` header of the request. A sample header using the credentials "Username" and "Password" would look like this: `Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=`.<br><br>
|
||||
Basic HTTP authentication requires the client to send the Username and Password as a single string, separated by a colon (':') and then encoded as Base64. This data needs to be placed in the `Authorization` header of the request. A sample header using the credentials "Username" and "Password" would look like this: `Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=`.<br><br>
|
||||
|
||||
We don't need to worry about creating the request, we only need to extract the credentials from the `Authorization` header and verify them.
|
||||
!!! note
|
||||
@ -47,7 +47,7 @@ return true; //or false if the username/password are invalid
|
||||
Tokens are some form of unique data that a server can provide to a client in order to verify the client's identity later. While on the surface level they don't provide more security than a strong password, they are designed to be less valuable by being *temporary* and providing *limited access*. Variables like expiration time and access scopes are heavily reliant on the implementation however.<br><br>
|
||||
|
||||
### Access Tokens
|
||||
The kind of the token itself can vary depending on the implementation and project requirements: Many services use randomly generated strings as tokens. Then compare them against a database to retrieve the associated user data. Some services however prefer using data bearing tokens. One example of the latter kind is JWT, which uses JSON strings encoded in base64 and signed using a private key or an agreed upon secret. While this has the added hassle of signing the token to ensure that it's not been tampered with. It does allow for the client to issue tokens without ever needing to present a password or contact a server. The server would simply be able to verify the signature using the client's public key or secret.<br><br>
|
||||
The kind of the token itself can vary depending on the implementation and project requirements: Many services use randomly generated strings as tokens. Then compare them against a database to retrieve the associated user data. Some services however prefer using data bearing tokens. One example of the latter kind is JWT, which uses JSON strings encoded in Base64 and signed using a private key or an agreed upon secret. While this has the added hassle of signing the token to ensure that it's not been tampered with. It does allow for the client to issue tokens without ever needing to present a password or contact a server. The server would simply be able to verify the signature using the client's public key or secret.<br><br>
|
||||
|
||||
### Using an Access Token
|
||||
Authenticating with an access token usually involves 2 stages: The first being acquiring the access token from an authority (either by providing credentials such as a username and a password to a server or generating a signed token). The scope of the token (what kind of information it can read or change) is usually defined in this step.<br><br>
|
||||
|
8
docs/guides/base64.md
Normal file
8
docs/guides/base64.md
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
## Encoding
|
||||
Using `#!cpp crow::utility::base64encode(mystring, mystring.size())` will return a Base64 encoded string. For URL safe Base64 `#!cpp crow::utility::base64encode_urlsafe(mystring, mystring.size())` can be used. The key used in the encoding process can be changed, it is a string containing all 64 characters to be used.
|
||||
|
||||
## Decoding
|
||||
**Introduced in: `master`**<br><br>
|
||||
|
||||
Using `#!cpp crow::utility::base64decode(mystring, mystring.size())` with `mystring` being a Base64 encoded string will return a plain-text string. The function works with both normal and URL safe Base64. However it cannot decode a Base64 string encoded with a custom key.
|
@ -1,4 +1,4 @@
|
||||
!!!Warning
|
||||
!!! Warning
|
||||
|
||||
This feature is currently only available on the "master" branch.
|
||||
|
||||
@ -16,7 +16,7 @@ You can define routes in a blueprint, similarly to how `#!cpp CROW_ROUTE(app, "/
|
||||
### 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, turning a route such as `/crow/rocks` into `/prefix/crow/rocks`.
|
||||
|
||||
!!!Warning
|
||||
!!! Warning
|
||||
|
||||
Unlike routes, blueprint prefixes should contain no slashes.
|
||||
|
||||
@ -24,7 +24,7 @@ Blueprints can have a prefix assigned to them. This can be done when creating a
|
||||
### 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
|
||||
!!! 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`.
|
||||
|
||||
@ -32,7 +32,7 @@ Blueprints let you define a custom static directory (relative to your working di
|
||||
### 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
|
||||
!!! 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");`.
|
||||
|
||||
|
@ -25,13 +25,19 @@ 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>
|
||||
|
||||
!!!note
|
||||
!!! note
|
||||
|
||||
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 `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>
|
||||
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.
|
||||
|
||||
Additionally, a `wvalue` can be initialized as an object using an initializer list, an example object would be `wvalue x = {{"a", 1}, {"b", 2}}`. Or as a list using `wvalue x = json::wvalue::list({1, 2, 3})`, lists can include any type that `wvalue` supports.
|
||||
!!! warning
|
||||
|
||||
JSON does not allow floating point values like `NaN` or `INF`, Crow will output `null` instead of `NaN` or `INF` when converting `wvalue` to a string. (`{"Key": NaN}` becomes `{"Key": null}`) (master and later)
|
||||
|
||||
<br><br>
|
||||
|
||||
Additionally, a `wvalue` can be initialized as an object using an initializer list, an example object would be `wvalue x = {{"a", 1}, {"b", 2}}`. Or as a list using `wvalue x = json::wvalue::list({1, 2, 3})`, lists can include any type that `wvalue` supports.<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>
|
||||
|
||||
@ -39,6 +45,6 @@ A JSON `wvalue` can be returned directly inside a route handler, this will cause
|
||||
|
||||
For more info on write values go [here](../../reference/classcrow_1_1json_1_1wvalue.html).
|
||||
|
||||
!!!note
|
||||
!!! 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,5 +1,9 @@
|
||||
Crow comes with a simple and easy to use logging system.<br><br>
|
||||
|
||||
!!! note
|
||||
|
||||
Currently Crow's Logger is not linked to the Crow application, meaning if an executable has more than one Crow application they'll be sharing any variables or classes relating to Logging.
|
||||
|
||||
## Setting up logging level
|
||||
You can set up the level at which crow displays logs by using the app's `loglevel(crow::LogLevel)` method.<br><br>
|
||||
|
||||
@ -22,7 +26,13 @@ To set a logLevel, just use `#!cpp app.loglevel(crow::LogLevel::Warning)`, This
|
||||
## Writing a log
|
||||
Writing a log is as simple as `#!cpp CROW_LOG_<LOG LEVEL> << "Hello";` (replace<LOG LEVEL> with the actual level in all caps, so you have `CROW_LOG_WARNING`).
|
||||
|
||||
!!! note
|
||||
|
||||
Log times are reported in GMT timezone by default. This is because HTTP requires all reported times for requests and responses to be in GMT. This can be changed by using the macro `CROW_USE_LOCALTIMEZONE` which will set **only the log timezone** to the server's local timezone.
|
||||
|
||||
## Creating A custom logger
|
||||
**Introduced in: `master`**<br><br>
|
||||
|
||||
Assuming you have an existing logger or Crow's default format just doesn't work for you. Crow allows you to use a custom logger for any log made using the `CROW_LOG_<LOG LEVEL>` macro.<br>
|
||||
All you need is a class extending `#!cpp crow::ILogHandler` containing the method `#!cpp void log(std::string, crow::LogLevel)`.<br>
|
||||
Once you have your custom logger, you need to set it via `#!cpp crow::logger::setHandler(&MyLogger);`. Here's a full example:<br>
|
||||
|
@ -1,9 +1,11 @@
|
||||
**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>
|
||||
It is typically used either in HTML forms, or when uploading multiple files.<br><br>
|
||||
|
||||
## How multipart messages work
|
||||
The structure of a multipart request is typically consistent of:<br>
|
||||
|
||||
- A Header: Typically `multipart/form-data;boundary=<boundary>`, This defines the HTTP message as being multipart, as well as defining the separator used to distinguish the different parts.<br>
|
||||
@ -13,10 +15,16 @@ The structure of a multipart request is typically consistent of:<br>
|
||||
- Value
|
||||
- `--<boundary>--`<br><br>
|
||||
|
||||
## Multipart messages in Crow
|
||||
Crow supports multipart requests and responses though `crow::multipart::message`.<br>
|
||||
A message can be created either by defining the headers, boundary, and individual parts and using them to create the message. or simply by reading a `crow::request`.<br><br>
|
||||
|
||||
Once a multipart message has been made, the individual parts can be accessed throughout `mpmes.parts`, `parts` is an `std::vector`, so accessing the individual parts should be straightforward.<br>
|
||||
In order to access the individual part's name or filename, something like `#!cpp mpmes.parts[0].headers[0].params["name"]` sould do the trick.<br><br>
|
||||
Once a multipart message has been made, the individual parts can be accessed throughout `msg.parts`, `parts` is an `std::vector`.<br><br>
|
||||
|
||||
**Introduced in: `master`**<br><br>
|
||||
|
||||
Part headers are organized in a similar way to request and response headers, and can be retrieved via `crow::multipart::get_header_object("header-key")`. This function returns a `crow::multipart::header` object.<br><br>
|
||||
|
||||
The message's individual body parts can be accessed by name using `msg.get_part_by_name("part-name")`.<br><br>
|
||||
|
||||
For more info on Multipart messages, go [here](../../reference/namespacecrow_1_1multipart.html)
|
||||
|
@ -10,7 +10,7 @@ We advise that you set crow up behind some form of reverse proxy if you plan on
|
||||
|
||||
## Apache2
|
||||
|
||||
Assuming you have both Apache2 and the modules [proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html), [proxy_http](https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html), [proxy_html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_html.html) (if you plan on serving html pages), and [proxy_wstunnel](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html) (if you plan on using websockets). You will need to enable those modules, which you can do using the following commands:
|
||||
Assuming you have both Apache2 and the modules [proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html), [proxy_http](https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html), [proxy_html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_html.html) (if you plan on serving HTML pages), and [proxy_wstunnel](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html) (if you plan on using websockets). You will need to enable those modules, which you can do using the following commands:
|
||||
|
||||
```sh
|
||||
a2enmod proxy
|
||||
|
@ -1,4 +1,4 @@
|
||||
A query string is the part of the url that comes after a `?` character, it is usually formatted as `key=value&otherkey=othervalue`.
|
||||
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>
|
||||
@ -12,7 +12,7 @@ Works the same as `get`, but removes the returned value.
|
||||
`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>
|
||||
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)
|
||||
|
@ -2,7 +2,7 @@ Routes define what happens when your client connects to a certain URL.<br>
|
||||
|
||||
## Macro
|
||||
`CROW_ROUTE(app, url)`<br>
|
||||
Can be replaced with `#!cpp app.route<crow::black_magick::get_parameter_tag(url)>(url)` or `#!cpp app.route_dynamic(url)` if you're using VS2013 or want runtime url evaluation. Although this usage is **NOT** recommended.
|
||||
Can be replaced with `#!cpp app.route<crow::black_magick::get_parameter_tag(url)>(url)` or `#!cpp app.route_dynamic(url)` if you're using VS2013 or want runtime URL evaluation. Although this usage is **NOT** recommended.
|
||||
## App
|
||||
Which app class to assign the route to.
|
||||
## Path (URL)
|
||||
@ -33,7 +33,7 @@ Basically a piece of code that gets executed whenever the client calls the assoc
|
||||
### Request
|
||||
Handlers can also use information from the request by adding it as a parameter `#!cpp ([](const crow::request& req){...})`.<br><br>
|
||||
|
||||
You can also access the url parameters in the handler using `#!cpp req.url_params.get("param_name");`. If the parameter doesn't exist, `nullptr` is returned.<br><br>
|
||||
You can also access the URL parameters in the handler using `#!cpp req.url_params.get("param_name");`. If the parameter doesn't exist, `nullptr` is returned.<br><br>
|
||||
|
||||
For more information on `crow::request` go [here](../../reference/structcrow_1_1request.html).<br><br>
|
||||
|
||||
@ -82,6 +82,6 @@ Instead of assigning a response code, you can use the `crow::status` enum, for e
|
||||
## Catchall routes
|
||||
**Introduced in: `v0.3`**<br><br>
|
||||
By default, any request that Crow can't find a route for will return a simple 404 response. You can change that to return a default route using the `CROW_CATCHALL_ROUTE(app)` macro. Defining it is identical to a normal route, even when it comes to the `const crow::request&` and `crow::response&` parameters being optional.
|
||||
!!!note
|
||||
!!! note
|
||||
|
||||
For versions higher than 0.3 (excluding patches), Catchall routes handle 404 and 405 responses. The default response will contain the code 404 or 405.
|
||||
|
@ -6,10 +6,19 @@ Crow supports returning Static files as responses in 2 ways.
|
||||
## Implicit
|
||||
Crow implicitly returns any static files placed in a `static` directory and any subdirectories, as long as the user calls the endpoint `/static/path/to/file`.<br><br>
|
||||
The static folder or endpoint can be changed by defining the macros `CROW_STATIC_DIRECTORY "alternative_directory/"` and `CROW_STATIC_ENDPOINT "/alternative_endpoint/<path>"`.<br>
|
||||
static directory changes the directory in the server's filesystem, while the endpoint changes the URL that the client needs to access.
|
||||
static directory changes the directory in the server's file system, while the endpoint changes the URL that the client needs to access.
|
||||
|
||||
## Explicit
|
||||
You can directly return a static file by using the `crow::response` method `#!cpp response.set_static_file_info("path/to/file");`. The path is relative to the executable unless preceded by `/`, then it is an absolute path.<br>
|
||||
Please keep in mind that using the `set_static_file_info` method does invalidate any data already in your response body.<br><br>
|
||||
You can directly return a static file by using the `crow::response` method `#!cpp response.set_static_file_info("path/to/file");`. The path is relative to the working directory.
|
||||
|
||||
**Note**: Crow sets the `content-type` header automatically based on the file's extension, if an extension is unavailable or undefined, Crow uses `text/plain`, if you'd like to explicitly set a `content-type`, use `#!cpp response.set_header("content-type", "mime/type");` **AFTER** calling `set_static_file_info`.
|
||||
!!! Warning
|
||||
|
||||
The path to the file is sanitized by default. it should be fine for most circumstances but if you know what you're doing and need the sanitizer off you can use `#!cpp response.set_static_file_info_unsafe("path/to/file")` instead.
|
||||
|
||||
!!! note
|
||||
|
||||
Crow sets the `content-type` header automatically based on the file's extension, if an extension is unavailable or undefined, Crow uses `text/plain`, if you'd like to explicitly set a `content-type`, use `#!cpp response.set_header("content-type", "mime/type");` **AFTER** calling `set_static_file_info`.
|
||||
|
||||
!!! note
|
||||
|
||||
Please keep in mind that using the `set_static_file_info` method means any data already in your response body is ignored and not sent to the client.
|
||||
|
@ -1,7 +1,11 @@
|
||||
Templating is when you return an html page with custom data. You can probably tell why that's useful.<br><br>
|
||||
Templating is when you return an HTML page with custom data. You can probably tell why that's useful.<br><br>
|
||||
|
||||
Crow supports [mustache](http://mustache.github.io) for templates through its own implementation `crow::mustache`.<br><br>
|
||||
|
||||
!!! note
|
||||
|
||||
Currently Crow's Mustache implementation is not linked to the Crow application, meaning if an executable has more than one Crow application they'll be sharing any variables or classes relating to template loading and compiling.
|
||||
|
||||
## Components of mustache
|
||||
|
||||
There are 2 components of a mustache template implementation:
|
||||
@ -12,6 +16,8 @@ There are 2 components of a mustache template implementation:
|
||||
### Page
|
||||
The HTML page (including the mustache tags). It is usually loaded into `crow::mustache::template_t`. It needs to be placed in the *templates directory* which should be directly inside the current working directory of the crow executable.<br><br>
|
||||
|
||||
The templates directory is usually called `templates`, but can be adjusted per Route (via `crow::mustache::set_base("new_templates_directory")`), per [Blueprint](../blueprints), or globally (via `crow::mustache::set_global_base("new_templates_directory"")`).<br><br>
|
||||
|
||||
For more information on how to formulate a template, see [this mustache manual](http://mustache.github.io/mustache.5.html).
|
||||
|
||||
### Context
|
||||
@ -21,13 +27,26 @@ A JSON object containing the tags as keys and their values. `crow::mustache::con
|
||||
|
||||
`crow::mustache::context` can take a C++ lambda as a value. The lambda needs to take a string as an argument and return a string, such as `#!cpp ctx[lmd] = [&](std::string){return "Hello World";};`.
|
||||
|
||||
!!! note
|
||||
|
||||
The string returned by the lamdba can contain mustache tags, Crow will parse it as any normal template string.
|
||||
|
||||
## Returning a template
|
||||
To return a mustache template, you need to load a page using `#!cpp auto page = crow::mustache::load("path/to/template.html");`, keep in mind that the path is relative to the templates directory.<br>
|
||||
You also need to set up the context by using `#!cpp crow::mustache::context ctx;`. Then you need to assign the keys and values, this can be done the same way you assign values to a json write value (`ctx["key"] = value;`).<br>
|
||||
To return a mustache template, you need to load a page using `#!cpp auto page = crow::mustache::load("path/to/template.html");`. Or just simply load a string using `#!cpp auto page = crow::mustache::compile("my mustache {{value}}");`. Keep in mind that the path is relative to the templates directory.
|
||||
|
||||
!!! note
|
||||
|
||||
You can also use `#!cpp auto page = crow::mustache::load_text("path/to/template.html");` if you want to load a template without mustache processing.
|
||||
|
||||
!!! Warning
|
||||
|
||||
The path to the template is sanitized by default. it should be fine for most circumstances but if you know what you're doing and need the sanitizer off you can use `#!cpp crow::mustache::load_unsafe()` instead.
|
||||
|
||||
<br>
|
||||
You also need to set up the context by using `#!cpp crow::mustache::context ctx;`. Then you need to assign the keys and values, this can be done the same way you assign values to a JSON write value (`ctx["key"] = value;`).<br>
|
||||
With your context and page ready, just `#!cpp return page.render(ctx);`. This will use the context data to return a filled template.<br>
|
||||
Alternatively you could just render the page without a context using `#!cpp return page.render();`.
|
||||
|
||||
!!! note
|
||||
|
||||
`#!cpp page.render();` returns a crow::returnable class in order to set the `Content-Type` header. to get a simple string, use `#!cpp page.render_string()` instead.
|
||||
|
||||
|
@ -9,7 +9,7 @@ A websocket route follows the macro with `.websocket()` which is then followed b
|
||||
By default, Crow allows Clients to send unmasked websocket messages, which is useful for debugging but goes against the protocol specification. Production Crow applications should enforce the protocol by adding `#!cpp #define CROW_ENFORCE_WS_SPEC` to their source code.
|
||||
|
||||
|
||||
- `#!cpp onaccept([&](const crow::request&){handler code goes here})` (This handler has to return bool)
|
||||
- `#!cpp onaccept([&](const crow::request&){handler code goes here})` (This handler has to return `bool`)
|
||||
- `#!cpp onopen([&](crow::websocket::connection& conn){handler code goes here})`
|
||||
- `#!cpp onmessage([&](crow::websocket::connection& conn, const std::string message, bool is_binary){handler code goes here})`
|
||||
- `#!cpp onerror([&](crow::websocket::connection& conn){handler code goes here})`
|
||||
|
@ -83,6 +83,10 @@ add_executable(example_middleware example_middleware.cpp)
|
||||
add_warnings_optimizations(example_middleware)
|
||||
target_link_libraries(example_middleware PUBLIC Crow::Crow)
|
||||
|
||||
add_executable(example_cors middlewares/example_cors.cpp)
|
||||
add_warnings_optimizations(example_cors)
|
||||
target_link_libraries(example_cors PUBLIC Crow::Crow)
|
||||
|
||||
if(MSVC)
|
||||
add_executable(example_vs example_vs.cpp)
|
||||
add_warnings_optimizations(example_vs)
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "crow.h"
|
||||
#include "crow/middlewares/cors.h"
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// Enable CORS
|
@ -121,6 +121,7 @@ namespace crow
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Get the port that Crow will handle requests on
|
||||
std::uint16_t port()
|
||||
{
|
||||
return port_;
|
||||
@ -178,7 +179,7 @@ namespace crow
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Set a response body size (in bytes) beyond which Crow automatically streams responses (Default is 1MiB)
|
||||
/// Set the response body size (in bytes) beyond which Crow automatically streams responses (Default is 1MiB)
|
||||
|
||||
///
|
||||
/// Any streamed response is unaffected by Crow's timer, and therefore won't timeout before a response is fully sent.
|
||||
@ -188,6 +189,7 @@ namespace crow
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Get the response body size (in bytes) beyond which Crow automatically streams responses
|
||||
size_t& stream_threshold()
|
||||
{
|
||||
return res_stream_threshold_;
|
||||
@ -328,6 +330,7 @@ namespace crow
|
||||
}
|
||||
}
|
||||
|
||||
/// Print the routing paths defined for each HTTP method
|
||||
void debug_print()
|
||||
{
|
||||
CROW_LOG_DEBUG << "Routing:";
|
||||
|
@ -222,6 +222,7 @@ namespace crow
|
||||
MAX
|
||||
};
|
||||
|
||||
/// @cond SKIP
|
||||
struct routing_params
|
||||
{
|
||||
std::vector<int64_t> int_params;
|
||||
@ -273,6 +274,7 @@ namespace crow
|
||||
{
|
||||
return string_params[index];
|
||||
}
|
||||
/// @endcond
|
||||
} // namespace crow
|
||||
|
||||
// clang-format off
|
||||
|
@ -7,26 +7,26 @@ namespace crow
|
||||
{
|
||||
struct CORSHandler;
|
||||
|
||||
// CORSRules is used for tuning cors policies
|
||||
/// Used for tuning CORS policies
|
||||
struct CORSRules
|
||||
{
|
||||
friend struct crow::CORSHandler;
|
||||
|
||||
// Set Access-Control-Allow-Origin. Default is "*"
|
||||
/// Set Access-Control-Allow-Origin. Default is "*"
|
||||
CORSRules& origin(const std::string& origin)
|
||||
{
|
||||
origin_ = origin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Set Access-Control-Allow-Methods. Default is "*"
|
||||
/// Set Access-Control-Allow-Methods. Default is "*"
|
||||
CORSRules& methods(crow::HTTPMethod method)
|
||||
{
|
||||
add_list_item(methods_, crow::method_name(method));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Set Access-Control-Allow-Methods. Default is "*"
|
||||
/// Set Access-Control-Allow-Methods. Default is "*"
|
||||
template<typename... Methods>
|
||||
CORSRules& methods(crow::HTTPMethod method, Methods... method_list)
|
||||
{
|
||||
@ -35,14 +35,14 @@ namespace crow
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Set Access-Control-Allow-Headers. Default is "*"
|
||||
/// Set Access-Control-Allow-Headers. Default is "*"
|
||||
CORSRules& headers(const std::string& header)
|
||||
{
|
||||
add_list_item(headers_, header);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Set Access-Control-Allow-Headers. Default is "*"
|
||||
/// Set Access-Control-Allow-Headers. Default is "*"
|
||||
template<typename... Headers>
|
||||
CORSRules& headers(const std::string& header, Headers... header_list)
|
||||
{
|
||||
@ -51,33 +51,33 @@ namespace crow
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Set Access-Control-Max-Age. Default is none
|
||||
/// Set Access-Control-Max-Age. Default is none
|
||||
CORSRules& max_age(int max_age)
|
||||
{
|
||||
max_age_ = std::to_string(max_age);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Enable Access-Control-Allow-Credentials
|
||||
/// Enable Access-Control-Allow-Credentials
|
||||
CORSRules& allow_credentials()
|
||||
{
|
||||
allow_credentials_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Ignore CORS and don't send any headers
|
||||
/// Ignore CORS and don't send any headers
|
||||
void ignore()
|
||||
{
|
||||
ignore_ = true;
|
||||
}
|
||||
|
||||
// Handle CORS on specific prefix path
|
||||
/// Handle CORS on specific prefix path
|
||||
CORSRules& prefix(const std::string& prefix);
|
||||
|
||||
// Handle CORS for specific blueprint
|
||||
/// Handle CORS for specific blueprint
|
||||
CORSRules& blueprint(const Blueprint& bp);
|
||||
|
||||
// Global CORS policy
|
||||
/// Global CORS policy
|
||||
CORSRules& global();
|
||||
|
||||
private:
|
||||
@ -85,7 +85,7 @@ namespace crow
|
||||
CORSRules(CORSHandler* handler):
|
||||
handler_(handler) {}
|
||||
|
||||
// build comma separated list
|
||||
/// build comma separated list
|
||||
void add_list_item(std::string& list, const std::string& val)
|
||||
{
|
||||
if (list == "*") list = "";
|
||||
@ -93,7 +93,7 @@ namespace crow
|
||||
list += val;
|
||||
}
|
||||
|
||||
// Set header `key` to `value` if it is not set
|
||||
/// Set header `key` to `value` if it is not set
|
||||
void set_header_no_override(const std::string& key, const std::string& value, crow::response& res)
|
||||
{
|
||||
if (value.size() == 0) return;
|
||||
@ -101,7 +101,7 @@ namespace crow
|
||||
res.add_header(key, value);
|
||||
}
|
||||
|
||||
// Set response headers
|
||||
/// Set response headers
|
||||
void apply(crow::response& res)
|
||||
{
|
||||
if (ignore_) return;
|
||||
@ -124,6 +124,7 @@ namespace crow
|
||||
};
|
||||
|
||||
/// CORSHandler is a global middleware for setting CORS headers.
|
||||
|
||||
///
|
||||
/// By default, it sets Access-Control-Allow-Origin/Methods/Headers to "*".
|
||||
/// The default behaviour can be changed with the `global()` cors rule.
|
||||
@ -142,21 +143,21 @@ namespace crow
|
||||
rule.apply(res);
|
||||
}
|
||||
|
||||
// Handle CORS on specific prefix path
|
||||
/// Handle CORS on a specific prefix path
|
||||
CORSRules& prefix(const std::string& prefix)
|
||||
{
|
||||
rules.emplace_back(prefix, CORSRules(this));
|
||||
return rules.back().second;
|
||||
}
|
||||
|
||||
// Handle CORS for specific blueprint
|
||||
/// Handle CORS for a specific blueprint
|
||||
CORSRules& blueprint(const Blueprint& bp)
|
||||
{
|
||||
rules.emplace_back(bp.prefix(), CORSRules(this));
|
||||
return rules.back().second;
|
||||
}
|
||||
|
||||
// Global CORS policy
|
||||
/// Get the global CORS policy
|
||||
CORSRules& global()
|
||||
{
|
||||
return default_;
|
||||
|
@ -272,6 +272,7 @@ namespace crow
|
||||
class CatchallRule
|
||||
{
|
||||
public:
|
||||
/// @cond SKIP
|
||||
CatchallRule() {}
|
||||
|
||||
template<typename Func>
|
||||
@ -349,7 +350,7 @@ namespace crow
|
||||
|
||||
handler_ = std::move(f);
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
bool has_handler()
|
||||
{
|
||||
return (handler_ != nullptr);
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
namespace crow
|
||||
{
|
||||
/// @cond SKIP
|
||||
namespace black_magic
|
||||
{
|
||||
#ifndef CROW_MSVC_WORKAROUND
|
||||
@ -528,6 +529,7 @@ namespace crow
|
||||
template<size_t i>
|
||||
using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
inline static std::string base64encode(const unsigned char* data, size_t size, const char* key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
|
||||
{
|
||||
|
@ -52,9 +52,11 @@ nav:
|
||||
- Blueprints: guides/blueprints.md
|
||||
- Compression: guides/compression.md
|
||||
- Websockets: guides/websockets.md
|
||||
- Base64: guides/base64.md
|
||||
- Writing Tests: guides/testing.md
|
||||
- Using Crow:
|
||||
- HTTP Authorization: guides/auth.md
|
||||
- CORS Setup: guides/CORS.md
|
||||
- Server setup:
|
||||
- Proxies: guides/proxies.md
|
||||
- Systemd run on startup: guides/syste.md
|
||||
|
Loading…
Reference in New Issue
Block a user