forked from skyfireitdiy/sflib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsf_http_base_server.h
163 lines (127 loc) · 7.07 KB
/
sf_http_base_server.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
* @version 1.0.0
* @author skyfire
* @mail [email protected]
* @see http://github.com/skyfireitdiy/sflib
* @file sf_http_base_server.h
* sflib第一版本发布
* 版本号1.0.0
* 发布日期:2018-10-22
*/
#pragma once
#include <functional>
#include <vector>
#include "sf_eventloop.h"
#include "sf_tcp_server.h"
#include "sf_logger.h"
#include "sf_object.h"
#include "sf_http_request.h"
#include "sf_http_response.h"
#include "sf_http_utils.h"
#include "sf_websocket_utils.h"
#include "sf_logger.h"
#include "sf_http_server_config.h"
#include <utility>
#include <mutex>
namespace skyfire {
/**
* @brief HTTP服务器基础框架
*/
class sf_http_base_server {
private:
const sf_http_server_config config__;
std::shared_ptr<sf_tcp_server> server__ = std::make_shared<sf_tcp_server>(true);
std::function<void(const sf_http_request&,sf_http_response&)> request_callback__;
std::function<void(const sf_http_request&,sf_http_response&)> websocket_request_callback__;
std::function<void(SOCKET,const std::string &url,const byte_array& data)> websocket_binary_data_callback__;
std::function<void(SOCKET,const std::string &url,const std::string& data)> websocket_text_data_callback__;
std::function<void(SOCKET,const std::string &url)> websocket_open_callback__;
std::function<void(SOCKET,const std::string &url)> websocket_close_callback__;
std::unordered_map<SOCKET, sf_request_context_t> request_context__;
std::recursive_mutex mu_request_context__;
std::unordered_map<SOCKET, sf_websocket_context_t> websocket_context__;
std::recursive_mutex mu_websocket_context__;
std::unordered_map<SOCKET, sf_multipart_data_context_t> multipart_data_context__;
std::recursive_mutex mu_multipart_data_context__;
void raw_data_coming__(SOCKET sock, const byte_array &data);
template <typename T>
bool analysis_websocket_pkg__(SOCKET sock, const T *header, int &resolve_pos, unsigned long long &len,
byte_array &body, bool &fin, int &op_code);
void websocket_data_coming__(SOCKET sock, const byte_array &data);
void build_new_request__(SOCKET sock);
void on_socket_closed__(SOCKET sock);
byte_array append_multipart_data__(sf_multipart_data_context_t &multipart_data, const byte_array &data);
void file_response__(SOCKET sock, sf_http_response &res) ;
void normal_response__(SOCKET sock, sf_http_response &res) ;
void multipart_response__(SOCKET sock, sf_http_response &res) ;
static bool check_analysis_multipart_file__(std::vector<sf_http_response::multipart_info_t>& multipart_data);
void close_request__(SOCKET sock) ;
void http_handler__(SOCKET sock, sf_http_request http_request);
void build_boundary_context_data(SOCKET sock, const sf_http_request &request);
void build_websocket_context_data__(SOCKET sock, const sf_http_request &request) ;
void send_response_file_part__(SOCKET sock, const sf_http_response::response_file_info_t &file, std::ifstream &fi) ;
protected:
/**
* 构造函数
* @param config http配置
*/
explicit sf_http_base_server(sf_http_server_config config);
/**
* 设置请求回调函数
* @param request_callback 请求回调函数,函数接收参数为const sf_http_request&类型参数req和sf_http_response&参数res,处理者根据req来设置res的状态,框架会解析res的状态来返回至客户端
*/
void set_request_callback(std::function<void(const sf_http_request&,sf_http_response&)> request_callback);
/**
* 设置websocket回调函数
* @param websocket_request_callback websocket回调函数,函数接收参数为const sf_http_request&类型参数req和sf_http_response&参数res,处理者根据req来设置res的状态,框架会解析res的状态来返回至客户端(websocket握手在此函数中实现)
*/
void set_websocket_request_callback(std::function<void(const sf_http_request&,sf_http_response&)> websocket_request_callback);
/**
* 设置websocket二进制数据的响应
* @param websocket_binary_data_callback websocket二进制数据回调函数,函数接收参数为SOCKET(websocket连接,可以在send_websocket_data中使用此标识发送数据)、url(WebSocket地址)、byte_array(接收到的二进制数据)
*/
void set_websocket_binary_data_callback(std::function<void(SOCKET,const std::string &url,const byte_array&)> websocket_binary_data_callback);
/**
* 设置websocket文本数据的响应
* @param websocket_text_data_callback websocket文本数据回调函数,函数接收参数为SOCKET(websocket连接,可以在send_websocket_data中使用此标识发送数据)、url(WebSocket地址)、string(接收到的文本数据)
*/
void set_websocket_text_data_callback(std::function<void(SOCKET,const std::string &url,const std::string&)> websocket_text_data_callback);
/**
* 设置websocket打开响应
* @param websocket_open_callback websocket打开回调函数,函数接收参数为SOCKET(websocket连接,可以在send_websocket_data中使用此标识发送数据)和url(WebSocket地址)
*/
void set_websocket_open_callback(std::function<void(SOCKET,const std::string &url)> websocket_open_callback);
/**
* 设置websocket关闭响应
* @param websocket_close_callback websocket打开回调函数,函数接收参数为SOCKET(websocket连接)和url(WebSocket地址)
*/
void set_websocket_close_callback(std::function<void(SOCKET,const std::string &url)> websocket_close_callback);
public:
/**
* 启动服务器,此函数会包含一个事件循环,因此在此处会阻塞,如果有其他逻辑需要处理,可以放置在后台线程
* @return 启动是否成功
*/
bool start();
/**
* 给特定的websocket发送消息
* @tparam T 消息类型,仅支持byte_array和string,其中byte_array用于二进制数据发送,string用于文本数据发送
* @param sock socket标识
* @param data 数据(二进制或者文本数据)
* @return 是否发送成功
*/
template <typename T>
bool send_websocket_data(SOCKET sock, const T& data);
/**
* 给所有的websocket发送消息(广播),注意:此函数没有返回值,无法判断是否发送成功
* @tparam T 消息类型,仅支持byte_array和string,其中byte_array用于二进制数据发送,string用于文本数据发送
* @param data 数据(二进制或者文本数据)
*/
template <typename T>
void send_websocket_data(const T& data);
/**
* 关闭特定的websocket
* @param sock websocket标识
*/
void close_websocket(SOCKET sock);
};
}