acl/lib_protocol/include/http/lib_http_util.h
2019-09-20 21:54:02 +08:00

235 lines
8.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __LIB_HTTP_UTIL_INCLUDE_H__
#define __LIB_HTTP_UTIL_INCLUDE_H__
#include "lib_http_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct HTTP_UTIL {
HTTP_HDR_REQ *hdr_req; /**< HTTP 请求头 */
HTTP_HDR_RES *hdr_res; /**< HTTP 响应头 */
HTTP_RES *http_res; /**< HTTP 响应体 */
char server_addr[256]; /**< 远程 HTTP 服务器地址 */
ACL_VSTREAM *stream; /**< 与 HTTP 服务器建立的网络流 */
int conn_timeout; /**< 连接 HTTP 服务器的超时时间 */
int rw_timeout; /**< 与 HTTP 服务器通信时每次 IO 的超时时间 */
ACL_VSTRING *req_buf; /**< 缓冲区 */
int res_body_dlen; /**< HTTP 响应数据体的长度 */
ACL_VSTREAM *dump_stream; /**< 转储接收数据的流 */
unsigned int flag; /**< 标志位 */
#define HTTP_UTIL_FLAG_SET_DUMP_FILE (1 << 0) /**< 允许转储响应体至文件 */
#define HTTP_UTIL_FLAG_SET_DUMP_STREAM (1 << 1) /**< 允许转储响应体至流 */
#define HTTP_UTIL_FLAG_HAS_RES_BODY (1 << 2) /**< 有 HTTP 响应体 */
#define HTTP_UTIL_FLAG_NO_RES_BODY (1 << 3) /**< 无 HTTP 响应体 */
} HTTP_UTIL;
/**
* 创建一个 HTTP_UTIL 请求对象
* @param url {const char*} 完整的请求 url
* @param method {const char*} 请求方法有效的请求方法有GET, POST, HEAD, CONNECT
* @return {HTTP_UTIL*}
*/
HTTP_API HTTP_UTIL *http_util_req_new(const char *url, const char *method);
/**
* 构建一个 HTTP_UTIL 响应对象
* @param status {int} 状态码,有效的状态码为: 1xx, 2xx, 3xx, 4xx, 5xx
* @return {HTTP_UTIL*}
*/
HTTP_API HTTP_UTIL *http_util_res_new(int status);
/**
* 释放一个 HTTP_UTIL 对象
* @param http_util {HTTP_UTIL*}
*/
HTTP_API void http_util_free(HTTP_UTIL *http_util);
/**
* 设置 HTTP 请求头信息, 如: Accept-Encoding: gzip,deflate
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 请求头中字段名称, 如 Accept-Encoding
* @param value {const char*} 请求头中字段的值, 如 gzip,deflate
*/
HTTP_API void http_util_set_req_entry(HTTP_UTIL *http_util, const char *name, const char *value);
/**
* 关闭 HTTP 请求头中的某个请求字段,该请求字段不会发往服务器
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 请求头中字段名称, 如 Accept-Encoding
*/
HTTP_API void http_util_off_req_entry(HTTP_UTIL *http_util, const char *name);
/**
* 获得请求头中某个字段的值
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 请求头中字段名称, 如 Accept-Encoding
* @return {char*} 如果非空则为请求字段值,否则表明该字段不存在
*/
HTTP_API char *http_util_get_req_value(HTTP_UTIL *http_util, const char *name);
/**
* 获得请求头中某个字段的 HTTP_HDR_ENTRY 对象
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 请求头中字段名称, 如 Accept-Encoding
* @return {HTTP_HDR_ENTRY*} 若为空则表示该字段不存在
*/
HTTP_API HTTP_HDR_ENTRY *http_util_get_req_entry(HTTP_UTIL *http_util, const char *name);
/**
* 设置请求头中 HTTP 数据体的数据长度
* @param http_util {HTTP_UTIL*}
* @param len {int} HTTP 数据体长度(必须 >= 0)
*/
HTTP_API void http_util_set_req_content_length(HTTP_UTIL *http_util, int len);
/**
* 设置请求头中 HTTP 会话保持长连接的存活时间(单位为秒)
* @param http_util {HTTP_UTIL*}
* @param timeout {int} HTTP 长连接的存活时间(单位为秒)
*/
HTTP_API void http_util_set_req_keep_alive(HTTP_UTIL *http_util, int timeout);
/**
* 设置请求头中 Connection 字段
* @param http_util {HTTP_UTIL*}
* @param value {const char*} 字段值,有效的字段为: keep-alive, close
*/
HTTP_API void http_util_set_req_connection(HTTP_UTIL *http_util, const char *value);
/**
* 设置请求头中的 Referer 字段
* @param http_util {HTTP_UTIL*}
* @param refer {const char*} 完整的 url, 如: http://www.test.com
*/
HTTP_API void http_util_set_req_refer(HTTP_UTIL *http_util, const char *refer);
/**
* 设置请求头中的 Cookie 字段,采用的是追加方式
* @param http_util {HTTP_UTIL*}
* @param name {const char*} Cookie 名称
* @param value {const char*} Cookie 值
*/
HTTP_API void http_util_set_req_cookie(HTTP_UTIL *http_util, const char *name, const char *value);
/**
* 设置 HTTP 代理服务器地址
* @param http_util {HTTP_UTIL*}
* @param proxy {const char*} 代理服务器地址,有效格式为: IP:PORT, DOMAIN:PORT,
* 如: 192.168.0.1:80, 192.168.0.2:8088, www.g.cn:80
*/
HTTP_API void http_util_set_req_proxy(HTTP_UTIL *http_util, const char *proxy);
/**
* 设置 HTTP 响应体的转储流,设置后 HTTP 响应体数据便会同时向该流转发
* @param http_util {HTTP_UTIL*}
* @param stream {ACL_VSTREAM *} 转储流
*/
HTTP_API void http_util_set_dump_stream(HTTP_UTIL *http_util, ACL_VSTREAM *stream);
/**
* 设置 HTTP 响应体的转储文件,设置后 HTTP 响应体数据便会转储于该文件
* @param http_util {HTTP_UTIL*}
* @param filename {const char*} 转储文件名
* @return {int} 如果返回值 < 0 则表示无法打开该文件, 否则表示打开文件成功
*/
HTTP_API int http_util_set_dump_file(HTTP_UTIL *http_util, const char *filename);
/**
* 打开远程 HTTP 服务器或代理服务器连接,同时构建 HTTP 请求头数据并且将该数据
* 发给新建立的网络连接
* @param http_util {HTTP_UTIL*}
* @return {int} 0: 成功; -1: 无法打开连接或发送请求头数据失败
*/
HTTP_API int http_util_req_open(HTTP_UTIL *http_util);
/**
* 当采用 POST 方法时,可以通过此函数向 HTTP 服务器或代理服务器发送请求体数据,
* 在一个请求过程中,可以多次调用本函数直至发送完请求体数据
* @param http_util {HTTP_UTIL*}
* @param data {const char*} 本次发送的数据地址,必须非空
* @param dlen {size_t} data 数据长度, 必须大于 0
* @return {int} > 0 表示本次成功发送的数据; -1: 表示发送数据失败, 应调用
* http_util_free 关闭网络流且释放内存资源
*/
HTTP_API int http_util_put_req_data(HTTP_UTIL *http_util, const char *data, size_t dlen);
/**
* 发送完请求数据后调用此函数从 HTTP 服务器读取完整的 HTTP 响应头
* @param http_util {HTTP_UTIL*}
* @return {int} 0: 成功; -1: 失败
*/
HTTP_API int http_util_get_res_hdr(HTTP_UTIL *http_util);
/**
* 从 HTTP 响应头中获得某个字段值
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 字段名称, 如 Content-Length
* @return {char*} 对应 name 的字段值, 如果为空则表示该字段不存在
*/
HTTP_API char *http_util_get_res_value(HTTP_UTIL *http_util, const char *name);
/**
* 从 HTTP 响应头中获得某个字段对象
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 字段名称, 如 Content-Length
* @return {HTTP_HDR_ENTRY*} 对应 name 的字段对象, 如果为空则表示该字段不存在
*/
HTTP_API HTTP_HDR_ENTRY *http_util_get_res_entry(HTTP_UTIL *http_util, const char *name);
/**
* 设置 HTTP 响应头中的某个字段值
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 字段名称, 如 Content-Type
* @param value {const char*} 字段值, 如 text/html
*/
HTTP_API void http_util_set_res_entry(HTTP_UTIL *http_util, const char *name, const char *value);
/**
* 关闭 HTTP 响应头中的某个字段
* @param http_util {HTTP_UTIL*}
* @param name {const char*} 字段名称, 如 Content-Type
*/
HTTP_API void http_util_off_res_entry(HTTP_UTIL *http_util, const char *name);
/**
* 读完 HTTP 响应头后调用此函数判断是否有 HTTP 响应体
* @param http_util {HTTP_UTIL*}
* @return {int} 0: 表示无响应体; !0: 表示有响应体
*/
HTTP_API int http_util_has_res_body(HTTP_UTIL *http_util);
/**
* 读完 HTTP 响应头后调用此函数从 HTTP 服务器读取 HTTP 数据体数据,需要连续调用
* 此函数,直至返回值 <= 0, 如果之前设置了转储文件或转储则在读取数据过程中同时会
* 拷贝一份数据给转储文件或转储流
* @param http_util {HTTP_UTIL*}
* @param buf {char *} 存储 HTTP 响应体的缓冲区
* @param size {size_t} buf 的空间大小
* @return {int} <= 0: 表示读结束; > 0: 表示本次读到的数据长度
*/
HTTP_API int http_util_get_res_body(HTTP_UTIL *http_util, char *buf, size_t size);
/**
* 将某个 url 的响应体数据转储至某个文件中
* @param url {const char*} 完整请求 url, 如: http://www.g.cn
* @param dump {const char*} 转储文件名
* @return {int} 读到的响应体数据长度, >=0: 表示成功, -1: 表示失败
*/
HTTP_API int http_util_dump_url(const char *url, const char *dump);
/**
* 将某个 url 的响应体数据转储至某个流中
* @param url {const char*} 完整请求 url, 如: http://www.g.cn
* @param stream {ACL_VSTREAM *} 转储流
* @return {int} 读到的响应体数据长度, >=0: 表示成功, -1: 表示失败
*/
HTTP_API int http_util_dump_url_to_stream(const char *url, ACL_VSTREAM *stream);
#ifdef __cplusplus
}
#endif
#endif