Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
NetWork
Cinatra
提交
e56bdacd
C
Cinatra
项目概览
NetWork
/
Cinatra
通知
5
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Cinatra
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
e56bdacd
编写于
4月 18, 2021
作者:
Q
qicosmos
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
clang-format11 format code.
上级
651edc79
变更
43
展开全部
隐藏空白更改
内联
并排
Showing
43 changed file
with
26476 addition
and
27384 deletion
+26476
-27384
example/example.vcxproj
example/example.vcxproj
+1
-1
example/main.cpp
example/main.cpp
+238
-212
include/cinatra.hpp
include/cinatra.hpp
+2
-2
include/cinatra/async_client.hpp
include/cinatra/async_client.hpp
+465
-442
include/cinatra/client_factory.hpp
include/cinatra/client_factory.hpp
+51
-54
include/cinatra/connection.hpp
include/cinatra/connection.hpp
+32
-19
include/cinatra/cookie.hpp
include/cinatra/cookie.hpp
+107
-146
include/cinatra/define.h
include/cinatra/define.h
+25
-30
include/cinatra/dh1024.pem
include/cinatra/dh1024.pem
+6
-5
include/cinatra/function_traits.hpp
include/cinatra/function_traits.hpp
+76
-70
include/cinatra/gzip.hpp
include/cinatra/gzip.hpp
+121
-127
include/cinatra/http_cache.hpp
include/cinatra/http_cache.hpp
+86
-98
include/cinatra/http_client.hpp
include/cinatra/http_client.hpp
+1087
-972
include/cinatra/http_parser.hpp
include/cinatra/http_parser.hpp
+107
-114
include/cinatra/http_router.hpp
include/cinatra/http_router.hpp
+236
-210
include/cinatra/http_server.hpp
include/cinatra/http_server.hpp
+13
-11
include/cinatra/io_service_pool.hpp
include/cinatra/io_service_pool.hpp
+90
-110
include/cinatra/itoa.hpp
include/cinatra/itoa.hpp
+223
-234
include/cinatra/itoa_jeaiii.hpp
include/cinatra/itoa_jeaiii.hpp
+81
-63
include/cinatra/mime_types.hpp
include/cinatra/mime_types.hpp
+503
-501
include/cinatra/modern_callback.h
include/cinatra/modern_callback.h
+52
-41
include/cinatra/multipart_parser.hpp
include/cinatra/multipart_parser.hpp
+414
-443
include/cinatra/multipart_reader.hpp
include/cinatra/multipart_reader.hpp
+123
-123
include/cinatra/nlohmann_json.hpp
include/cinatra/nlohmann_json.hpp
+18504
-19507
include/cinatra/picohttpparser.h
include/cinatra/picohttpparser.h
+557
-528
include/cinatra/render.h
include/cinatra/render.h
+713
-768
include/cinatra/request.hpp
include/cinatra/request.hpp
+11
-13
include/cinatra/response.hpp
include/cinatra/response.hpp
+10
-10
include/cinatra/response_cv.hpp
include/cinatra/response_cv.hpp
+408
-370
include/cinatra/response_parser.hpp
include/cinatra/response_parser.hpp
+205
-224
include/cinatra/router.hpp
include/cinatra/router.hpp
+65
-68
include/cinatra/server.crt
include/cinatra/server.crt
+18
-16
include/cinatra/server.key
include/cinatra/server.key
+20
-17
include/cinatra/session.hpp
include/cinatra/session.hpp
+69
-88
include/cinatra/session_manager.hpp
include/cinatra/session_manager.hpp
+70
-68
include/cinatra/sha1.hpp
include/cinatra/sha1.hpp
+222
-229
include/cinatra/upload_file.hpp
include/cinatra/upload_file.hpp
+87
-91
include/cinatra/uri.hpp
include/cinatra/uri.hpp
+275
-267
include/cinatra/url_encode_decode.hpp
include/cinatra/url_encode_decode.hpp
+54
-51
include/cinatra/use_asio.hpp
include/cinatra/use_asio.hpp
+9
-11
include/cinatra/utils.hpp
include/cinatra/utils.hpp
+657
-660
include/cinatra/websocket.hpp
include/cinatra/websocket.hpp
+244
-241
include/cinatra/ws_define.h
include/cinatra/ws_define.h
+139
-129
未找到文件。
example/example.vcxproj
浏览文件 @
e56bdacd
...
...
@@ -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'"
>
...
...
example/main.cpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra.hpp
浏览文件 @
e56bdacd
...
...
@@ -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
include/cinatra/async_client.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/client_factory.hpp
浏览文件 @
e56bdacd
#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
include/cinatra/connection.hpp
浏览文件 @
e56bdacd
#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
include/cinatra/cookie.hpp
浏览文件 @
e56bdacd
#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
include/cinatra/define.h
浏览文件 @
e56bdacd
#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
include/cinatra/dh1024.pem
浏览文件 @
e56bdacd
-----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-- ---
include/cinatra/function_traits.hpp
浏览文件 @
e56bdacd
#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
include/cinatra/gzip.hpp
浏览文件 @
e56bdacd
#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
include/cinatra/http_cache.hpp
浏览文件 @
e56bdacd
#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
include/cinatra/http_client.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/http_parser.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/http_router.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/http_server.hpp
浏览文件 @
e56bdacd
#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 "
cooki
e.hpp"
#include "
url_encode_decod
e.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\n
Access-Control-Allow-origin: *
\r\n
Accept-Ranges: bytes
\r\n
"
;
std
::
string
header_str
=
"HTTP/1.1 200 OK
\r\n
Access-Control-Allow-origin: "
"*
\r\n
Accept-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
include/cinatra/io_service_pool.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/itoa.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/itoa_jeaiii.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/mime_types.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/modern_callback.h
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/multipart_parser.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/multipart_reader.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/nlohmann_json.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/picohttpparser.h
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/render.h
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/request.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/response.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/response_cv.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/response_parser.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/router.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/server.crt
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/server.key
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/session.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/session_manager.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/sha1.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/upload_file.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/uri.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/url_encode_decode.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/use_asio.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/utils.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/websocket.hpp
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
include/cinatra/ws_define.h
浏览文件 @
e56bdacd
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录