Skip to content

Latest commit

 

History

History
216 lines (148 loc) · 8.09 KB

interceptor.md

File metadata and controls

216 lines (148 loc) · 8.09 KB

拦截器

  • 拦截器的功能非常重要,可以说是HTTP协议的核心,所有数据都通过它去处理的,可以拦截所有的数据,所以命名为拦截器,它需要实现连接服务器、根据上层的需求去与HTTP服务器进行交互,GET数据、POST数据等,然后还需要处理来自HTTP服务器的响应报文,解析它并且根据响应处理对应的情况,比如重定向、404、重连等,最后获取到数据,递交到上层。

状态结构

  • 拦截器使用状态机处理,处理过程基本如下:

interceptor

  • 状态定义如下:
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