mirror of https://github.com/CrowCpp/Crow.git
Merge branch 'master' into sessions
This commit is contained in:
commit
36e59f07ec
|
@ -33,12 +33,12 @@ Crow is a C++ framework for creating HTTP or Websocket web services. It uses rou
|
|||
## Documentation
|
||||
Available [here](https://crowcpp.org).
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> If you are using Crow v0.3, then you have to put `#define CROW_MAIN` at the top of one and only one source file.
|
||||
|
||||
## Examples
|
||||
|
||||
#### Disclaimer
|
||||
|
||||
If you are using version v0.3, then you have to put `#define CROW_MAIN` at the top of one and only one source file.
|
||||
|
||||
#### Hello World
|
||||
```cpp
|
||||
#include "crow.h"
|
||||
|
|
|
@ -4,7 +4,7 @@ include(CMakeFindDependencyMacro)
|
|||
|
||||
get_filename_component(CROW_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
list(APPEND CMAKE_MODULE_PATH ${CROW_CMAKE_DIR})
|
||||
find_dependency(asio)
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH -1)
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
--md-primary-fg-color: #24404f;
|
||||
--md-accent-fg-color: #445e6d;
|
||||
--md-default-fg-color: rgba(255, 255, 255, 0.87);
|
||||
--md-typeset-color: rgba(255, 255, 255, 0.80);
|
||||
--md-admonition-fg-color: rgba(255, 255, 255, 0.80);
|
||||
--md-default-fg-color--light: rgba(255, 255, 255, 0.54);
|
||||
--md-default-fg-color--lighter: rgba(255, 255, 255, 0.32);
|
||||
--md-default-fg-color--lightest: rgba(255, 255, 255, 0.07);
|
||||
|
@ -30,6 +32,7 @@
|
|||
--md-code-hl-comment-color: var(--md-code-fg-color) !important;
|
||||
--md-code-hl-generic-color: var(--md-code-fg-color) !important;
|
||||
--md-code-hl-variable-color: var(--md-code-fg-color) !important;
|
||||
--md-code-hl-operator-color: var(--md-code-fg-color) !important;
|
||||
--md-code-fg-color: #adadad !important;
|
||||
--md-code-hl-punctuation-color: #adadad !important;
|
||||
--home-border-color: #ffffff20;
|
||||
|
|
|
@ -119,11 +119,10 @@ inline int qs_parse(char* qs, char* qs_kv[], int qs_kv_size, bool parse_url = tr
|
|||
{
|
||||
qs_kv[i] = substr_ptr;
|
||||
j = strcspn(substr_ptr, "&");
|
||||
if ( substr_ptr[j] == '\0' ) { break; }
|
||||
if ( substr_ptr[j] == '\0' ) { i++; break; } // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
|
||||
substr_ptr += j + 1;
|
||||
i++;
|
||||
}
|
||||
i++; // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
|
||||
|
||||
// we only decode the values in place, the keys could have '='s in them
|
||||
// which will hose our ability to distinguish keys from values later
|
||||
|
|
|
@ -1538,7 +1538,10 @@ namespace crow
|
|||
return;
|
||||
else if (req.method == HTTPMethod::Head)
|
||||
{
|
||||
method_actual = HTTPMethod::Get;
|
||||
// support HEAD requests using GET if not defined as method for the requested URL
|
||||
if (!std::get<0>(per_methods_[static_cast<int>(HTTPMethod::Head)].trie.find(req.url)))
|
||||
method_actual = HTTPMethod::Get;
|
||||
|
||||
res.skip_body = true;
|
||||
}
|
||||
else if (req.method == HTTPMethod::Options)
|
||||
|
@ -1549,6 +1552,9 @@ namespace crow
|
|||
{
|
||||
for (int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
|
||||
{
|
||||
if (static_cast<int>(HTTPMethod::Head) == i)
|
||||
continue; // HEAD is always allowed
|
||||
|
||||
if (!per_methods_[i].trie.is_empty())
|
||||
{
|
||||
allow += method_name(static_cast<HTTPMethod>(i)) + ", ";
|
||||
|
@ -1562,14 +1568,20 @@ namespace crow
|
|||
}
|
||||
else
|
||||
{
|
||||
bool rules_matched = false;
|
||||
for (int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
|
||||
{
|
||||
if (std::get<0>(per_methods_[i].trie.find(req.url)))
|
||||
{
|
||||
rules_matched = true;
|
||||
|
||||
if (static_cast<int>(HTTPMethod::Head) == i)
|
||||
continue; // HEAD is always allowed
|
||||
|
||||
allow += method_name(static_cast<HTTPMethod>(i)) + ", ";
|
||||
}
|
||||
}
|
||||
if (allow != "OPTIONS, HEAD, ")
|
||||
if (rules_matched)
|
||||
{
|
||||
allow = allow.substr(0, allow.size() - 2);
|
||||
res = response(204);
|
||||
|
|
|
@ -309,6 +309,10 @@ TEST_CASE("http_method")
|
|||
return "1";
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/head_only")
|
||||
.methods("HEAD"_method)([](const request& /*req*/) {
|
||||
return response{202};
|
||||
});
|
||||
CROW_ROUTE(app, "/get_only")
|
||||
.methods("GET"_method)([](const request& /*req*/) {
|
||||
return "get";
|
||||
|
@ -354,6 +358,18 @@ TEST_CASE("http_method")
|
|||
CHECK("1" == res.body);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/head_only";
|
||||
req.method = "HEAD"_method;
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK(202 == res.code);
|
||||
CHECK("" == res.body);
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
@ -454,6 +470,18 @@ TEST_CASE("http_method")
|
|||
CHECK(204 == res.code);
|
||||
CHECK("OPTIONS, HEAD, GET, POST, PATCH, PURGE" == res.get_header_value("Allow"));
|
||||
}
|
||||
|
||||
{
|
||||
request req;
|
||||
response res;
|
||||
|
||||
req.url = "/head_only";
|
||||
req.method = "OPTIONS"_method;
|
||||
app.handle(req, res);
|
||||
|
||||
CHECK(204 == res.code);
|
||||
CHECK("OPTIONS, HEAD" == res.get_header_value("Allow"));
|
||||
}
|
||||
} // http_method
|
||||
|
||||
TEST_CASE("server_handling_error_request")
|
||||
|
|
Loading…
Reference in New Issue