From dc5d9ba2908c2f7e9346e0d6d7f06011cf2ebdfc Mon Sep 17 00:00:00 2001 From: Huu Nguyen Date: Mon, 28 Sep 2015 20:22:02 -0400 Subject: [PATCH 01/37] Add two new gcc compilers to travis configuration --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index cec01865a..8dc7d129c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ compiler: env: matrix: - 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 addons: apt: @@ -19,6 +21,8 @@ addons: - boost-latest packages: - g++-4.8 + - g++-4.9 + - g++-5 - libboost1.55-all-dev - python-pip From d42888fa286ea18e8d599e0191198ea3cff24d9d Mon Sep 17 00:00:00 2001 From: Huu Nguyen Date: Mon, 28 Sep 2015 20:22:42 -0400 Subject: [PATCH 02/37] Add clang compiler to travis configuration --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8dc7d129c..e283093ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,16 +13,20 @@ env: - 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: apt: sources: - ubuntu-toolchain-r-test - boost-latest + - llvm-toolchain-precise + - llvm-toolchain-precise-3.6 packages: - g++-4.8 - g++-4.9 - g++-5 + - clang-3.6 - libboost1.55-all-dev - python-pip From d580ed7d25e6c642215db91a241faf4332be9a64 Mon Sep 17 00:00:00 2001 From: barcarolle Date: Thu, 20 Oct 2016 15:06:32 +0900 Subject: [PATCH 03/37] typo README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bea6c5091..f6261b4a5 100644 --- a/README.md +++ b/README.md @@ -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 - [Mustache](http://mustache.github.io/) based templating library (crow::mustache) - 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 - Websocket support From 990a8a34d090db2754d5004d0f793ea149fcd330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:18:21 +0100 Subject: [PATCH 04/37] Trying to add support for conan.io dependency system... --- CMakeLists.txt | 4 ++++ conanfile.txt | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 conanfile.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index e2d3bc7dc..4d257bd5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 2.8) project (crow_all) + +include(build/conanbuildinfo.cmake) +conan_basic_setup() + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") find_package(Tcmalloc) find_package(Threads) diff --git a/conanfile.txt b/conanfile.txt new file mode 100644 index 000000000..22b112a18 --- /dev/null +++ b/conanfile.txt @@ -0,0 +1,7 @@ +[requires] +Boost/1.60.0@lasote/stable +OpenSSL/1.0.2i@lasote/stable + +[generators] +cmake + From bcf943b9b19552465c2482652444178152799cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:35:49 +0100 Subject: [PATCH 05/37] Trying to add support for conan.io --- conanfile.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 conanfile.py diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 000000000..416ffd146 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,23 @@ +from conans import ConanFile, CMake + +class CrowConan(ConanFile): + name = "Crow" + version = "0.1" + settings = "os", "compiler", "build_type", "arch" + # No exports necessary + + def source(self): + # this will create a hello subfolder, take it into account + self.run("git clone https://github.com/javierjeronimo/crow.git") + + def build(self): + cmake = CMake(self.settings) + self.run("cmake . %s" % cmake.build_config) + self.run("make") + + def package(self): + self.copy("*.h", dst="include", src="amalgamate") + + def package_info(self): + self.cpp_info.libs = ["crow"] + From ede9a21dbc7658b64571233af8f06ee671c9888e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:40:17 +0100 Subject: [PATCH 06/37] More... --- conanfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conanfile.py b/conanfile.py index 416ffd146..677c678b8 100644 --- a/conanfile.py +++ b/conanfile.py @@ -3,6 +3,8 @@ from conans import ConanFile, CMake class CrowConan(ConanFile): name = "Crow" version = "0.1" + url = "https://github.com/javierjeronimo/crow" + license = "see https://github.com/ipkn/crow/blob/master/LICENSE" settings = "os", "compiler", "build_type", "arch" # No exports necessary @@ -12,6 +14,7 @@ class CrowConan(ConanFile): def build(self): cmake = CMake(self.settings) + self.run('cmake %s %s' % (self.conanfile_directory, cmake.command_line)) self.run("cmake . %s" % cmake.build_config) self.run("make") From 0f4cfc91086dc2d1f05407ac738a581f5768951b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:44:15 +0100 Subject: [PATCH 07/37] More --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 677c678b8..ba12a10cb 100644 --- a/conanfile.py +++ b/conanfile.py @@ -14,7 +14,7 @@ class CrowConan(ConanFile): def build(self): cmake = CMake(self.settings) - self.run('cmake %s %s' % (self.conanfile_directory, cmake.command_line)) + # self.run('cmake %s %s' % (self.conanfile_directory, cmake.command_line)) self.run("cmake . %s" % cmake.build_config) self.run("make") From 748a95c84fe43471c5de58122de4c778f08ae2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:51:32 +0100 Subject: [PATCH 08/37] More --- conanfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conanfile.py b/conanfile.py index ba12a10cb..533179f50 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,4 +1,5 @@ from conans import ConanFile, CMake +import shutil class CrowConan(ConanFile): name = "Crow" @@ -11,6 +12,7 @@ class CrowConan(ConanFile): def source(self): # this will create a hello subfolder, take it into account self.run("git clone https://github.com/javierjeronimo/crow.git") + shutil.move("crow/*", ".") def build(self): cmake = CMake(self.settings) From 09cae9f4c213628f909fd0f8a9dcdaf5e10c17dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:54:34 +0100 Subject: [PATCH 09/37] More --- conanfile.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/conanfile.py b/conanfile.py index 533179f50..b72db5cf3 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,5 +1,4 @@ from conans import ConanFile, CMake -import shutil class CrowConan(ConanFile): name = "Crow" @@ -12,11 +11,10 @@ class CrowConan(ConanFile): def source(self): # this will create a hello subfolder, take it into account self.run("git clone https://github.com/javierjeronimo/crow.git") - shutil.move("crow/*", ".") def build(self): cmake = CMake(self.settings) - # self.run('cmake %s %s' % (self.conanfile_directory, cmake.command_line)) + self.run('cmake %s/crow %s' % (self.conanfile_directory, cmake.command_line)) self.run("cmake . %s" % cmake.build_config) self.run("make") From 5037825a59811027047c0100dced0760e78b8ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 11:56:33 +0100 Subject: [PATCH 10/37] More --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index b72db5cf3..8a19503c0 100644 --- a/conanfile.py +++ b/conanfile.py @@ -15,7 +15,7 @@ class CrowConan(ConanFile): def build(self): cmake = CMake(self.settings) self.run('cmake %s/crow %s' % (self.conanfile_directory, cmake.command_line)) - self.run("cmake . %s" % cmake.build_config) + self.run("cmake --build . %s" % cmake.build_config) self.run("make") def package(self): From d43cd764353cd12a40cdb9c692593d9caba2cd43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 12:00:26 +0100 Subject: [PATCH 11/37] More --- conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conanfile.py b/conanfile.py index 8a19503c0..4f2987eaf 100644 --- a/conanfile.py +++ b/conanfile.py @@ -6,6 +6,7 @@ class CrowConan(ConanFile): url = "https://github.com/javierjeronimo/crow" license = "see https://github.com/ipkn/crow/blob/master/LICENSE" settings = "os", "compiler", "build_type", "arch" + generators = "cmake" # No exports necessary def source(self): From e9c97b1350025d93247704dc1f47a8b6fd6211cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 12:02:04 +0100 Subject: [PATCH 12/37] More --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d257bd5d..05a90b78e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 2.8) project (crow_all) -include(build/conanbuildinfo.cmake) +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") From 2877991498b009a16723a2b171967b846c8a74ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 12:07:14 +0100 Subject: [PATCH 13/37] Requirements --- conanfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conanfile.py b/conanfile.py index 4f2987eaf..cf0c798e7 100644 --- a/conanfile.py +++ b/conanfile.py @@ -7,6 +7,9 @@ class CrowConan(ConanFile): license = "see https://github.com/ipkn/crow/blob/master/LICENSE" settings = "os", "compiler", "build_type", "arch" generators = "cmake" + + requires = (("Boost/1.60.0@lasote/stable"), + ("OpenSSL/1.0.2i@lasote/stable")) # No exports necessary def source(self): From c2f3aea0a1f60c7d2d5f586fe7abb2362c40faf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sat, 19 Nov 2016 12:39:13 +0100 Subject: [PATCH 14/37] Its a header only conan package --- conanfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index cf0c798e7..9b063787f 100644 --- a/conanfile.py +++ b/conanfile.py @@ -5,7 +5,6 @@ class CrowConan(ConanFile): version = "0.1" url = "https://github.com/javierjeronimo/crow" license = "see https://github.com/ipkn/crow/blob/master/LICENSE" - settings = "os", "compiler", "build_type", "arch" generators = "cmake" requires = (("Boost/1.60.0@lasote/stable"), From 5f786cdccd2b511f867d08dbe7a10b7566e1e9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sun, 20 Nov 2016 22:40:47 +0100 Subject: [PATCH 15/37] Fixes --- conanfile.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/conanfile.py b/conanfile.py index 9b063787f..73d9b14de 100644 --- a/conanfile.py +++ b/conanfile.py @@ -6,6 +6,7 @@ class CrowConan(ConanFile): url = "https://github.com/javierjeronimo/crow" license = "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")) @@ -17,13 +18,9 @@ class CrowConan(ConanFile): 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") + 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") - - def package_info(self): - self.cpp_info.libs = ["crow"] - From 18bc428f06d71e061e49b71813027d9ef8ab8fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sun, 20 Nov 2016 22:43:34 +0100 Subject: [PATCH 16/37] indent --- conanfile.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/conanfile.py b/conanfile.py index 73d9b14de..36d8ba54e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,5 +1,6 @@ from conans import ConanFile, CMake + class CrowConan(ConanFile): name = "Crow" version = "0.1" @@ -10,6 +11,7 @@ class CrowConan(ConanFile): requires = (("Boost/1.60.0@lasote/stable"), ("OpenSSL/1.0.2i@lasote/stable")) + # No exports necessary def source(self): @@ -18,9 +20,10 @@ class CrowConan(ConanFile): 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") + 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") + +def package(self): + self.copy("*.h", dst="include", src="amalgamate") From 79ca284d6c341f43157e038c722c30440859b1ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sun, 20 Nov 2016 22:47:14 +0100 Subject: [PATCH 17/37] indent --- conanfile.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/conanfile.py b/conanfile.py index 36d8ba54e..a8eb8c1c1 100644 --- a/conanfile.py +++ b/conanfile.py @@ -24,6 +24,5 @@ class CrowConan(ConanFile): self.run("cmake --build . %s" % cmake.build_config) self.run("make") - -def package(self): - self.copy("*.h", dst="include", src="amalgamate") + def package(self): + self.copy("*.h", dst="include", src="amalgamate") From 91ac9111d45fa618a311c9dd2c8f30c031d8f46b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sun, 20 Nov 2016 23:04:25 +0100 Subject: [PATCH 18/37] fix --- conanfile.txt | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 conanfile.txt diff --git a/conanfile.txt b/conanfile.txt deleted file mode 100644 index 22b112a18..000000000 --- a/conanfile.txt +++ /dev/null @@ -1,7 +0,0 @@ -[requires] -Boost/1.60.0@lasote/stable -OpenSSL/1.0.2i@lasote/stable - -[generators] -cmake - From a71c0a0edb9262eb7dc83c67bf523fa7272d701f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Sun, 20 Nov 2016 23:20:48 +0100 Subject: [PATCH 19/37] ignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6dcb0a252..cfe8b6444 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ build .directory crow_all.h + +# conan.io +build/ From c03d3b2d5aebbfc11fd85af93d6c389ca4d39d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jer=C3=B3nimo=20Su=C3=A1rez?= Date: Tue, 22 Nov 2016 17:50:06 +0100 Subject: [PATCH 20/37] Make it compatible with conan.io (but optional). --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05a90b78e..f7f2d9957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required(VERSION 2.8) 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/") find_package(Tcmalloc) @@ -28,13 +30,13 @@ endif() include_directories( ${Boost_INCLUDE_DIR} ) -set(PROJECT_INCLUDE_DIR +set(PROJECT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include ) include_directories("${PROJECT_INCLUDE_DIR}") include_directories("${PROJECT_SOURCE_DIR}") - + #add_subdirectory(src) add_subdirectory(examples) if (MSVC) From 32d66d6fd1ac7f90512a573991de4940b5063374 Mon Sep 17 00:00:00 2001 From: Vsevolod Kvachev Date: Tue, 6 Dec 2016 18:22:10 +0300 Subject: [PATCH 21/37] Upgrade amalgamate --- amalgamate/crow_all.h | 3029 ++++++++++++++++++++-------------------- include/crow/routing.h | 8 +- 2 files changed, 1520 insertions(+), 1517 deletions(-) diff --git a/amalgamate/crow_all.h b/amalgamate/crow_all.h index 41b06ffb1..6ffbe66e8 100644 --- a/amalgamate/crow_all.h +++ b/amalgamate/crow_all.h @@ -1,3 +1,239 @@ +#pragma once + +#include +#include +#include + +namespace crow +{ + struct ci_hash + { + size_t operator()(const std::string& key) const + { + std::size_t seed = 0; + std::locale locale; + + for(auto c : key) + { + boost::hash_combine(seed, std::toupper(c, locale)); + } + + return seed; + } + }; + + struct ci_key_eq + { + bool operator()(const std::string& l, const std::string& r) const + { + return boost::iequals(l, r); + } + }; + + using ci_map = std::unordered_multimap; +} + + + +/* + * + * TinySHA1 - a header only implementation of the SHA1 algorithm in C++. Based + * on the implementation in boost::uuid::details. + * + * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1 + * + * Copyright (c) 2012-22 SAURAV MOHAPATRA + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _TINY_SHA1_HPP_ +#define _TINY_SHA1_HPP_ +#include +#include +#include +#include +namespace sha1 +{ + class SHA1 + { + public: + typedef uint32_t digest32_t[5]; + typedef uint8_t digest8_t[20]; + inline static uint32_t LeftRotate(uint32_t value, size_t count) { + return (value << count) ^ (value >> (32-count)); + } + SHA1(){ reset(); } + virtual ~SHA1() {} + SHA1(const SHA1& s) { *this = s; } + const SHA1& operator = (const SHA1& s) { + memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); + memcpy(m_block, s.m_block, 64); + m_blockByteIndex = s.m_blockByteIndex; + m_byteCount = s.m_byteCount; + return *this; + } + SHA1& reset() { + m_digest[0] = 0x67452301; + m_digest[1] = 0xEFCDAB89; + m_digest[2] = 0x98BADCFE; + m_digest[3] = 0x10325476; + m_digest[4] = 0xC3D2E1F0; + m_blockByteIndex = 0; + m_byteCount = 0; + return *this; + } + SHA1& processByte(uint8_t octet) { + this->m_block[this->m_blockByteIndex++] = octet; + ++this->m_byteCount; + if(m_blockByteIndex == 64) { + this->m_blockByteIndex = 0; + processBlock(); + } + return *this; + } + SHA1& processBlock(const void* const start, const void* const end) { + const uint8_t* begin = static_cast(start); + const uint8_t* finish = static_cast(end); + while(begin != finish) { + processByte(*begin); + begin++; + } + return *this; + } + SHA1& processBytes(const void* const data, size_t len) { + const uint8_t* block = static_cast(data); + processBlock(block, block + len); + return *this; + } + const uint32_t* getDigest(digest32_t digest) { + size_t bitCount = this->m_byteCount * 8; + processByte(0x80); + if (this->m_blockByteIndex > 56) { + while (m_blockByteIndex != 0) { + processByte(0); + } + while (m_blockByteIndex < 56) { + processByte(0); + } + } else { + while (m_blockByteIndex < 56) { + processByte(0); + } + } + processByte(0); + processByte(0); + processByte(0); + processByte(0); + processByte( static_cast((bitCount>>24) & 0xFF)); + processByte( static_cast((bitCount>>16) & 0xFF)); + processByte( static_cast((bitCount>>8 ) & 0xFF)); + processByte( static_cast((bitCount) & 0xFF)); + + memcpy(digest, m_digest, 5 * sizeof(uint32_t)); + return digest; + } + const uint8_t* getDigestBytes(digest8_t digest) { + digest32_t d32; + getDigest(d32); + size_t di = 0; + digest[di++] = ((d32[0] >> 24) & 0xFF); + digest[di++] = ((d32[0] >> 16) & 0xFF); + digest[di++] = ((d32[0] >> 8) & 0xFF); + digest[di++] = ((d32[0]) & 0xFF); + + digest[di++] = ((d32[1] >> 24) & 0xFF); + digest[di++] = ((d32[1] >> 16) & 0xFF); + digest[di++] = ((d32[1] >> 8) & 0xFF); + digest[di++] = ((d32[1]) & 0xFF); + + digest[di++] = ((d32[2] >> 24) & 0xFF); + digest[di++] = ((d32[2] >> 16) & 0xFF); + digest[di++] = ((d32[2] >> 8) & 0xFF); + digest[di++] = ((d32[2]) & 0xFF); + + digest[di++] = ((d32[3] >> 24) & 0xFF); + digest[di++] = ((d32[3] >> 16) & 0xFF); + digest[di++] = ((d32[3] >> 8) & 0xFF); + digest[di++] = ((d32[3]) & 0xFF); + + digest[di++] = ((d32[4] >> 24) & 0xFF); + digest[di++] = ((d32[4] >> 16) & 0xFF); + digest[di++] = ((d32[4] >> 8) & 0xFF); + digest[di++] = ((d32[4]) & 0xFF); + return digest; + } + + protected: + void processBlock() { + uint32_t w[80]; + for (size_t i = 0; i < 16; i++) { + w[i] = (m_block[i*4 + 0] << 24); + w[i] |= (m_block[i*4 + 1] << 16); + w[i] |= (m_block[i*4 + 2] << 8); + w[i] |= (m_block[i*4 + 3]); + } + for (size_t i = 16; i < 80; i++) { + w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1); + } + + uint32_t a = m_digest[0]; + uint32_t b = m_digest[1]; + uint32_t c = m_digest[2]; + uint32_t d = m_digest[3]; + uint32_t e = m_digest[4]; + + for (std::size_t i=0; i<80; ++i) { + uint32_t f = 0; + uint32_t k = 0; + + if (i<20) { + f = (b & c) | (~b & d); + k = 0x5A827999; + } else if (i<40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } else if (i<60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } else { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = LeftRotate(b, 30); + b = a; + a = temp; + } + + m_digest[0] += a; + m_digest[1] += b; + m_digest[2] += c; + m_digest[3] += d; + m_digest[4] += e; + } + private: + digest32_t m_digest; + uint8_t m_block[64]; + size_t m_blockByteIndex; + size_t m_byteCount; + }; +} +#endif + + + #pragma once #include @@ -6,6 +242,8 @@ #include #include +namespace crow +{ // ---------------------------------------------------------------------------- // qs_parse (modified) // https://github.com/bartgrantham/qs_parse @@ -231,6 +469,7 @@ inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t return val; } +} // ---------------------------------------------------------------------------- @@ -2986,242 +3225,6 @@ http_parser_version(void) { -#pragma once - -#include -#include -#include - -namespace crow -{ - struct ci_hash - { - size_t operator()(const std::string& key) const - { - std::size_t seed = 0; - std::locale locale; - - for(auto c : key) - { - boost::hash_combine(seed, std::toupper(c, locale)); - } - - return seed; - } - }; - - struct ci_key_eq - { - bool operator()(const std::string& l, const std::string& r) const - { - return boost::iequals(l, r); - } - }; - - using ci_map = std::unordered_multimap; -} - - - -/* - * - * TinySHA1 - a header only implementation of the SHA1 algorithm in C++. Based - * on the implementation in boost::uuid::details. - * - * SHA1 Wikipedia Page: http://en.wikipedia.org/wiki/SHA-1 - * - * Copyright (c) 2012-22 SAURAV MOHAPATRA - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef _TINY_SHA1_HPP_ -#define _TINY_SHA1_HPP_ -#include -#include -#include -#include -namespace sha1 -{ - class SHA1 - { - public: - typedef uint32_t digest32_t[5]; - typedef uint8_t digest8_t[20]; - inline static uint32_t LeftRotate(uint32_t value, size_t count) { - return (value << count) ^ (value >> (32-count)); - } - SHA1(){ reset(); } - virtual ~SHA1() {} - SHA1(const SHA1& s) { *this = s; } - const SHA1& operator = (const SHA1& s) { - memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); - memcpy(m_block, s.m_block, 64); - m_blockByteIndex = s.m_blockByteIndex; - m_byteCount = s.m_byteCount; - return *this; - } - SHA1& reset() { - m_digest[0] = 0x67452301; - m_digest[1] = 0xEFCDAB89; - m_digest[2] = 0x98BADCFE; - m_digest[3] = 0x10325476; - m_digest[4] = 0xC3D2E1F0; - m_blockByteIndex = 0; - m_byteCount = 0; - return *this; - } - SHA1& processByte(uint8_t octet) { - this->m_block[this->m_blockByteIndex++] = octet; - ++this->m_byteCount; - if(m_blockByteIndex == 64) { - this->m_blockByteIndex = 0; - processBlock(); - } - return *this; - } - SHA1& processBlock(const void* const start, const void* const end) { - const uint8_t* begin = static_cast(start); - const uint8_t* finish = static_cast(end); - while(begin != finish) { - processByte(*begin); - begin++; - } - return *this; - } - SHA1& processBytes(const void* const data, size_t len) { - const uint8_t* block = static_cast(data); - processBlock(block, block + len); - return *this; - } - const uint32_t* getDigest(digest32_t digest) { - size_t bitCount = this->m_byteCount * 8; - processByte(0x80); - if (this->m_blockByteIndex > 56) { - while (m_blockByteIndex != 0) { - processByte(0); - } - while (m_blockByteIndex < 56) { - processByte(0); - } - } else { - while (m_blockByteIndex < 56) { - processByte(0); - } - } - processByte(0); - processByte(0); - processByte(0); - processByte(0); - processByte( static_cast((bitCount>>24) & 0xFF)); - processByte( static_cast((bitCount>>16) & 0xFF)); - processByte( static_cast((bitCount>>8 ) & 0xFF)); - processByte( static_cast((bitCount) & 0xFF)); - - memcpy(digest, m_digest, 5 * sizeof(uint32_t)); - return digest; - } - const uint8_t* getDigestBytes(digest8_t digest) { - digest32_t d32; - getDigest(d32); - size_t di = 0; - digest[di++] = ((d32[0] >> 24) & 0xFF); - digest[di++] = ((d32[0] >> 16) & 0xFF); - digest[di++] = ((d32[0] >> 8) & 0xFF); - digest[di++] = ((d32[0]) & 0xFF); - - digest[di++] = ((d32[1] >> 24) & 0xFF); - digest[di++] = ((d32[1] >> 16) & 0xFF); - digest[di++] = ((d32[1] >> 8) & 0xFF); - digest[di++] = ((d32[1]) & 0xFF); - - digest[di++] = ((d32[2] >> 24) & 0xFF); - digest[di++] = ((d32[2] >> 16) & 0xFF); - digest[di++] = ((d32[2] >> 8) & 0xFF); - digest[di++] = ((d32[2]) & 0xFF); - - digest[di++] = ((d32[3] >> 24) & 0xFF); - digest[di++] = ((d32[3] >> 16) & 0xFF); - digest[di++] = ((d32[3] >> 8) & 0xFF); - digest[di++] = ((d32[3]) & 0xFF); - - digest[di++] = ((d32[4] >> 24) & 0xFF); - digest[di++] = ((d32[4] >> 16) & 0xFF); - digest[di++] = ((d32[4] >> 8) & 0xFF); - digest[di++] = ((d32[4]) & 0xFF); - return digest; - } - - protected: - void processBlock() { - uint32_t w[80]; - for (size_t i = 0; i < 16; i++) { - w[i] = (m_block[i*4 + 0] << 24); - w[i] |= (m_block[i*4 + 1] << 16); - w[i] |= (m_block[i*4 + 2] << 8); - w[i] |= (m_block[i*4 + 3]); - } - for (size_t i = 16; i < 80; i++) { - w[i] = LeftRotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1); - } - - uint32_t a = m_digest[0]; - uint32_t b = m_digest[1]; - uint32_t c = m_digest[2]; - uint32_t d = m_digest[3]; - uint32_t e = m_digest[4]; - - for (std::size_t i=0; i<80; ++i) { - uint32_t f = 0; - uint32_t k = 0; - - if (i<20) { - f = (b & c) | (~b & d); - k = 0x5A827999; - } else if (i<40) { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } else if (i<60) { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } else { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; - e = d; - d = c; - c = LeftRotate(b, 30); - b = a; - a = temp; - } - - m_digest[0] += a; - m_digest[1] += b; - m_digest[2] += c; - m_digest[3] += d; - m_digest[4] += e; - } - private: - digest32_t m_digest; - uint8_t m_block[64]; - size_t m_blockByteIndex; - size_t m_byteCount; - }; -} -#endif - - - #pragma once // settings for crow // TODO - replace with runtime config. libucl? @@ -3379,6 +3382,930 @@ namespace crow +#pragma once + +#include +#include +#include +#include +#include +#include +#include + + + + +namespace crow +{ + namespace black_magic + { +#ifndef CROW_MSVC_WORKAROUND + struct OutOfRange + { + OutOfRange(unsigned /*pos*/, unsigned /*length*/) {} + }; + constexpr unsigned requires_in_range( unsigned i, unsigned len ) + { + return i >= len ? throw OutOfRange(i, len) : i; + } + + class const_str + { + const char * const begin_; + unsigned size_; + + public: + template< unsigned N > + constexpr const_str( const char(&arr)[N] ) : begin_(arr), size_(N - 1) { + static_assert( N >= 1, "not a string literal"); + } + constexpr char operator[]( unsigned i ) const { + return requires_in_range(i, size_), begin_[i]; + } + + constexpr operator const char *() const { + return begin_; + } + + constexpr const char* begin() const { return begin_; } + constexpr const char* end() const { return begin_ + size_; } + + constexpr unsigned size() const { + return size_; + } + }; + + constexpr unsigned find_closing_tag(const_str s, unsigned p) + { + return s[p] == '>' ? p : find_closing_tag(s, p+1); + } + + constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0) + { + return + i == s.size() + ? f == 0 : + f < 0 || f >= 2 + ? false : + s[i] == '<' + ? is_valid(s, i+1, f+1) : + s[i] == '>' + ? is_valid(s, i+1, f-1) : + is_valid(s, i+1, f); + } + + constexpr bool is_equ_p(const char* a, const char* b, unsigned n) + { + return + *a == 0 && *b == 0 && n == 0 + ? true : + (*a == 0 || *b == 0) + ? false : + n == 0 + ? true : + *a != *b + ? false : + is_equ_p(a+1, b+1, n-1); + } + + constexpr bool is_equ_n(const_str a, unsigned ai, const_str b, unsigned bi, unsigned n) + { + return + ai + n > a.size() || bi + n > b.size() + ? false : + n == 0 + ? true : + a[ai] != b[bi] + ? false : + is_equ_n(a,ai+1,b,bi+1,n-1); + } + + constexpr bool is_int(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 5); + } + + constexpr bool is_uint(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 6); + } + + constexpr bool is_float(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 7) || + is_equ_n(s, i, "", 0, 8); + } + + constexpr bool is_str(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 5) || + is_equ_n(s, i, "", 0, 8); + } + + constexpr bool is_path(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 6); + } +#endif + template + struct parameter_tag + { + static const int value = 0; + }; +#define CROW_INTERNAL_PARAMETER_TAG(t, i) \ +template <> \ +struct parameter_tag \ +{ \ + static const int value = i; \ +} + CROW_INTERNAL_PARAMETER_TAG(int, 1); + CROW_INTERNAL_PARAMETER_TAG(char, 1); + CROW_INTERNAL_PARAMETER_TAG(short, 1); + CROW_INTERNAL_PARAMETER_TAG(long, 1); + CROW_INTERNAL_PARAMETER_TAG(long long, 1); + CROW_INTERNAL_PARAMETER_TAG(unsigned int, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned char, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned short, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned long, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned long long, 2); + CROW_INTERNAL_PARAMETER_TAG(double, 3); + CROW_INTERNAL_PARAMETER_TAG(std::string, 4); +#undef CROW_INTERNAL_PARAMETER_TAG + template + struct compute_parameter_tag_from_args_list; + + template <> + struct compute_parameter_tag_from_args_list<> + { + static const int value = 0; + }; + + template + struct compute_parameter_tag_from_args_list + { + static const int sub_value = + compute_parameter_tag_from_args_list::value; + static const int value = + parameter_tag::type>::value + ? sub_value* 6 + parameter_tag::type>::value + : sub_value; + }; + + static inline bool is_parameter_tag_compatible(uint64_t a, uint64_t b) + { + if (a == 0) + return b == 0; + if (b == 0) + return a == 0; + int sa = a%6; + int sb = a%6; + if (sa == 5) sa = 4; + if (sb == 5) sb = 4; + if (sa != sb) + return false; + return is_parameter_tag_compatible(a/6, b/6); + } + + static inline unsigned find_closing_tag_runtime(const char* s, unsigned p) + { + return + s[p] == 0 + ? throw std::runtime_error("unmatched tag <") : + s[p] == '>' + ? p : find_closing_tag_runtime(s, p + 1); + } + + static inline uint64_t get_parameter_tag_runtime(const char* s, unsigned p = 0) + { + return + s[p] == 0 + ? 0 : + s[p] == '<' ? ( + std::strncmp(s+p, "", 5) == 0 + ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 1 : + std::strncmp(s+p, "", 6) == 0 + ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 2 : + (std::strncmp(s+p, "", 7) == 0 || + std::strncmp(s+p, "", 8) == 0) + ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 3 : + (std::strncmp(s+p, "", 5) == 0 || + std::strncmp(s+p, "", 8) == 0) + ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 4 : + std::strncmp(s+p, "", 6) == 0 + ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 5 : + throw std::runtime_error("invalid parameter type") + ) : + get_parameter_tag_runtime(s, p+1); + } +#ifndef CROW_MSVC_WORKAROUND + constexpr uint64_t get_parameter_tag(const_str s, unsigned p = 0) + { + return + p == s.size() + ? 0 : + s[p] == '<' ? ( + is_int(s, p) + ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 1 : + is_uint(s, p) + ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 2 : + is_float(s, p) + ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 3 : + is_str(s, p) + ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 4 : + is_path(s, p) + ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 5 : + throw std::runtime_error("invalid parameter type") + ) : + get_parameter_tag(s, p+1); + } +#endif + + template + struct S + { + template + using push = S; + template + using push_back = S; + template class U> + using rebind = U; + }; +template + struct CallHelper; + template + struct CallHelper> + { + template ()(std::declval()...)) + > + static char __test(int); + + template + static int __test(...); + + static constexpr bool value = sizeof(__test(0)) == sizeof(char); + }; + + + template + struct single_tag_to_type + { + }; + + template <> + struct single_tag_to_type<1> + { + using type = int64_t; + }; + + template <> + struct single_tag_to_type<2> + { + using type = uint64_t; + }; + + template <> + struct single_tag_to_type<3> + { + using type = double; + }; + + template <> + struct single_tag_to_type<4> + { + using type = std::string; + }; + + template <> + struct single_tag_to_type<5> + { + using type = std::string; + }; + + + template + struct arguments + { + using subarguments = typename arguments::type; + using type = + typename subarguments::template push::type>; + }; + + template <> + struct arguments<0> + { + using type = S<>; + }; + + template + struct last_element_type + { + using type = typename std::tuple_element>::type; + }; + + + template <> + struct last_element_type<> + { + }; + + + // from http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth + template using Invoke = typename T::type; + + template struct seq{ using type = seq; }; + + template struct concat; + + template + struct concat, seq> + : seq{}; + + template + using Concat = Invoke>; + + template struct gen_seq; + template using GenSeq = Invoke>; + + template + struct gen_seq : Concat, GenSeq>{}; + + template<> struct gen_seq<0> : seq<>{}; + template<> struct gen_seq<1> : seq<0>{}; + + template + struct pop_back_helper; + + template + struct pop_back_helper, Tuple> + { + template