4G_module/include/cmiot/cm_http.h

438 lines
16 KiB
C
Raw Normal View History

2024-09-02 17:54:29 +08:00
/**
* @file cm_http_client.h
* @brief HTTP协议客户端接口
* @copyright Copyright © 2021 China Mobile IOT. All rights reserved.
* @author By chenxy
* @date 2021/05/21
*
* @defgroup http http
* @ingroup NP
* @{
*/
#ifndef __CM_HTTP_H__
#define __CM_HTTP_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
/** @defgroup httpclient_define Define
* @{
*/
#ifndef true
#define true (1)
#endif
#ifndef false
#define false (0)
#endif
#ifndef bool
#define bool int
#endif
#ifndef NULL
#define NULL ((void *)0)
#endif
/**HTTP默认端口*/
#define HTTP_DEFAULT_PORT 80
/**HTTPS默认端口*/
#define HTTPS_DEFAULT_PORT 443
/**HTTP可创建实例个数*/
#define HTTPCLIENT_CTX_MAX_NUM 4
/**HTTP连接超时最大时间*/
#define HTTPCLIENT_CONNECT_TIMEOUT_MAXTIME 180
/**HTTP请求响应超时最大时间*/
#define HTTPCLIENT_WAITRSP_TIMEOUT_MAXTIME 60
/**HTTP连接超时默认时间*/
#define HTTPCLIENT_CONNECT_TIMEOUT_DEFAULT 60
/**HTTP请求响应超时默认时间*/
#define HTTPCLIENT_WAITRSP_TIMEOUT_DEFAULT 0
/**
* @}
*/
/** @defgroup httpclient_enum Enum
* @{
*/
/**HTTP请求类型*/
typedef enum {
HTTPCLIENT_REQUEST_NONE = 0,
HTTPCLIENT_REQUEST_GET,
HTTPCLIENT_REQUEST_POST,
HTTPCLIENT_REQUEST_PUT,
HTTPCLIENT_REQUEST_DELETE,
HTTPCLIENT_REQUEST_HEAD,
HTTPCLIENT_REQUEST_MAX
} cm_httpclient_request_type_e;
/**HTTP回调事件*/
typedef enum{
CM_HTTP_CALLBACK_EVENT_REQ_START_SUCC_IND=1, /*!< 请求启动成功事件 */
CM_HTTP_CALLBACK_EVENT_RSP_HEADER_IND, /*!< 接收到报头事件 */
CM_HTTP_CALLBACK_EVENT_RSP_CONTENT_IND, /*!< 接收到消息体事件 */
CM_HTTP_CALLBACK_EVENT_RSP_END_IND, /*!< 请求响应结束事件 */
CM_HTTP_CALLBACK_EVENT_ERROR_IND, /*!< 请求失败事件 */
}cm_httpclient_callback_event_e;
/**HTTP异常状态码*/
typedef enum{
CM_HTTP_EVENT_CODE_DNS_FAIL=1, /*!< DNS解析失败 */
CM_HTTP_EVENT_CODE_CONNECT_FAIL, /*!< 连接服务器失败 */
CM_HTTP_EVENT_CODE_CONNECT_TIMEOUT, /*!< 连接超时 */
CM_HTTP_EVENT_CODE_SSL_CONNECT_FAIL, /*!< SSL握手失败 */
CM_HTTP_EVENT_CODE_CONNECT_BREAK, /*!< 连接异常断开 */
CM_HTTP_EVENT_CODE_WAITRSP_TIMEOUT, /*!< 等待响应超时 */
CM_HTTP_EVENT_CODE_DATA_PARSE_FAIL, /*!< 数据解析失败 */
CM_HTTP_EVENT_CODE_CACHR_NOT_ENOUGH, /*!< 缓存空间不足 */
CM_HTTP_EVENT_CODE_DATA_DROP, /*!< 数据丢包 */
CM_HTTP_EVENT_CODE_WRITE_FILE_FAIL, /*!< 写文件失败 */
CM_HTTP_EVENT_CODE_UNKNOWN=255, /*!< 未知错误 */
}cm_httpclient_error_event_e;
/**HTTP结果码*/
typedef enum{
CM_HTTP_RET_CODE_OK = 0, /*!< 成功 */
CM_HTTP_RET_CODE_OPERATION_NOT_ALLOWED = 3, /*!< 操作不被允许 3 */
CM_HTTP_RET_CODE_MALLOC_FAIL = 23, /*!< 内存分配失败 23 */
CM_HTTP_RET_CODE_PARAM_ERROR = 50, /*!< 参数错误 50 */
CM_HTTP_RET_CODE_UNKNOWN_ERROR = 650, /*!< 未知错误 650 */
CM_HTTP_RET_CODE_NO_MORE_FREE_CLIENT = 651, /*!< 没有空闲客户端 651 */
CM_HTTP_RET_CODE_CLIENT_NOT_CREATE = 652, /*!< 客户端未创建 652 */
CM_HTTP_RET_CODE_CLIENT_IS_BUSY = 653, /*!< 客户端忙 653 */
CM_HTTP_RET_CODE_URL_PARSE_FAIL = 654, /*!< URL解析失败 654 */
CM_HTTP_RET_CODE_SSL_NOT_ENABLE = 655, /*!< SSL未使能 655 */
CM_HTTP_RET_CODE_CONNECT_FAIL = 656, /*!< 连接失败 656 */
CM_HTTP_RET_CODE_SEND_DATA_FAIL = 657, /*!< 数据发送失败 657 */
CM_HTTP_RET_CODE_OPEN_FILE_FAIL = 658, /*!< 打开文件失败 658 */
} cm_httpclient_ret_code_e;
/**
* @}
*/
/** @defgroup httpclient_struct Struct
* @{
*/
/**HTTP实例句柄*/
typedef void *cm_httpclient_handle_t;
/**HTTP回调*/
/*
* @param [in] client_handle
* @param [in] event
* @param [in] param
*
* CM_HTTP_CALLBACK_EVENT_REQ_START_SUCC_IND NULL
* CM_HTTP_CALLBACK_EVENT_RSP_HEADER_IND cm_httpclient_callback_rsp_header_param_t
* CM_HTTP_CALLBACK_EVENT_RSP_CONTENT_IND cm_httpclient_callback_rsp_content_param_t
* CM_HTTP_CALLBACK_EVENT_RSP_END_IND NULL
* CM_HTTP_CALLBACK_EVENT_ERROR_IND cm_httpclient_error_event_e
*/
typedef void (*cm_httpclient_event_callback_func)(cm_httpclient_handle_t client_handle, cm_httpclient_callback_event_e event, void *param);
/**HTTP相关回调函数*/
typedef struct {
uint16_t response_code;
uint16_t response_header_len;
const uint8_t *response_header;
}cm_httpclient_callback_rsp_header_param_t;
/**HTTP相关回调函数*/
typedef struct {
uint32_t total_len; /*!< 数据总长度chunked模式时为0 */
uint32_t sum_len; /*!< 已接收长度 */
uint32_t current_len; /*!< 当前包长度 */
const uint8_t *response_content; /*!< 数据 */
}cm_httpclient_callback_rsp_content_param_t;
/**HTTP可配参数*/
typedef struct {
uint8_t ssl_enable; /*!< 是否使用HTTPS */
int32_t ssl_id; /*!< ssl 索引号 */
uint8_t cid; /*!< PDP索引 */
uint8_t conn_timeout; /*!< 连接超时时间 */
uint8_t rsp_timeout; /*!< 响应超时时间 */
uint8_t dns_priority; /*!< dns解析优先级 0使用全局优先级。1v4优先。2v6优先 */
}cm_httpclient_cfg_t;
/**HTTP 同步接口输入参数*/
typedef struct {
cm_httpclient_request_type_e method; /*!< 请求类型 */
const uint8_t *path; /*!< 请求路径 */
uint32_t content_length; /*!< 数据长度 */
uint8_t *content; /*!< 数据 */
}cm_httpclient_sync_param_t;
/**HTTP 同步接口响应数据*/
typedef struct {
uint32_t response_code; /*!< 请求成功时的响应结果码 */
uint32_t response_header_len; /*!< 响应报头长度 */
uint32_t response_content_len; /*!< 响应消息体长度 */
uint8_t *response_header; /*!< 响应报头内部分配空间使用完后可调用cm_httpclient_sync_free_data释放 */
uint8_t *response_content; /*!< 响应消息体内部分配空间使用完后可调用cm_httpclient_sync_free_data释放 */
}cm_httpclient_sync_response_t;
/**
* @}
*/
/**
* @brief uri编码(-_.!~*'();/?:@&=+$,#)
*
* @param [in] src
* @param [in] len
*
* @return /NULL
*
* @details uri编码-_.!~*'();/?:@&=+$,#使
*/
uint8_t *cm_httpclient_uri_encode(const uint8_t *src, const uint32_t len);
/**
* @brief uri编码(-_.!~*'())
*
* @param [in] src
* @param [in] len
*
* @return /NULL
*
* @details uri编码-_.!~*'()使
*/
uint8_t *cm_httpclient_uri_encode_component(const uint8_t *src, const uint32_t len);
/**
* @brief
*
* @param [in] url url需要填写完整url仅为格式示例"https://39.106.55.200:80"
* @param [in] callback 使cm_httpclient_sync_request()NULL即可
* @param [out] handle
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details
*/
cm_httpclient_ret_code_e cm_httpclient_create(const uint8_t *url, cm_httpclient_event_callback_func callback, cm_httpclient_handle_t *handle);
/**
* @brief
*
* @param [in] handle
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details close socketHTTPeloop模块中让其执行close socket操作eloop中100ms的延时
*/
cm_httpclient_ret_code_e cm_httpclient_delete(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] client
*
* @return false / true
*
* @details
*/
bool cm_httpclient_is_busy(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] handle
* @param [in] cfg
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details ,cm_httpclient_set_cfg()
*/
cm_httpclient_ret_code_e cm_httpclient_set_cfg(cm_httpclient_handle_t handle, cm_httpclient_cfg_t cfg);
/**
* @brief http连接
*
* @param [in] handle
*
* @return
*
* @details http连接
*/
void cm_httpclient_terminate(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] handle
* @param [in] header
* @param [in] header_len
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details
* header指针
* cm_httpclient_custom_header_free接口释放内部设置
*/
cm_httpclient_ret_code_e cm_httpclient_custom_header_set(cm_httpclient_handle_t handle, uint8_t *header, uint16_t header_len);
/**
* @brief
*
* @param [in] handle
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details NULL0
*/
cm_httpclient_ret_code_e cm_httpclient_custom_header_free(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] handle
* @param [in] header
* @param [in] header_len
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details
*
* header指针
* cm_httpclient_specific_header_free接口释放内部设置
*/
cm_httpclient_ret_code_e cm_httpclient_specific_header_set(cm_httpclient_handle_t handle, uint8_t *header, uint16_t header_len);
/**
* @brief
*
* @param [in] handle
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details NULL0
*/
cm_httpclient_ret_code_e cm_httpclient_specific_header_free(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] handle
* @param [in] method
* @param [in] path
* @param [in] chunked chunked模式
* @param [in] content_length content数据总长度chunked模式时无效
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details request_start_func回调中指示开始完成
* content数据
*/
cm_httpclient_ret_code_e cm_httpclient_request_start(cm_httpclient_handle_t handle, cm_httpclient_request_type_e method, const uint8_t *path,
bool chunked, uint32_t content_length);
/**
* @brief
*
* @param [in] handle
* @param [in] content
* @param [in] content_len
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details request_start_func回调后可使用 \n
* socket发送缓存空间6424064240
*/
cm_httpclient_ret_code_e cm_httpclient_request_send(cm_httpclient_handle_t handle, const uint8_t *content, uint32_t content_len);
/**
* @brief
*
* @param [in] handle
*
* @return 0 / cm_httpclient_ret_code_e
*
* @details chunked模式下将发送结束包
*/
cm_httpclient_ret_code_e cm_httpclient_request_end(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] handle
*
* @return -1 /
*
* @details
*/
int32_t cm_httpclient_get_response_code(cm_httpclient_handle_t handle);
/**
* @brief
*
* @param [in] header
* @param [in] key key
* @param [out] value
*
* @return
*
* @details keyvalue
* value输出的为header中的指针位置
*/
uint32_t cm_httpclient_parse_header(const uint8_t *header, const uint8_t *key, uint8_t **value);
/**
* @brief ()
*
* @param [in] handle
* @param [in] param cm_httpclient_sync_param_t
* @param [out] response cm_httpclient_sync_response_t
*
* @return cm_httpclient_ret_code_e
*
* @details http请求同步接口chunk模式发送
* 使cm_httpclient_sync_free_data接口释放
* \n
* socket发送缓存空间6424064240
*/
cm_httpclient_ret_code_e cm_httpclient_sync_request(cm_httpclient_handle_t handle, cm_httpclient_sync_param_t param,
cm_httpclient_sync_response_t *response);
/**
* @brief ()
*
* @param [in] handle
*
* @return
*
* @details
*/
void cm_httpclient_sync_free_data(cm_httpclient_handle_t handle);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CM_HTTP_H__ */