提交 e56bdacd 编写于 作者: Q qicosmos

clang-format11 format code.

上级 651edc79
......@@ -95,7 +95,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>__SSE4_2__;CINATRA_ENABLE_SSL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
......
此差异已折叠。
......@@ -5,7 +5,7 @@
#ifndef CINATRA_CINATRA_HPP
#define CINATRA_CINATRA_HPP
#include "cinatra/http_server.hpp"
#include "cinatra/client_factory.hpp"
#include "cinatra/http_server.hpp"
#endif //CINATRA_CINATRA_HPP
#endif // CINATRA_CINATRA_HPP
此差异已折叠。
#pragma once
#include "http_client.hpp"
#include "async_client.hpp"
#include "http_client.hpp"
namespace cinatra {
class client_factory {
public:
static client_factory& instance() {
static client_factory instance;
return instance;
}
class client_factory {
public:
static client_factory &instance() {
static client_factory instance;
return instance;
}
template<typename...Args>
auto new_client(Args&&... args) {
return std::make_shared<http_client>(ios_, std::forward<Args>(args)...);
}
template <typename... Args> auto new_client(Args &&...args) {
return std::make_shared<http_client>(ios_, std::forward<Args>(args)...);
}
template<typename...Args>
std::shared_ptr<async_client> new_async_client(Args&& ... args) {
return std::make_shared<async_client>(ios_, std::forward<Args>(args)...);
}
template <typename... Args>
std::shared_ptr<async_client> new_async_client(Args &&...args) {
return std::make_shared<async_client>(ios_, std::forward<Args>(args)...);
}
void run() {
ios_.run();
}
void run() { ios_.run(); }
void stop() {
ios_.stop();
}
void stop() { ios_.stop(); }
private:
client_factory() : work_(ios_) {
thd_ = std::make_shared<std::thread>([this] {ios_.run(); });
}
private:
client_factory() : work_(ios_) {
thd_ = std::make_shared<std::thread>([this] { ios_.run(); });
}
~client_factory() {
ios_.stop();
thd_->join();
}
~client_factory() {
ios_.stop();
thd_->join();
}
client_factory(const client_factory&) = delete;
client_factory& operator=(const client_factory&) = delete;
client_factory(client_factory&&) = delete;
client_factory& operator=(client_factory&&) = delete;
client_factory(const client_factory &) = delete;
client_factory &operator=(const client_factory &) = delete;
client_factory(client_factory &&) = delete;
client_factory &operator=(client_factory &&) = delete;
boost::asio::io_service ios_;
boost::asio::io_service::work work_;
std::shared_ptr<std::thread> thd_;
};
boost::asio::io_service ios_;
boost::asio::io_service::work work_;
std::shared_ptr<std::thread> thd_;
};
//inline auto get(std::string uri, size_t timeout_seconds = 5) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->get(std::move(uri), timeout_seconds);
//}
// inline auto get(std::string uri, size_t timeout_seconds = 5) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->get(std::move(uri), timeout_seconds);
//}
//inline auto post(std::string uri, std::string body, size_t timeout_seconds = 5) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->post(std::move(uri), std::move(body), timeout_seconds);
//}
// inline auto post(std::string uri, std::string body, size_t timeout_seconds =
// 5) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->post(std::move(uri), std::move(body), timeout_seconds);
//}
//inline error_code async_get(std::string uri, callback_t cb) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->async_get(std::move(uri), std::move(cb));
//}
// inline error_code async_get(std::string uri, callback_t cb) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->async_get(std::move(uri), std::move(cb));
//}
//inline error_code async_post(std::string uri, std::string body, callback_t cb) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->async_post(std::move(uri), std::move(body), std::move(cb));
//}
}
\ No newline at end of file
// inline error_code async_post(std::string uri, std::string body, callback_t
// cb) {
// auto client = cinatra::client_factory::instance().new_client();
// return client->async_post(std::move(uri), std::move(body), std::move(cb));
//}
} // namespace cinatra
\ No newline at end of file
#pragma once
#include "use_asio.hpp"
#include <vector>
#include <cassert>
#include <mutex>
#include <any>
#include "define.h"
#include "http_cache.hpp"
#include "request.hpp"
#include "response.hpp"
#include "use_asio.hpp"
#include "websocket.hpp"
#include "define.h"
#include "http_cache.hpp"
#include <any>
#include <cassert>
#include <mutex>
#include <vector>
namespace cinatra {
using http_handler = std::function<void(request &, response &)>;
......@@ -85,7 +85,8 @@ public:
#else
static_assert(
!is_ssl_,
"please add definition CINATRA_ENABLE_SSL"); // guard, not allowed coming in this branch
"please add definition CINATRA_ENABLE_SSL"); // guard, not allowed
// coming in this branch
#endif
} else {
return socket_;
......@@ -180,16 +181,16 @@ public:
auto &get_tag() { return tag_; }
template <typename... Fs> void send_ws_string(std::string msg, Fs &&... fs) {
template <typename... Fs> void send_ws_string(std::string msg, Fs &&...fs) {
send_ws_msg(std::move(msg), opcode::text, std::forward<Fs>(fs)...);
}
template <typename... Fs> void send_ws_binary(std::string msg, Fs &&... fs) {
template <typename... Fs> void send_ws_binary(std::string msg, Fs &&...fs) {
send_ws_msg(std::move(msg), opcode::binary, std::forward<Fs>(fs)...);
}
template <typename... Fs>
void send_ws_msg(std::string msg, opcode op = opcode::text, Fs &&... fs) {
void send_ws_msg(std::string msg, opcode op = opcode::text, Fs &&...fs) {
constexpr const size_t size = sizeof...(Fs);
static_assert(size != 0 || size != 2);
if constexpr (size == 2) {
......@@ -333,7 +334,8 @@ private:
#else
static_assert(
!is_ssl_,
"please add definition CINATRA_ENABLE_SSL"); // guard, not allowed coming in this branch
"please add definition CINATRA_ENABLE_SSL"); // guard, not allowed
// coming in this branch
#endif
}
......@@ -393,7 +395,10 @@ private:
return;
}
}
// if (req_.get_method() == "GET"&&http_cache::get().need_cache(req_.get_url())&&!http_cache::get().not_cache(req_.get_url())) { handle_cache(); return;
// if (req_.get_method() ==
//"GET"&&http_cache::get().need_cache(req_.get_url())&&!http_cache::get().not_cache(req_.get_url()))
//{ handle_cache();
//return;
// }
req_.set_last_len(len_);
......@@ -465,7 +470,8 @@ private:
size_t left_body_len = 0;
// int index = 1;
while (true) {
// std::cout << std::this_thread::get_id() << ", index: " << index << "\n";
// std::cout << std::this_thread::get_id() << ", index: " << index <<
// "\n";
result = req_.parse_header(len_);
if (result == -1) {
return;
......@@ -571,7 +577,11 @@ private:
}
// cache
// if (req_.get_method() == "GET"&&http_cache::get().need_cache(req_.get_url()) && !http_cache::get().not_cache(req_.get_url())) { auto raw_url = req_.raw_url(); http_cache::get().add(std::string(raw_url.data(), raw_url.length()), res_.raw_content());
// if (req_.get_method() ==
//"GET"&&http_cache::get().need_cache(req_.get_url()) &&
//!http_cache::get().not_cache(req_.get_url())) { auto raw_url =
//req_.raw_url(); http_cache::get().add(std::string(raw_url.data(),
//raw_url.length()), res_.raw_content());
// }
boost::asio::async_write(
......@@ -648,7 +658,8 @@ private:
/****************** begin handle http body data *****************/
void handle_string_body(std::size_t bytes_transferred) {
// defalt add limitation for string_body and else. you can remove the limitation for very big string.
// defalt add limitation for string_body and else. you can remove the
// limitation for very big string.
if (req_.at_capacity()) {
response_back(status_type::bad_request,
"The request is too long, limitation is 3M");
......@@ -1191,7 +1202,8 @@ private:
}
//-------------web socket----------------//
//-------------chunked(read chunked not support yet, write chunked is ok)----------------------//
//-------------chunked(read chunked not support yet, write chunked is
//ok)----------------------//
void handle_chunked(size_t bytes_transferred) {
int ret = req_.parse_chunked(bytes_transferred);
if (ret == parse_status::has_error) {
......@@ -1208,7 +1220,8 @@ private:
req_.set_state(data_proc_state::data_continue);
call_back(); // app set the data
}
//-------------chunked(read chunked not support yet, write chunked is ok)----------------------//
//-------------chunked(read chunked not support yet, write chunked is
//ok)----------------------//
void handle_body() {
if (req_.at_capacity()) {
......@@ -1398,4 +1411,4 @@ inline constexpr data_proc_state ws_open = data_proc_state::data_begin;
inline constexpr data_proc_state ws_message = data_proc_state::data_continue;
inline constexpr data_proc_state ws_close = data_proc_state::data_close;
inline constexpr data_proc_state ws_error = data_proc_state::data_error;
}
} // namespace cinatra
#pragma once
#include <string>
#include "utils.hpp"
#include <string>
namespace cinatra {
class cookie {
public:
cookie() = default;
cookie(const std::string& name, const std::string& value) : name_(name), value_(value) {
}
void set_version(int version) {
version_ = version;
}
void set_name(const std::string& name) {
name_ = name;
}
std::string get_name() const {
return name_;
}
void set_value(const std::string& value) {
value_ = value;
}
std::string get_value() const {
return value_;
}
void set_comment(const std::string& comment) {
comment_ = comment;
}
void set_domain(const std::string& domain) {
domain_ = domain;
}
void set_path(const std::string& path) {
path_ = path;
}
void set_priority(const std::string& priority) {
priority_ = priority;
}
void set_secure(bool secure) {
secure_ = secure;
}
void set_max_age(std::time_t seconds) {
max_age_ = seconds;
}
void set_http_only(bool http_only) {
http_only_ = http_only;
}
std::string to_string() const {
std::string result;
result.reserve(256);
result.append(name_);
result.append("=");
if (version_ == 0)
{
// Netscape cookie
result.append(value_);
if (!path_.empty())
{
result.append("; path=");
result.append(path_);
}
if (!priority_.empty())
{
result.append("; Priority=");
result.append(priority_);
}
if (max_age_ != -1)
{
result.append("; expires=");
result.append(get_gmt_time_str(max_age_));
}
if (secure_)
{
result.append("; secure");
}
if (http_only_)
{
result.append("; HttpOnly");
}
}
else
{
// RFC 2109 cookie
result.append("\"");
result.append(value_);
result.append("\"");
if (!comment_.empty())
{
result.append("; Comment=\"");
result.append(comment_);
result.append("\"");
}
if (!path_.empty())
{
result.append("; Path=\"");
result.append(path_);
result.append("\"");
}
if (!priority_.empty())
{
result.append("; Priority=\"");
result.append(priority_);
result.append("\"");
}
if (max_age_ != -1)
{
result.append("; Max-Age=\"");
result.append(std::to_string(max_age_));
result.append("\"");
}
if (secure_)
{
result.append("; secure");
}
if (http_only_)
{
result.append("; HttpOnly");
}
result.append("; Version=\"1\"");
}
return result;
}
private:
int version_ = 0;
std::string name_ = "";
std::string value_ = "";
std::string comment_ = "";
std::string domain_ = "";
std::string path_ = "";
std::string priority_ = "";
bool secure_ = false;
std::time_t max_age_ = -1;
bool http_only_ = false;
};
}
class cookie {
public:
cookie() = default;
cookie(const std::string &name, const std::string &value)
: name_(name), value_(value) {}
void set_version(int version) { version_ = version; }
void set_name(const std::string &name) { name_ = name; }
std::string get_name() const { return name_; }
void set_value(const std::string &value) { value_ = value; }
std::string get_value() const { return value_; }
void set_comment(const std::string &comment) { comment_ = comment; }
void set_domain(const std::string &domain) { domain_ = domain; }
void set_path(const std::string &path) { path_ = path; }
void set_priority(const std::string &priority) { priority_ = priority; }
void set_secure(bool secure) { secure_ = secure; }
void set_max_age(std::time_t seconds) { max_age_ = seconds; }
void set_http_only(bool http_only) { http_only_ = http_only; }
std::string to_string() const {
std::string result;
result.reserve(256);
result.append(name_);
result.append("=");
if (version_ == 0) {
// Netscape cookie
result.append(value_);
if (!path_.empty()) {
result.append("; path=");
result.append(path_);
}
if (!priority_.empty()) {
result.append("; Priority=");
result.append(priority_);
}
if (max_age_ != -1) {
result.append("; expires=");
result.append(get_gmt_time_str(max_age_));
}
if (secure_) {
result.append("; secure");
}
if (http_only_) {
result.append("; HttpOnly");
}
} else {
// RFC 2109 cookie
result.append("\"");
result.append(value_);
result.append("\"");
if (!comment_.empty()) {
result.append("; Comment=\"");
result.append(comment_);
result.append("\"");
}
if (!path_.empty()) {
result.append("; Path=\"");
result.append(path_);
result.append("\"");
}
if (!priority_.empty()) {
result.append("; Priority=\"");
result.append(priority_);
result.append("\"");
}
if (max_age_ != -1) {
result.append("; Max-Age=\"");
result.append(std::to_string(max_age_));
result.append("\"");
}
if (secure_) {
result.append("; secure");
}
if (http_only_) {
result.append("; HttpOnly");
}
result.append("; Version=\"1\"");
}
return result;
}
private:
int version_ = 0;
std::string name_ = "";
std::string value_ = "";
std::string comment_ = "";
std::string domain_ = "";
std::string path_ = "";
std::string priority_ = "";
bool secure_ = false;
std::time_t max_age_ = -1;
bool http_only_ = false;
};
} // namespace cinatra
#pragma once
#if defined (__GNUC__)
#if defined(__GNUC__)
#if __GNUC__ < 8
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
......@@ -13,37 +13,32 @@ namespace fs = std::filesystem;
#endif
namespace cinatra {
enum class content_type {
string,
multipart,
urlencoded,
chunked,
octet_stream,
websocket,
unknown,
};
enum class content_type {
string,
multipart,
urlencoded,
chunked,
octet_stream,
websocket,
unknown,
};
enum class req_content_type{
html,
json,
string,
multipart,
none
};
enum class req_content_type { html, json, string, multipart, none };
constexpr inline auto HTML = req_content_type::html;
constexpr inline auto JSON = req_content_type::json;
constexpr inline auto TEXT = req_content_type::string;
constexpr inline auto NONE = req_content_type::none;
constexpr inline auto HTML = req_content_type::html;
constexpr inline auto JSON = req_content_type::json;
constexpr inline auto TEXT = req_content_type::string;
constexpr inline auto NONE = req_content_type::none;
inline const std::string_view STATIC_RESOURCE = "cinatra_static_resource";
inline const std::string CSESSIONID = "CSESSIONID";
inline const std::string_view STATIC_RESOURCE = "cinatra_static_resource";
inline const std::string CSESSIONID = "CSESSIONID";
const static inline std::string CRCF = "\r\n";
const static inline std::string TWO_CRCF = "\r\n\r\n";
const static inline std::string BOUNDARY = "--CinatraBoundary2B8FAF4A80EDB307";
const static inline std::string MULTIPART_END = CRCF + "--" + BOUNDARY + "--" + TWO_CRCF;
const static inline std::string CRCF = "\r\n";
const static inline std::string TWO_CRCF = "\r\n\r\n";
const static inline std::string BOUNDARY = "--CinatraBoundary2B8FAF4A80EDB307";
const static inline std::string MULTIPART_END =
CRCF + "--" + BOUNDARY + "--" + TWO_CRCF;
struct NonSSL {};
struct SSL {};
}
struct NonSSL {};
struct SSL {};
} // namespace cinatra
-----BEGIN DH PARAMETERS-----
MIGHAoGBAKkQmvrDWq/HYZy8tkXIEOHb1EnViMz+hLmjx64Bv4QF+B6e3dXjbUf5
gzlvFMFs1bY35XA3oRW//Qp5Jkj9Mz+VM/FYuZr8MYJosxIRlAPSVYQs6W4FqwK8
MhezkO2Pt6KhKrUUO7IjLY84pmoo9d8f+DLZi9opBdEKBX6Qd28LAgEC
-----END DH PARAMETERS-----
-----BEGIN DH PARAMETERS-- ---MIGHAoGBAKkQmvrDWq / HYZy8tkXIEOHb1EnViMz +
hLmjx64Bv4QF +
B6e3dXjbUf5
gzlvFMFs1bY35XA3oRW // Qp5Jkj9Mz+VM/FYuZr8MYJosxIRlAPSVYQs6W4FqwK8
MhezkO2Pt6KhKrUUO7IjLY84pmoo9d8f +
DLZi9opBdEKBX6Qd28LAgEC-- ---END DH PARAMETERS-- ---
#pragma once
#include <type_traits>
#include <functional>
#include <tuple>
#include <type_traits>
//member function
#define TIMAX_FUNCTION_TRAITS(...)\
template <typename ReturnType, typename ClassType, typename... Args>\
struct function_traits_impl<ReturnType(ClassType::*)(Args...) __VA_ARGS__> : function_traits_impl<ReturnType(Args...)>{};\
// member function
#define TIMAX_FUNCTION_TRAITS(...) \
template <typename ReturnType, typename ClassType, typename... Args> \
struct function_traits_impl<ReturnType (ClassType::*)(Args...) __VA_ARGS__> \
: function_traits_impl<ReturnType(Args...)> {};
namespace timax
{
/*
* 1. function type ==> Ret(Args...)
* 2. function pointer ==> Ret(*)(Args...)
* 3. function reference ==> Ret(&)(Args...)
* 4. pointer to non-static member function ==> Ret(T::*)(Args...)
* 5. function object and functor ==> &T::operator()
* 6. function with generic operator call ==> template <typeanme ... Args> &T::operator()
*/
template <typename T>
struct function_traits_impl;
namespace timax {
/*
* 1. function type ==>
* Ret(Args...)
* 2. function pointer ==>
* Ret(*)(Args...)
* 3. function reference ==>
* Ret(&)(Args...)
* 4. pointer to non-static member function ==> Ret(T::*)(Args...)
* 5. function object and functor ==> &T::operator()
* 6. function with generic operator call ==> template <typeanme ...
* Args> &T::operator()
*/
template <typename T> struct function_traits_impl;
template<typename T>
struct function_traits : function_traits_impl<
std::remove_cv_t<std::remove_reference_t<T>>>
{};
template <typename T>
struct function_traits
: function_traits_impl<std::remove_cv_t<std::remove_reference_t<T>>> {};
template<typename Ret, typename... Args>
struct function_traits_impl<Ret(Args...)>
{
public:
enum { arity = sizeof...(Args) };
typedef Ret function_type(Args...);
typedef Ret result_type;
using stl_function_type = std::function<function_type>;
typedef Ret(*pointer)(Args...);
template <typename Ret, typename... Args>
struct function_traits_impl<Ret(Args...)> {
public:
enum { arity = sizeof...(Args) };
typedef Ret function_type(Args...);
typedef Ret result_type;
using stl_function_type = std::function<function_type>;
typedef Ret (*pointer)(Args...);
template<size_t I>
struct args
{
static_assert(I < arity, "index is out of range, index must less than sizeof Args");
using type = typename std::tuple_element<I, std::tuple<Args...>>::type;
};
template <size_t I> struct args {
static_assert(I < arity,
"index is out of range, index must less than sizeof Args");
using type = typename std::tuple_element<I, std::tuple<Args...>>::type;
};
typedef std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...> tuple_type;
using args_type_t = std::tuple<Args...>;
};
typedef std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>
tuple_type;
using args_type_t = std::tuple<Args...>;
};
template<size_t I, typename Function>
using arg_type = typename function_traits<Function>::template args<I>::type;
template <size_t I, typename Function>
using arg_type = typename function_traits<Function>::template args<I>::type;
// function pointer
template<typename Ret, typename... Args>
struct function_traits_impl<Ret(*)(Args...)> : function_traits<Ret(Args...)> {};
// function pointer
template <typename Ret, typename... Args>
struct function_traits_impl<Ret (*)(Args...)> : function_traits<Ret(Args...)> {
};
// std::function
template <typename Ret, typename... Args>
struct function_traits_impl<std::function<Ret(Args...)>> : function_traits_impl<Ret(Args...)> {};
// std::function
template <typename Ret, typename... Args>
struct function_traits_impl<std::function<Ret(Args...)>>
: function_traits_impl<Ret(Args...)> {};
// pointer of non-static member function
TIMAX_FUNCTION_TRAITS()
TIMAX_FUNCTION_TRAITS(const)
TIMAX_FUNCTION_TRAITS(volatile)
TIMAX_FUNCTION_TRAITS(const volatile)
// pointer of non-static member function
TIMAX_FUNCTION_TRAITS()
TIMAX_FUNCTION_TRAITS(const)
TIMAX_FUNCTION_TRAITS(volatile)
TIMAX_FUNCTION_TRAITS(const volatile)
// functor
template<typename Callable>
struct function_traits_impl : function_traits_impl<decltype(&Callable::operator())> {};
// functor
template <typename Callable>
struct function_traits_impl
: function_traits_impl<decltype(&Callable::operator())> {};
template <typename Function>
typename function_traits<Function>::stl_function_type to_function(const Function& lambda)
{
return static_cast<typename function_traits<Function>::stl_function_type>(lambda);
}
template <typename Function>
typename function_traits<Function>::stl_function_type
to_function(const Function &lambda) {
return static_cast<typename function_traits<Function>::stl_function_type>(
lambda);
}
template <typename Function>
typename function_traits<Function>::stl_function_type to_function(Function&& lambda)
{
return static_cast<typename function_traits<Function>::stl_function_type>(std::forward<Function>(lambda));
}
template <typename Function>
typename function_traits<Function>::stl_function_type
to_function(Function &&lambda) {
return static_cast<typename function_traits<Function>::stl_function_type>(
std::forward<Function>(lambda));
}
template <typename Function>
typename function_traits<Function>::pointer to_function_pointer(const Function& lambda)
{
return static_cast<typename function_traits<Function>::pointer>(lambda);
}
template <typename Function>
typename function_traits<Function>::pointer
to_function_pointer(const Function &lambda) {
return static_cast<typename function_traits<Function>::pointer>(lambda);
}
} // namespace timax
#pragma once
#include <zlib.h>
#include <string_view>
#include <zlib.h>
namespace cinatra::gzip_codec {
//from https://github.com/chafey/GZipCodec
// from https://github.com/chafey/GZipCodec
#define CHUNK 16384
#define windowBits 15
#define GZIP_ENCODING 16
// GZip Compression
// @param data - the data to compress (does not have to be string, can be binary data)
// @param compressed_data - the resulting gzip compressed data
// @param level - the gzip compress level -1 = default, 0 = no compression, 1= worst/fastest compression, 9 = best/slowest compression
// @return - true on success, false on failure
inline bool compress(std::string_view data, std::string& compressed_data, int level = -1) {
unsigned char out[CHUNK];
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
if (deflateInit2(&strm, level, Z_DEFLATED, windowBits | GZIP_ENCODING, 8, Z_DEFAULT_STRATEGY) != Z_OK)
{
return false;
}
strm.next_in = (unsigned char*)data.data();
strm.avail_in = (uInt)data.length();
do {
int have;
strm.avail_out = CHUNK;
strm.next_out = out;
if (deflate(&strm, Z_FINISH) == Z_STREAM_ERROR)
{
return false;
}
have = CHUNK - strm.avail_out;
compressed_data.append((char*)out, have);
} while (strm.avail_out == 0);
if (deflateEnd(&strm) != Z_OK)
{
return false;
}
return true;
}
// GZip Compression
// @param data - the data to compress (does not have to be string, can be binary
// data)
// @param compressed_data - the resulting gzip compressed data
// @param level - the gzip compress level -1 = default, 0 = no compression, 1=
// worst/fastest compression, 9 = best/slowest compression
// @return - true on success, false on failure
inline bool compress(std::string_view data, std::string &compressed_data,
int level = -1) {
unsigned char out[CHUNK];
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
if (deflateInit2(&strm, level, Z_DEFLATED, windowBits | GZIP_ENCODING, 8,
Z_DEFAULT_STRATEGY) != Z_OK) {
return false;
}
strm.next_in = (unsigned char *)data.data();
strm.avail_in = (uInt)data.length();
do {
int have;
strm.avail_out = CHUNK;
strm.next_out = out;
if (deflate(&strm, Z_FINISH) == Z_STREAM_ERROR) {
return false;
}
have = CHUNK - strm.avail_out;
compressed_data.append((char *)out, have);
} while (strm.avail_out == 0);
if (deflateEnd(&strm) != Z_OK) {
return false;
}
return true;
}
// GZip Decompression
// @param compressed_data - the gzip compressed data
// @param data - the resulting uncompressed data (may contain binary data)
// @return - true on success, false on failure
inline bool uncompress(std::string_view compressed_data, std::string& data) {
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
// GZip Decompression
// @param compressed_data - the gzip compressed data
// @param data - the resulting uncompressed data (may contain binary data)
// @return - true on success, false on failure
inline bool uncompress(std::string_view compressed_data, std::string &data) {
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if (inflateInit2(&strm, 16 + MAX_WBITS) != Z_OK)
{
return false;
}
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if (inflateInit2(&strm, 16 + MAX_WBITS) != Z_OK) {
return false;
}
strm.avail_in = (uInt)compressed_data.length();
strm.next_in = (unsigned char*)compressed_data.data();
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
return false;
}
have = CHUNK - strm.avail_out;
data.append((char*)out, have);
} while (strm.avail_out == 0);
strm.avail_in = (uInt)compressed_data.length();
strm.next_in = (unsigned char *)compressed_data.data();
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
switch (ret) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
return false;
}
have = CHUNK - strm.avail_out;
data.append((char *)out, have);
} while (strm.avail_out == 0);
if (inflateEnd(&strm) != Z_OK) {
return false;
}
if (inflateEnd(&strm) != Z_OK) {
return false;
}
return true;
}
return true;
}
inline int compress_file(const char* src_file, const char * out_file_name)
{
char buf[BUFSIZ] = { 0 };
uInt bytes_read = 0;
gzFile out = gzopen(out_file_name, "wb");
if (!out)
{
return -1;
}
inline int compress_file(const char *src_file, const char *out_file_name) {
char buf[BUFSIZ] = {0};
uInt bytes_read = 0;
gzFile out = gzopen(out_file_name, "wb");
if (!out) {
return -1;
}
std::ifstream in(src_file, std::ios::binary);
if (!in.is_open()) {
return -1;
}
std::ifstream in(src_file, std::ios::binary);
if (!in.is_open()) {
return -1;
}
while (true)
{
in.read(buf, BUFSIZ);
bytes_read = (uInt)in.gcount();
if (bytes_read == 0)
break;
int bytes_written = gzwrite(out, buf, bytes_read);
if (bytes_written == 0)
{
gzclose(out);
return -1;
}
if (bytes_read != BUFSIZ)
break;
}
gzclose(out);
while (true) {
in.read(buf, BUFSIZ);
bytes_read = (uInt)in.gcount();
if (bytes_read == 0)
break;
int bytes_written = gzwrite(out, buf, bytes_read);
if (bytes_written == 0) {
gzclose(out);
return -1;
}
if (bytes_read != BUFSIZ)
break;
}
gzclose(out);
return 0;
}
return 0;
}
inline int uncompress_file(const char* src_file, const char * out_file_name) {
char buf[BUFSIZ] = { 0 };
std::ofstream out(out_file_name, std::ios::binary);
if (!out.is_open()) {
return -1;
}
inline int uncompress_file(const char *src_file, const char *out_file_name) {
char buf[BUFSIZ] = {0};
std::ofstream out(out_file_name, std::ios::binary);
if (!out.is_open()) {
return -1;
}
gzFile fi = gzopen(src_file, "rb");
if (!fi)
{
return -1;
}
gzFile fi = gzopen(src_file, "rb");
if (!fi) {
return -1;
}
gzrewind(fi);
while (!gzeof(fi))
{
int len = gzread(fi, buf, BUFSIZ);
out.write(buf, len);
}
gzclose(fi);
gzrewind(fi);
while (!gzeof(fi)) {
int len = gzread(fi, buf, BUFSIZ);
out.write(buf, len);
}
gzclose(fi);
return 0;
}
}
\ No newline at end of file
return 0;
}
} // namespace cinatra::gzip_codec
\ No newline at end of file
#pragma once
#include "use_asio.hpp"
#include <mutex>
#include <string>
#include <string_view>
#include <mutex>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "use_asio.hpp"
namespace cinatra {
constexpr const size_t MAX_CACHE_SIZE = 100000;
class http_cache {
public:
static http_cache& get(){
static http_cache instance;
return instance;
}
void add(const std::string& key, const std::vector<std::string>& content) {
std::unique_lock<std::mutex> lock(mtx_);
if (std::distance(cur_it_, cache_.end()) > MAX_CACHE_SIZE) {
cur_it_ = cache_.begin();
}
cur_it_ = cache_.emplace(key, content).first;
cache_time_[key] = std::time(nullptr) + max_cache_age_;
}
std::vector<std::string> get(const std::string& key) {
std::unique_lock<std::mutex> lock(mtx_);
auto time_it = cache_time_.find(key);
auto it = cache_.find(key);
auto now_time = std::time(nullptr);
if(time_it != cache_time_.end() && time_it->second >= now_time){
return it == cache_.end() ? std::vector<std::string>{} : it->second;
}else{
if(time_it != cache_time_.end() && it != cache_.end()){
cur_it_ = cache_.erase(it);
}
return std::vector<std::string>{};
}
}
bool empty() {
return cache_.empty();
}
void update(const std::string& key) {
std::unique_lock<std::mutex> lock(mtx_);
auto it = cache_.find(key);
if (it != cache_.end())
cache_.erase(it);
}
void add_skip(std::string_view key) {
skip_cache_.emplace(key);
}
void add_single_cache(std::string_view key)
{
need_single_cache_.emplace(key);
}
void enable_cache(bool b) {
need_cache_ = b;
}
bool need_cache(std::string_view key) {
if(need_cache_){
return need_cache_;
}else{
return need_single_cache_.find(key)!= need_single_cache_.end();
}
}
bool not_cache(std::string_view key) {
return skip_cache_.find(key) != skip_cache_.end();
}
void set_cache_max_age(std::time_t seconds)
{
max_cache_age_ = seconds;
}
std::time_t get_cache_max_age()
{
return max_cache_age_;
}
private:
http_cache() {};
http_cache(const http_cache&) = delete;
http_cache(http_cache&&) = delete;
std::mutex mtx_;
bool need_cache_ = false;
std::unordered_map<std::string, std::vector<std::string>> cache_;
std::unordered_map<std::string, std::vector<std::string>>::iterator cur_it_ = http_cache::cache_.begin();
std::unordered_set<std::string_view> skip_cache_;
std::unordered_set<std::string_view> need_single_cache_;
std::time_t max_cache_age_ = 0;
std::unordered_map<std::string, std::time_t > cache_time_;
};
}
\ No newline at end of file
constexpr const size_t MAX_CACHE_SIZE = 100000;
class http_cache {
public:
static http_cache &get() {
static http_cache instance;
return instance;
}
void add(const std::string &key, const std::vector<std::string> &content) {
std::unique_lock<std::mutex> lock(mtx_);
if (std::distance(cur_it_, cache_.end()) > MAX_CACHE_SIZE) {
cur_it_ = cache_.begin();
}
cur_it_ = cache_.emplace(key, content).first;
cache_time_[key] = std::time(nullptr) + max_cache_age_;
}
std::vector<std::string> get(const std::string &key) {
std::unique_lock<std::mutex> lock(mtx_);
auto time_it = cache_time_.find(key);
auto it = cache_.find(key);
auto now_time = std::time(nullptr);
if (time_it != cache_time_.end() && time_it->second >= now_time) {
return it == cache_.end() ? std::vector<std::string>{} : it->second;
} else {
if (time_it != cache_time_.end() && it != cache_.end()) {
cur_it_ = cache_.erase(it);
}
return std::vector<std::string>{};
}
}
bool empty() { return cache_.empty(); }
void update(const std::string &key) {
std::unique_lock<std::mutex> lock(mtx_);
auto it = cache_.find(key);
if (it != cache_.end())
cache_.erase(it);
}
void add_skip(std::string_view key) { skip_cache_.emplace(key); }
void add_single_cache(std::string_view key) {
need_single_cache_.emplace(key);
}
void enable_cache(bool b) { need_cache_ = b; }
bool need_cache(std::string_view key) {
if (need_cache_) {
return need_cache_;
} else {
return need_single_cache_.find(key) != need_single_cache_.end();
}
}
bool not_cache(std::string_view key) {
return skip_cache_.find(key) != skip_cache_.end();
}
void set_cache_max_age(std::time_t seconds) { max_cache_age_ = seconds; }
std::time_t get_cache_max_age() { return max_cache_age_; }
private:
http_cache(){};
http_cache(const http_cache &) = delete;
http_cache(http_cache &&) = delete;
std::mutex mtx_;
bool need_cache_ = false;
std::unordered_map<std::string, std::vector<std::string>> cache_;
std::unordered_map<std::string, std::vector<std::string>>::iterator cur_it_ =
http_cache::cache_.begin();
std::unordered_set<std::string_view> skip_cache_;
std::unordered_set<std::string_view> need_single_cache_;
std::time_t max_cache_age_ = 0;
std::unordered_map<std::string, std::time_t> cache_time_;
};
} // namespace cinatra
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
#pragma once
#include "use_asio.hpp"
#include <string>
#include <vector>
#include <string_view>
#include <vector>
#include "io_service_pool.hpp"
#include "connection.hpp"
#include "http_router.hpp"
#include "router.hpp"
#include "cookie.hpp"
#include "function_traits.hpp"
#include "url_encode_decode.hpp"
#include "http_cache.hpp"
#include "http_router.hpp"
#include "io_service_pool.hpp"
#include "router.hpp"
#include "session_manager.hpp"
#include "cookie.hpp"
#include "url_encode_decode.hpp"
namespace cinatra {
......@@ -27,7 +27,7 @@ class http_server_ : private noncopyable {
public:
using type = ScoketType;
template <class... Args>
explicit http_server_(Args &&... args)
explicit http_server_(Args &&...args)
: io_service_pool_(std::forward<Args>(args)...) {
http_cache::get().set_cache_max_age(86400);
init_conn_callback();
......@@ -167,9 +167,10 @@ public:
// set http handlers
template <http_method... Is, typename Function, typename... AP>
void set_http_handler(std::string_view name, Function &&f, AP &&... ap) {
void set_http_handler(std::string_view name, Function &&f, AP &&...ap) {
if constexpr (has_type<enable_cache<bool>,
std::tuple<std::decay_t<AP>...>>::value) { // for cache
std::tuple<std::decay_t<AP>...>>::value) { // for
// cache
bool b = false;
((!b && (b = need_cache(std::forward<AP>(ap)))), ...);
if (!b) {
......@@ -429,7 +430,8 @@ private:
void write_ranges_header(request &req, std::string_view mime,
std::string filename, std::string file_size) {
std::string header_str = "HTTP/1.1 200 OK\r\nAccess-Control-Allow-origin: *\r\nAccept-Ranges: bytes\r\n";
std::string header_str = "HTTP/1.1 200 OK\r\nAccess-Control-Allow-origin: "
"*\r\nAccept-Ranges: bytes\r\n";
header_str.append("Content-Disposition: attachment;filename=");
header_str.append(std::move(filename)).append("\r\n");
header_str.append("Connection: keep-alive\r\n");
......@@ -555,4 +557,4 @@ using http_server_proxy = http_server_<T, io_service_pool>;
using http_server = http_server_proxy<NonSSL>;
using http_ssl_server = http_server_proxy<SSL>;
}
} // namespace cinatra
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册