acl
3.5.3.0
http_request.hpp
浏览该文件的文档.
1
#pragma once
2
#include "../acl_cpp_define.hpp"
3
#include <vector>
4
#include "../connpool/connect_client.hpp"
5
#include "
http_header.hpp
"
6
7
namespace
acl
{
8
9
class
http_client;
10
class
http_pipe;
11
class
socket_stream;
12
class
charset_conv;
13
class
sslbase_conf;
14
class
xml;
15
class
json;
16
17
/**
18
* HTTP 客户端请求类,该类对象支持长连接,同时当连接断时会自动重试
19
*/
20
class
ACL_CPP_API
http_request
:
public
connect_client
21
{
22
public
:
23
/**
24
* 构造函数:通过该构造函数传入的 socket_stream 流对象并
25
* 不会被关闭,需要调用者自己关闭
26
* @param client {socket_stream*} HTTP 连接流对象,可以是请求端的流,
27
* 也可以是响应端的流;当本对象被销毁时,client 对象是否会被自动销毁,
28
* 取决于参数 stream_fixed 的值
29
* @param conn_timeout {int} 如果传入的流关闭,则内部会
30
* 自动重试,此时需要该值表示连接服务器的超时时间(秒),
31
* 至于重连流的 IO 读写超时时间是从 输入的流中继承的
32
* @param unzip {bool} 是否对服务器响应的数据自动进行解压
33
* 注:当该类实例被多次使用时,用户应该在每次调用前调用
34
* request_header::http_header::reset()
35
* @param stream_fixed {bool} 当该值为 true 时,则当 http_client 对象
36
* 被销毁时,传入的 client 流对象不会被销毁,需应用自行销毁;如果该
37
* 值为 false 时,则当本对象销毁时,client 流对象也将被销毁
38
*/
39
http_request
(
socket_stream
* client,
int
conn_timeout = 60,
40
bool
unzip =
true
,
bool
stream_fixed =
true
);
41
42
/**
43
* 构造函数:该构造函数内部创建的 socket_stream 流会自行关闭
44
* @param addr {const char*} WEB 服务器地址,地址格式:domain|port,
45
* 如:www.baidu.com|80
46
* @param conn_timeout {int} 远程连接服务器超时时间(秒)
47
* @param rw_timeout {int} IO 读写超时时间(秒)
48
* @param unzip {bool} 是否对服务器响应的数据自动进行解压
49
*/
50
http_request
(
const
char
* addr,
int
conn_timeout = 60,
51
int
rw_timeout = 60,
bool
unzip =
true
);
52
53
virtual
~
http_request
(
void
);
54
55
/**
56
* 设置在读取服务响应数据时是否针对压缩数据进行解压
57
* @param on {bool}
58
* @return {http_request&}
59
*/
60
http_request
& set_unzip(
bool
on);
61
62
/**
63
* 设置客户端 SSL 通信方式,内部缺省为非 SSL 通信方式
64
* @param conf {sslbase_conf*} 客户端 SSL 配置对象
65
* @return {http_request&}
66
*/
67
http_request
& set_ssl(
sslbase_conf
* conf);
68
69
/**
70
* 获得 HTTP 请求头对象,然后在返回的 HTTP 请求头对象中添加
71
* 自己的请求头字段或 http_header::reset()重置请求头状态,
72
* 参考:http_header 类
73
* @return {http_header&}
74
*/
75
http_header
& request_header(
void
);
76
77
/**
78
* 设置本地字符集,当本地字符集非空时,则边接收数据边进行字符集转换
79
* @param local_charset {const char*} 本地字符集
80
* @return {http_header&}
81
*/
82
http_request
& set_local_charset(
const
char
* local_charset);
83
84
/**
85
* 向 HTTP 服务器发送 HTTP 请求头及 HTTP 请求体,同时从
86
* HTTP 服务器读取 HTTP 响应头,对于长连接,当连接中断时
87
* 会再重试一次,在调用下面的几个 get_body 函数前必须先
88
* 调用本函数(或调用 write_head/write_body);
89
* 正常情况下,该函数在发送完请求数据后会读 HTTP 响应头,
90
* 所以用户在本函数返回 true 后可以调用:get_body() 或
91
* http_request::get_clinet()->read_body(char*, size_t)
92
* 继续读 HTTP 响应的数据体
93
* @param data {const void*} 发送的数据体地址,非空时自动按
94
* POST 方法发送,否则按 GET 方法发送
95
* @param len {size_} data 非空时指定 data 数据长度
96
* @return {bool} 发送请求数据及读 HTTP 响应头数据是否成功
97
*/
98
bool
request(
const
void
* data,
size_t
len);
99
100
/**
101
* 当采用流式写数据时,需要首先调用本函数发送 HTTP 请求头
102
* @return {bool} 是否成功,如果成功才可以继续调用 write_body
103
*/
104
bool
write_head();
105
106
/**
107
* 当采用流式写数据时,在调用 write_head 后,可以循环调用本函数
108
* 发送 HTTP 请求体数据;当输入的两个参数为空值时则表示数据写完;
109
* 当发送完数据后,该函数内部会自动读取 HTTP 响应头数据,用户可
110
* 继续调用 get_body/read_body 获取 HTTP 响应体数据
111
* @param data {const void*} 数据地址指针,当该值为空指针时表示
112
* 数据发送完毕
113
* @param len {size_t} data 非空指针时表示数据长度
114
* @return {bool} 发送数据体是否成功
115
* 注:当应用发送完数据后,必须再调用一次本函数,同时将两个参数都赋空
116
*/
117
bool
write_body(
const
void
* data,
size_t
len);
118
119
/////////////////////////////////////////////////////////////////////
120
121
/**
122
* 当发送完请求数据后,内部会自动调用读 HTTP 响应头过程,可以通过此函数
123
* 获得服务端响应的 HTTP 状态字(2xx, 3xx, 4xx, 5xx);
124
* 其实该函数内部只是调用了 http_client::response_status 方法
125
* @return {int}
126
*/
127
int
http_status()
const
;
128
129
/**
130
* 获得 HTTP 响应的数据体长度
131
* @return {int64) 返回值若为 -1 则表明 HTTP 头不存在或没有长度字段
132
*/
133
#if defined(_WIN32) || defined(_WIN64)
134
__int64 body_length(
void
)
const
;
135
#else
136
long
long
int
body_length(
void
)
const
;
137
#endif
138
/**
139
* HTTP 数据流(响应流是否允许保持长连接)
140
* @return {bool}
141
*/
142
bool
keep_alive(
void
)
const
;
143
144
/**
145
* 获得 HTTP 响应头中某个字段名的字段值
146
* @param name {const char*} 字段名
147
* @return {const char*} 字段值,为空时表示不存在
148
*/
149
const
char
* header_value(
const
char
*
name
)
const
;
150
151
/**
152
* 是否读完了数据体
153
* @return {bool}
154
*/
155
bool
body_finish()
const
;
156
157
/**
158
* 当调用 request 成功后调用本函数,读取服务器响应体数据
159
* 并将结果存储于规定的 xml 对象中
160
* @param out {xml&} HTTP 响应体数据存储于该 xml 对象中
161
* @param to_charset {const char*} 当该项非空,内部自动
162
* 将数据转成该字符集存储于 xml 对象中
163
* @return {bool} 读数据是否成功
164
* 注:当响应数据体特别大时不应用此函数,以免内存耗光
165
*/
166
bool
get_body(
xml
& out,
const
char
* to_charset = NULL);
167
168
/**
169
* 当调用 request 成功后调用本函数,读取服务器响应体数据
170
* 并将结果存储于规定的 json 对象中
171
* @param out {json&} HTTP 响应体数据存储于该 json 对象中
172
* @param to_charset {const char*} 当该项非空,内部自动
173
* 将数据转成该字符集存储于 json 对象中
174
* @return {bool} 读数据是否成功
175
* 注:当响应数据体特别大时不应用此函数,以免内存耗光
176
*/
177
bool
get_body(
json
& out,
const
char
* to_charset = NULL);
178
179
/**
180
* 当调用 request 成功后调用本函数,读取服务器全部响应数据
181
* 存储于输入的缓冲区中
182
* @param out {string&} 存储响应数据体
183
* @param to_charset {const char*} 当该项非空,内部自动
184
* 将数据转成该字符集存储于 out 对象中
185
* 注:当响应数据体特别大时不应用此函数,以免内存耗光
186
*/
187
bool
get_body(
string
& out,
const
char
* to_charset = NULL);
188
189
/**
190
* 当调用 request 成功后调用本函数,读取服务器响应数据并
191
* 存储于输入的缓冲区中,可以循环调用本函数,直至数据读完了,
192
* @param buf {char*} 存储部分响应数据体
193
* @param size {size_t} buf 缓冲区大小
194
* @return {int} 返回值 == 0 表示正常读完毕,< 0 表示服务器
195
* 关闭连接,> 0 表示已经读到的数据,用户应该一直读数据直到
196
* 返回值 <= 0 为止
197
* 注:该函数读到的是原始 HTTP 数据体数据,不做解压和字符集
198
* 解码,用户自己根据需要进行处理
199
*/
200
int
read_body(
char
* buf,
size_t
size);
201
202
/**
203
* 当调用 request 成功后调用本函数读 HTTP 响应数据体,可以循环调用
204
* 本函数,本函数内部自动对压缩数据进行解压,如果在调用本函数之前调用
205
* set_charset 设置了本地字符集,则还同时对数据进行字符集转码操作
206
* @param out {string&} 存储结果数据
207
* @param clean {bool} 每次调用本函数时,是否要求先自动将缓冲区 out
208
* 的数据清空
209
* @param real_size {int*} 当该指针非空时,存储解压前读到的真正数据
210
* 长度,如果在构造函数中指定了非自动解压模式且读到的数据 > 0,则该
211
* 值存储的长度值应该与本函数返回值相同;当读出错或未读到任何数据时,
212
* 该值存储的长度值为 0
213
* @return {int} == 0 表示读完毕,可能连接并未关闭;>0 表示本次读操作
214
* 读到的数据长度(当为解压后的数据时,则表示为解压之后的数据长度,
215
* 与真实读到的数据不同,真实读到的数据长度应该通过参数 real_size 来
216
* 获得); < 0 表示数据流关闭,此时若 real_size 非空,则 real_size 存
217
* 储的值应该为 0
218
* 当返回 0 时,可调用 body_finish 函数判断是否读完了所有数据体
219
*/
220
int
read_body(
string
& out,
bool
clean =
false
,
int
* real_size = NULL);
221
222
/**
223
* 调用 request 成功后调用本函数来从 HTTP 服务端读一行数据,可循环调用
224
* 本函数,直到返回 false 或 body_finish() 返回 true 为止;
225
* 内部自动对压缩数据解压,如果在调用本函数之前调用 set_charset 设置了
226
* 本地字符集,则还同时对数据进行字符集转码操作
227
* @param out {string&} 存储结果数据
228
* @param nonl {bool} 读到的一行数据是否自动去掉尾部的 "\r\n" 或 "\n"
229
* @param size {size_t*} 该指针非空时存放读到的数据长度
230
* @return {bool} 是否读到一行数据:返回 true 时表示读到了一行数据,
231
* 可以通过 body_finish() 是否为 true 来判断是否读数据体已经结束,
232
* 当读到一个空行 且 nonl = true 时,则 *size = 0;当返回 false 时
233
* 表示未读完整行且读完毕,
234
* *size 中存放着读到的数据长度
235
*/
236
bool
body_gets(
string
& out,
bool
nonl =
true
,
size_t
* size = NULL);
237
238
/**
239
* 当通过 http_request::request_header().set_range() 设置了
240
* range 的请求时,此函数检查服务器返回的数据是否支持 range
241
* @return {bool}
242
*/
243
bool
support_range(
void
)
const
;
244
245
#if defined(_WIN32) || defined(_WIN64)
246
/**
247
* 当调用了 http_request::request_header().set_range() 且读取服务器
248
* 返回的数据头后,此函数用来获得支持分段功能的起始偏移位置
249
* @return {acl_int64} 若服务器不支持 range 方式,则返回值 < 0
250
*/
251
__int64 get_range_from(
void
)
const
;
252
253
/**
254
* 当调用了 http_request::request_header().set_range() 且读取服务器
255
* 返回的数据头后,此函数用来获得支持分段功能结束偏移位置
256
* @return {acl_int64} 若服务器不支持 range 方式,则返回值 < 0
257
*/
258
__int64 get_range_to(
void
)
const
;
259
260
/**
261
* 当调用了 http_request::request_header().set_range() 且读取服务器
262
* 返回的数据头后,此函数用来获得支持分段功能的整个数据体大小,该值
263
* 即代表 HTTP 响应数据体大小
264
* @return {acl_int64} 若服务器不支持 range 方式,则返回值 < 0
265
*/
266
__int64 get_range_max(
void
)
const
;
267
#else
268
long
long
int
get_range_from(
void
)
const
;
269
long
long
int
get_range_to(
void
)
const
;
270
long
long
int
get_range_max(
void
)
const
;
271
#endif
272
273
/**
274
* 获得服务器返回的 Set-Cookie 的集合
275
* @return {const std::vector<HttpCookie*>*} 返回空表示
276
* 没有 cookie 对象或连接流为空
277
*/
278
const
std::vector<HttpCookie*>* get_cookies(
void
)
const
;
279
280
/**
281
* 获得服务器返回的 Set-Cookie 设置的某个 cookie 对象
282
* @param name {const char*} cookie 名
283
* @param case_insensitive {bool} 是否区分大小写,true 表示
284
* 不区分大小写
285
* @return {const HttpCookie*} 返回 NULL 表示不存在
286
*/
287
const
HttpCookie
* get_cookie(
const
char
*
name
,
288
bool
case_insensitive =
true
)
const
;
289
290
/////////////////////////////////////////////////////////////////////
291
292
/**
293
* 获得 http_client HTTP 连接流,可以通过返回的对象获得
294
* 服务器响应的头部分数据,参考:http_client 类
295
* @return {http_client*} 当返回空时表示流出错了
296
*/
297
http_client
* get_client(
void
)
const
;
298
299
/**
300
* 重置请求状态,在同一个连接的多次请求时会调用此函数
301
*/
302
void
reset(
void
);
303
304
protected
:
305
/**
306
* 基类 connect_client 纯虚函数,显式调用本函数用来打开与服务端的连接
307
* @return {bool} 连接是否成功
308
*/
309
virtual
bool
open();
310
311
private
:
312
char
addr_[64];
313
bool
unzip_;
314
sslbase_conf
* ssl_conf_;
315
char
local_charset_[64];
316
charset_conv
* conv_;
317
http_client
* client_;
318
http_header
header_;
319
bool
cookie_inited_;
320
std::vector<HttpCookie*>* cookies_;
321
#if defined(_WIN32) || defined(_WIN64)
322
__int64 range_from_;
323
__int64 range_to_;
324
__int64 range_max_;
325
#else
326
long
long
int
range_from_;
327
long
long
int
range_to_;
328
long
long
int
range_max_;
329
#endif
330
// 在写 HTTP 请求数据体时,该标志位标识是否允许重试过
331
bool
need_retry_;
332
333
bool
send_request(
const
void
* data,
size_t
len);
334
bool
try_open(
bool
* reuse_conn);
335
void
close(
void
);
336
void
create_cookies(
void
);
337
http_pipe
* get_pipe(
const
char
* to_charset);
338
void
set_charset_conv();
339
void
check_range(
void
);
340
};
341
342
}
// namespace acl
acl::connect_client
Definition:
connect_client.hpp:10
name
HTTP_API void const char * name
Definition:
lib_http.h:620
http_header.hpp
acl::http_pipe
Definition:
http_pipe.hpp:11
acl::http_header
Definition:
http_header.hpp:19
acl
Definition:
acl_cpp_init.hpp:4
acl::sslbase_conf
Definition:
sslbase_conf.hpp:10
acl::http_request
Definition:
http_request.hpp:20
acl::json
Definition:
json.hpp:427
acl::socket_stream
Definition:
socket_stream.hpp:14
acl::HttpCookie
Definition:
HttpCookie.hpp:12
acl::charset_conv
Definition:
charset_conv.hpp:11
ACL_CPP_API
#define ACL_CPP_API
Definition:
acl_cpp_define.hpp:16
acl::http_client
Definition:
http_client.hpp:25
acl::xml
Definition:
xml.hpp:331
include
acl_cpp
http
http_request.hpp
生成于 2021年 九月 10日 星期五 11:14:44 , 为 acl使用
1.8.15