- 拦截器的功能非常重要,可以说是HTTP协议的核心,所有数据都通过它去处理的,可以拦截所有的数据,所以命名为拦截器,它需要实现连接服务器、根据上层的需求去与HTTP服务器进行交互,GET数据、POST数据等,然后还需要处理来自HTTP服务器的响应报文,解析它并且根据响应处理对应的情况,比如重定向、404、重连等,最后获取到数据,递交到上层。
- 拦截器使用状态机处理,处理过程基本如下:
- 状态定义如下:
typedef enum http_interceptor_status {
http_interceptor_status_invalid = 0x00,
http_interceptor_status_init,
http_interceptor_status_connect,
http_interceptor_status_request,
http_interceptor_status_response_headers,
http_interceptor_status_response_body,
http_interceptor_status_close
} http_interceptor_status_t;
typedef struct http_interceptor {
network_t *network;
http_connect_params_t *connect_params;
http_request_t request;
http_response_t response;
http_interceptor_status_t status;
http_message_buffer_t *message;
char *buffer;
size_t buffer_len;
size_t cmd_timeout;
size_t data_process;
struct http_parser *parser;
struct http_parser_settings *parser_settings;
http_event_t *evetn;
void *owner;
union {
uint32_t all_flag;
struct {
uint32_t again : 4;
uint32_t redirects : 4;
uint32_t retry : 4;
uint32_t authenticate : 4;
uint32_t chunked : 4;
uint32_t chunked_complete : 4;
uint32_t complete : 4;
uint32_t keep_alive : 4;
} flag_t;
} flag;
} http_interceptor_t;
-
network:网卡抽象接口,需要底层网络数据通道打交道,对网络数据的读写操作。
-
connect_params:连接参数,用于构造HTTP请求相关的字段。
-
request:HTTP请求结构,构造请求相关信息。
-
response:HTTP响应结构,用于处理响应的相关信息。
-
status:状态,描述拦截器当前的处理状态。
-
message:HTTP报文缓冲区,用于存储写数据时的报文内容,比如在HTTP请求的时候,它保存了HTTP请求报文的起始行、头部、主体等内容。
-
buffer:接收数据缓冲区,接收完数据就递交到上层去。
-
buffer_len:可以由用户指定的报文缓冲区长度,默认值是
HTTP_DEFAULT_BUF_SIZE
。 -
data_process:已经处理的数据长度。
-
cmd_timeout:可以由用户指定的超时时间,默认值是
HTTP_DEFAULT_CMD_TIMEOUT
。 -
parser:http解析响应报文的数据结构。
-
parser_settings:解析报文时响应的配置,其实是指定相应的回调函数。
-
evetn:事件回调,在需要的时候通过回调函数处理,将数据上报,比如发生错误的时候、在请求之前、在接收到应答的时候、在解析报文的时候、在解析完成报文的时候、上报body数据的时候等等。
-
owner:所有者属性,该拦截器是属于哪个上层结构的。
-
flag:使用了共用体与结构体描述的一个拦截器标志位:
-
again:是否需要重新处理。
-
redirects:重定向标志位,拦截器自动处理重定向的内容,这个操作对用户来说是透明的。
-
retry:重新尝试。保留未用。
-
authenticate:需要认证。
-
chunked:接收的数据是分块的。
-
chunked_complete:所有分块数据接收完毕。
-
complete:数据接收完成。
-
keep_alive:指定长连接。
-
- 拦截器初始化,主要实现的功能有:为网卡结构分配内存空间、初始化HTTP请求/响应相关数据结构、初始化HTTP回调事件evetn、为HTTP报文message分配内存空间、为HTTP解析器parser、parser_settings分配相关的内存空间并且初始它们。
int http_interceptor_init(http_interceptor_t *interceptor)
- 拦截器的释放操作,因为在处理HTTP的时候会动态分配非常多的内存空间,在最后应该要回收它们,注意,此函数不仅回收了http_interceptor_init()函数分配的内存空间,还会回收在处理HTTP请求、应答、解析时候动态申请的内存空间。
int http_interceptor_release(http_interceptor_t *interceptor);
- 设置ca证书
void http_interceptor_set_ca(const char *ca);
- 设置拦截器的所有者属性,指定拦截器归属谁所有,可以为NULL,但一般不为NULL。
void http_interceptor_set_owner(http_interceptor_t *interceptor, void *owner);
- 注册回调函数事件,在合适的时候会通过回调函数告知上层,一般来说在回调函数中需要判断是何种事件产生的回调,决定是否需要处理,回调函数的类型是http_event_cb_t,详细内容查看HTTP回调事件。
void http_interceptor_event_register(http_interceptor_t *interceptor, http_event_cb_t cb);
- 拦截器设置连接参数。
int http_interceptor_set_connect_params(http_interceptor_t *interceptor, http_connect_params_t *conn_param)
- 拦截器连接服务器,在链接之前要准备好接收响应报文的内容,初始化interceptor->parser结构。
int http_interceptor_connect(http_interceptor_t *interceptor)
- 发起HTTP请求,指定请求的方法(GET / POST等),如果是POST还要指定报文主体的内容post_buf,也可以为NULL。这个函数中会调用 HTTP请求 相关的函数,构造起始行,构造报文HTTP请求首部、主体等,然后再通过
_http_write_buffer()
函数将数据发送出去。
int http_interceptor_request(http_interceptor_t *interceptor, http_request_method_t mothod, const char *post_buf)
- 拦截器状态机处理,过程如前文的状态图所示。
int http_interceptor_process(http_interceptor_t *interceptor,
http_connect_params_t *connect_params,
http_request_method_t mothod,
void *post_buf,
void *owner,
http_event_cb_t cb);
与网卡相关的读/写数据操作:
- 读数据。
static int _http_read_buffer(http_interceptor_t *interceptor, size_t length)
- 写数据。
static int _http_write_buffer(http_interceptor_t *interceptor, unsigned char *buf, int length)
- 设置、获取拦截器的状态信息
static void _http_interceptor_set_status(http_interceptor_t *interceptor, http_interceptor_status_t status)
static http_interceptor_status_t _http_interceptor_get_status(http_interceptor_t *interceptor)
- 设置解析器的回调函数,注意这些是内部的处理函数。
static int _http_interceptor_parser_setting(http_interceptor_t *interceptor)
{
interceptor->parser_settings->on_url = _http_on_url;
interceptor->parser_settings->on_status = _http_on_status;
interceptor->parser_settings->on_header_field = _http_on_header_field;
interceptor->parser_settings->on_header_value = _http_on_header_value;
interceptor->parser_settings->on_headers_complete = _http_on_headers_complete;
interceptor->parser_settings->on_message_begin = _http_on_message_begin;
interceptor->parser_settings->on_message_complete = _http_on_message_complete;
interceptor->parser_settings->on_body = _http_on_body;
interceptor->parser_settings->on_chunk_header = _http_on_chunk_header;
interceptor->parser_settings->on_chunk_complete = _http_on_chunk_complete;
interceptor->parser->data = interceptor;
}
上一篇: HTTP响应
下一篇: httpclient