mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
ef17b8cb9b
3
.gitignore
vendored
3
.gitignore
vendored
@ -33,3 +33,6 @@ build
|
|||||||
|
|
||||||
.directory
|
.directory
|
||||||
crow_all.h
|
crow_all.h
|
||||||
|
|
||||||
|
# conan.io
|
||||||
|
build/
|
||||||
|
10
.travis.yml
10
.travis.yml
@ -11,14 +11,22 @@ compiler:
|
|||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- COMPILER=g++-4.8 CCOMPILER=gcc-4.8 PUSH_COVERAGE=ON
|
- COMPILER=g++-4.8 CCOMPILER=gcc-4.8 PUSH_COVERAGE=ON
|
||||||
|
- COMPILER=g++-4.9 CCOMPILER=gcc-4.9
|
||||||
|
- COMPILER=g++-5 CCOMPILER=gcc-5
|
||||||
|
- COMPILER=clang++-3.6 CCOMPILER=clang-3.6
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
- boost-latest
|
- boost-latest
|
||||||
|
- llvm-toolchain-precise
|
||||||
|
- llvm-toolchain-precise-3.6
|
||||||
packages:
|
packages:
|
||||||
- g++-4.8
|
- g++-4.8
|
||||||
|
- g++-4.9
|
||||||
|
- g++-5
|
||||||
|
- clang-3.6
|
||||||
- libboost1.55-all-dev
|
- libboost1.55-all-dev
|
||||||
- python-pip
|
- python-pip
|
||||||
|
|
||||||
@ -36,4 +44,4 @@ script: make && ctest
|
|||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- cd ..
|
- cd ..
|
||||||
- if [ "PUSH_COVERAGE" == "ON" ]; then coveralls --gcov gcov-4.8 -i include --gcov-options '\-lp'; fi
|
- if [ "$PUSH_COVERAGE" == "ON" ]; then coveralls --gcov gcov-4.8 -i include --gcov-options '\-lp'; fi
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project (crow_all)
|
project (crow_all)
|
||||||
|
|
||||||
|
if(EXISTS "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
|
||||||
|
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||||
|
conan_basic_setup()
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||||
find_package(Tcmalloc)
|
find_package(Tcmalloc)
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
|
@ -32,7 +32,7 @@ int main()
|
|||||||
- You can also use [json11](https://github.com/dropbox/json11) or [rapidjson](https://github.com/miloyip/rapidjson) for better speed or readability
|
- You can also use [json11](https://github.com/dropbox/json11) or [rapidjson](https://github.com/miloyip/rapidjson) for better speed or readability
|
||||||
- [Mustache](http://mustache.github.io/) based templating library (crow::mustache)
|
- [Mustache](http://mustache.github.io/) based templating library (crow::mustache)
|
||||||
- Header only
|
- Header only
|
||||||
- Provide an amalgamated header file `crow_all.h' with every features
|
- Provide an amalgamated header file `crow_all.h` with every features
|
||||||
- Middleware support
|
- Middleware support
|
||||||
- Websocket support
|
- Websocket support
|
||||||
|
|
||||||
|
10145
amalgamate/crow_all.h
10145
amalgamate/crow_all.h
File diff suppressed because it is too large
Load Diff
28
conanfile.py
Normal file
28
conanfile.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from conans import ConanFile, CMake
|
||||||
|
|
||||||
|
|
||||||
|
class CrowConan(ConanFile):
|
||||||
|
name = "Crow"
|
||||||
|
version = "0.1"
|
||||||
|
url = "https://github.com/ipkn/crow"
|
||||||
|
license = "MIT; see https://github.com/ipkn/crow/blob/master/LICENSE"
|
||||||
|
generators = "cmake"
|
||||||
|
settings = "os", "compiler", "build_type", "arch"
|
||||||
|
|
||||||
|
requires = (("Boost/1.60.0@lasote/stable"),
|
||||||
|
("OpenSSL/1.0.2i@lasote/stable"))
|
||||||
|
|
||||||
|
# No exports necessary
|
||||||
|
|
||||||
|
def source(self):
|
||||||
|
# this will create a hello subfolder, take it into account
|
||||||
|
self.run("git clone https://github.com/ipkn/crow.git")
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
cmake = CMake(self.settings)
|
||||||
|
self.run('cmake %s/crow %s' % (self.conanfile_directory, cmake.command_line))
|
||||||
|
self.run("cmake --build . %s" % cmake.build_config)
|
||||||
|
self.run("make")
|
||||||
|
|
||||||
|
def package(self):
|
||||||
|
self.copy("*.h", dst="include", src="amalgamate")
|
@ -146,6 +146,15 @@ int main()
|
|||||||
for(const auto& countVal : count) {
|
for(const auto& countVal : count) {
|
||||||
os << " - " << countVal << '\n';
|
os << " - " << countVal << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To get a dictionary from the request
|
||||||
|
// You have to submit something like '/params?mydict[a]=b&mydict[abcd]=42' to have a list of pairs ((a, b) and (abcd, 42))
|
||||||
|
auto mydict = req.url_params.get_dict("mydict");
|
||||||
|
os << "The key 'dict' contains " << mydict.size() << " value(s).\n";
|
||||||
|
for(const auto& mydictVal : mydict) {
|
||||||
|
os << " - " << mydictVal.first << " -> " << mydictVal.second << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
return crow::response{os.str()};
|
return crow::response{os.str()};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -33,8 +33,13 @@ int main()
|
|||||||
|
|
||||||
CROW_ROUTE(app, "/")
|
CROW_ROUTE(app, "/")
|
||||||
([]{
|
([]{
|
||||||
|
char name[256];
|
||||||
|
gethostname(name, 256);
|
||||||
|
crow::mustache::context x;
|
||||||
|
x["servername"] = name;
|
||||||
|
|
||||||
auto page = crow::mustache::load("ws.html");
|
auto page = crow::mustache::load("ws.html");
|
||||||
return page.render();
|
return page.render(x);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.port(40080)
|
app.port(40080)
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<textarea id="log" cols=100 rows=50>
|
<textarea id="log" cols=100 rows=50>
|
||||||
</textarea>
|
</textarea>
|
||||||
<script>
|
<script>
|
||||||
var sock = new WebSocket("ws://i.ipkn.me:40080/ws");
|
var sock = new WebSocket("ws://{{servername}}:40080/ws");
|
||||||
sock.onopen = ()=>{
|
sock.onopen = ()=>{
|
||||||
console.log('open')
|
console.log('open')
|
||||||
}
|
}
|
||||||
|
@ -374,6 +374,7 @@ namespace crow
|
|||||||
{401, "HTTP/1.1 401 Unauthorized\r\n"},
|
{401, "HTTP/1.1 401 Unauthorized\r\n"},
|
||||||
{403, "HTTP/1.1 403 Forbidden\r\n"},
|
{403, "HTTP/1.1 403 Forbidden\r\n"},
|
||||||
{404, "HTTP/1.1 404 Not Found\r\n"},
|
{404, "HTTP/1.1 404 Not Found\r\n"},
|
||||||
|
{422, "HTTP/1.1 422 Unprocessable Entity\r\n"},
|
||||||
|
|
||||||
{500, "HTTP/1.1 500 Internal Server Error\r\n"},
|
{500, "HTTP/1.1 500 Internal Server Error\r\n"},
|
||||||
{501, "HTTP/1.1 501 Not Implemented\r\n"},
|
{501, "HTTP/1.1 501 Not Implemented\r\n"},
|
||||||
|
@ -121,13 +121,20 @@ namespace crow
|
|||||||
timer.async_wait(handler);
|
timer.async_wait(handler);
|
||||||
|
|
||||||
init_count ++;
|
init_count ++;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
io_service_pool_[i]->run();
|
if (io_service_pool_[i]->run() == 0)
|
||||||
|
{
|
||||||
|
// when io_service.run returns 0, there are no more works to do.
|
||||||
|
break;
|
||||||
|
}
|
||||||
} catch(std::exception& e)
|
} catch(std::exception& e)
|
||||||
{
|
{
|
||||||
CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: " << e.what();
|
CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: " << e.what();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (tick_function_ && tick_interval_.count() > 0)
|
if (tick_function_ && tick_interval_.count() > 0)
|
||||||
@ -193,6 +200,10 @@ namespace crow
|
|||||||
p->start();
|
p->start();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
do_accept();
|
do_accept();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1264,6 +1264,23 @@ namespace crow
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wvalue& operator=(std::vector<wvalue>&& v)
|
||||||
|
{
|
||||||
|
if (t_ != type::List)
|
||||||
|
reset();
|
||||||
|
t_ = type::List;
|
||||||
|
if (!l)
|
||||||
|
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
|
||||||
|
l->clear();
|
||||||
|
l->resize(v.size());
|
||||||
|
size_t idx = 0;
|
||||||
|
for(auto& x:v)
|
||||||
|
{
|
||||||
|
(*l)[idx++] = std::move(x);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
wvalue& operator=(const std::vector<T>& v)
|
wvalue& operator=(const std::vector<T>& v)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
namespace crow
|
namespace crow
|
||||||
{
|
{
|
||||||
@ -197,6 +199,48 @@ inline char * qs_k2v(const char * key, char * const * qs_kv, int qs_kv_size, int
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close;
|
||||||
|
|
||||||
|
name_len = strlen(dict_name);
|
||||||
|
|
||||||
|
#ifdef _qsSORTING
|
||||||
|
// TODO: binary search for key in the sorted qs_kv
|
||||||
|
#else // _qsSORTING
|
||||||
|
for(i=0; i<qs_kv_size; i++)
|
||||||
|
{
|
||||||
|
if ( strncmp(dict_name, qs_kv[i], name_len) == 0 )
|
||||||
|
{
|
||||||
|
skip_to_eq = strcspn(qs_kv[i], "=");
|
||||||
|
if ( qs_kv[i][skip_to_eq] == '=' )
|
||||||
|
skip_to_eq++;
|
||||||
|
skip_to_brace_open = strcspn(qs_kv[i], "[");
|
||||||
|
if ( qs_kv[i][skip_to_brace_open] == '[' )
|
||||||
|
skip_to_brace_open++;
|
||||||
|
skip_to_brace_close = strcspn(qs_kv[i], "]");
|
||||||
|
|
||||||
|
if ( skip_to_brace_open <= skip_to_brace_close &&
|
||||||
|
skip_to_brace_open > 0 &&
|
||||||
|
skip_to_brace_close > 0 &&
|
||||||
|
nth == 0 )
|
||||||
|
{
|
||||||
|
auto key = std::string(qs_kv[i] + skip_to_brace_open, skip_to_brace_close - skip_to_brace_open);
|
||||||
|
auto value = std::string(qs_kv[i] + skip_to_eq);
|
||||||
|
return boost::make_optional(std::make_pair(key, value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--nth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _qsSORTING
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t val_len)
|
inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t val_len)
|
||||||
{
|
{
|
||||||
@ -336,6 +380,20 @@ namespace crow
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> get_dict (const std::string& name) const
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, std::string> ret;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if (auto element = qs_dict_name2kv(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++))
|
||||||
|
ret.insert(*element);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string url_;
|
std::string url_;
|
||||||
|
@ -156,7 +156,7 @@ namespace crow
|
|||||||
struct Wrapped
|
struct Wrapped
|
||||||
{
|
{
|
||||||
template <typename ... Args>
|
template <typename ... Args>
|
||||||
void set(Func f, typename std::enable_if<
|
void set_(Func f, typename std::enable_if<
|
||||||
!std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value
|
!std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value
|
||||||
, int>::type = 0)
|
, int>::type = 0)
|
||||||
{
|
{
|
||||||
@ -190,7 +190,7 @@ namespace crow
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename ... Args>
|
template <typename ... Args>
|
||||||
void set(Func f, typename std::enable_if<
|
void set_(Func f, typename std::enable_if<
|
||||||
std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value &&
|
std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value &&
|
||||||
!std::is_same<typename std::tuple_element<1, std::tuple<Args..., void, void>>::type, response&>::value
|
!std::is_same<typename std::tuple_element<1, std::tuple<Args..., void, void>>::type, response&>::value
|
||||||
, int>::type = 0)
|
, int>::type = 0)
|
||||||
@ -205,7 +205,7 @@ namespace crow
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ... Args>
|
template <typename ... Args>
|
||||||
void set(Func f, typename std::enable_if<
|
void set_(Func f, typename std::enable_if<
|
||||||
std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value &&
|
std::is_same<typename std::tuple_element<0, std::tuple<Args..., void>>::type, const request&>::value &&
|
||||||
std::is_same<typename std::tuple_element<1, std::tuple<Args..., void, void>>::type, response&>::value
|
std::is_same<typename std::tuple_element<1, std::tuple<Args..., void, void>>::type, response&>::value
|
||||||
, int>::type = 0)
|
, int>::type = 0)
|
||||||
@ -276,12 +276,12 @@ namespace crow
|
|||||||
|
|
||||||
void handle_upgrade(const request& req, response&, SocketAdaptor&& adaptor) override
|
void handle_upgrade(const request& req, response&, SocketAdaptor&& adaptor) override
|
||||||
{
|
{
|
||||||
new crow::websocket::Connection<SocketAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_);
|
new crow::websocket::Connection<SocketAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
|
||||||
}
|
}
|
||||||
#ifdef CROW_ENABLE_SSL
|
#ifdef CROW_ENABLE_SSL
|
||||||
void handle_upgrade(const request& req, response&, SSLAdaptor&& adaptor) override
|
void handle_upgrade(const request& req, response&, SSLAdaptor&& adaptor) override
|
||||||
{
|
{
|
||||||
new crow::websocket::Connection<SSLAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_);
|
new crow::websocket::Connection<SSLAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -313,11 +313,19 @@ namespace crow
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
self_t& onaccept(Func f)
|
||||||
|
{
|
||||||
|
accept_handler_ = f;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::function<void(crow::websocket::connection&)> open_handler_;
|
std::function<void(crow::websocket::connection&)> open_handler_;
|
||||||
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler_;
|
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler_;
|
||||||
std::function<void(crow::websocket::connection&, const std::string&)> close_handler_;
|
std::function<void(crow::websocket::connection&, const std::string&)> close_handler_;
|
||||||
std::function<void(crow::websocket::connection&)> error_handler_;
|
std::function<void(crow::websocket::connection&)> error_handler_;
|
||||||
|
std::function<bool(const crow::request&)> accept_handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -410,7 +418,7 @@ namespace crow
|
|||||||
throw std::runtime_error("route_dynamic: Handler type is mismatched with URL parameters: " + rule_);
|
throw std::runtime_error("route_dynamic: Handler type is mismatched with URL parameters: " + rule_);
|
||||||
}
|
}
|
||||||
auto ret = detail::routing_handler_call_helper::Wrapped<Func, typename function_t::template arg<Indices>...>();
|
auto ret = detail::routing_handler_call_helper::Wrapped<Func, typename function_t::template arg<Indices>...>();
|
||||||
ret.template set<
|
ret.template set_<
|
||||||
typename function_t::template arg<Indices>...
|
typename function_t::template arg<Indices>...
|
||||||
>(std::move(f));
|
>(std::move(f));
|
||||||
return ret;
|
return ret;
|
||||||
@ -456,10 +464,16 @@ namespace crow
|
|||||||
static_assert(!std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
|
static_assert(!std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
|
||||||
"Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
|
"Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
|
||||||
|
|
||||||
handler_ = [f = std::move(f)](const request&, response& res, Args ... args){
|
handler_ = (
|
||||||
|
#ifdef CROW_CAN_USE_CPP14
|
||||||
|
[f = std::move(f)]
|
||||||
|
#else
|
||||||
|
[f]
|
||||||
|
#endif
|
||||||
|
(const request&, response& res, Args ... args){
|
||||||
res = response(f(args...));
|
res = response(f(args...));
|
||||||
res.end();
|
res.end();
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
@ -475,10 +489,16 @@ namespace crow
|
|||||||
static_assert(!std::is_same<void, decltype(f(std::declval<crow::request>(), std::declval<Args>()...))>::value,
|
static_assert(!std::is_same<void, decltype(f(std::declval<crow::request>(), std::declval<Args>()...))>::value,
|
||||||
"Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
|
"Handler function cannot have void return type; valid return types: string, int, crow::resposne, crow::json::wvalue");
|
||||||
|
|
||||||
handler_ = [f = std::move(f)](const crow::request& req, crow::response& res, Args ... args){
|
handler_ = (
|
||||||
|
#ifdef CROW_CAN_USE_CPP14
|
||||||
|
[f = std::move(f)]
|
||||||
|
#else
|
||||||
|
[f]
|
||||||
|
#endif
|
||||||
|
(const crow::request& req, crow::response& res, Args ... args){
|
||||||
res = response(f(req, args...));
|
res = response(f(req, args...));
|
||||||
res.end();
|
res.end();
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
#include <boost/array.hpp>
|
||||||
#include "crow/socket_adaptors.h"
|
#include "crow/socket_adaptors.h"
|
||||||
#include "crow/http_request.h"
|
#include "crow/http_request.h"
|
||||||
#include "crow/TinySHA1.hpp"
|
#include "crow/TinySHA1.hpp"
|
||||||
@ -39,8 +40,10 @@ namespace crow
|
|||||||
std::function<void(crow::websocket::connection&)> open_handler,
|
std::function<void(crow::websocket::connection&)> open_handler,
|
||||||
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler,
|
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler,
|
||||||
std::function<void(crow::websocket::connection&, const std::string&)> close_handler,
|
std::function<void(crow::websocket::connection&, const std::string&)> close_handler,
|
||||||
std::function<void(crow::websocket::connection&)> error_handler)
|
std::function<void(crow::websocket::connection&)> error_handler,
|
||||||
|
std::function<bool(const crow::request&)> accept_handler)
|
||||||
: adaptor_(std::move(adaptor)), open_handler_(std::move(open_handler)), message_handler_(std::move(message_handler)), close_handler_(std::move(close_handler)), error_handler_(std::move(error_handler))
|
: adaptor_(std::move(adaptor)), open_handler_(std::move(open_handler)), message_handler_(std::move(message_handler)), close_handler_(std::move(close_handler)), error_handler_(std::move(error_handler))
|
||||||
|
, accept_handler_(std::move(accept_handler))
|
||||||
{
|
{
|
||||||
if (!boost::iequals(req.get_header_value("upgrade"), "websocket"))
|
if (!boost::iequals(req.get_header_value("upgrade"), "websocket"))
|
||||||
{
|
{
|
||||||
@ -48,6 +51,17 @@ namespace crow
|
|||||||
delete this;
|
delete this;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accept_handler_)
|
||||||
|
{
|
||||||
|
if (!accept_handler_(req))
|
||||||
|
{
|
||||||
|
adaptor.close();
|
||||||
|
delete this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
// Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||||
// Sec-WebSocket-Version: 13
|
// Sec-WebSocket-Version: 13
|
||||||
std::string magic = req.get_header_value("Sec-WebSocket-Key") + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
std::string magic = req.get_header_value("Sec-WebSocket-Key") + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
||||||
@ -486,6 +500,7 @@ namespace crow
|
|||||||
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler_;
|
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler_;
|
||||||
std::function<void(crow::websocket::connection&, const std::string&)> close_handler_;
|
std::function<void(crow::websocket::connection&, const std::string&)> close_handler_;
|
||||||
std::function<void(crow::websocket::connection&)> error_handler_;
|
std::function<void(crow::websocket::connection&)> error_handler_;
|
||||||
|
std::function<bool(const crow::request&)> accept_handler_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user