(c)如果响应体的编码格式为Transfer-Encoding: chunked时:
通过CacheInfo的碎片数据管理接口,查询出当前Raw缓存文件中,以(a)中计算出的缓存文件偏移量位置,查出可用的数据长度有多少。
如果Raw缓存文件中存在可用数据,将可用数据长度截成最多50个1M大小的数据块,将Raw缓存文件名、1M数据块起始位置、长度作为参数添加到res_body_chunk中。如果添加到chunk中的数据总长度达到或超过源请求HTTPMsg消息的响应总长度,则将res_body_chunk设置结束状态,启动TCP发送流程。
如果Raw缓存文件中不存在可用数据,则与上述(b)流程类似。
(d)如果源HTTPMsg中统计发送给客户端的响应数据总长度小于res_body_chunk中的总长度,开始发送chunk中的数据。
(6)发送响应给客户端的流程是标准通用的流程
基于HTTP Proxy的缓存数据存储、发送、缓存信息管理维护等功能全部实现完成。
十二. HTTP Tunnel
HTTP Tunnel是在客户端和Origin服务器之间,通过Tunnel网关,建立传输隧道的通信方式,eJet服务器可以充当HTTP Tunnel网关,分别与客户端和Origin服务器之间建立两个TCP连接,并在这两个连接之间进行数据的实时转发。根据RFC 2616规范,HTTP CONNECT请求方法是建立HTTP Tunnel的基本方式。
HTTP Tunnel最常用的场景是HTTP Proxy正向代理服务器,代理转发客户端https的安全连接请求到Origin服务器,一般情况下,需要采用端到端的TLS/SSL连接,这时,客户端会尝试发送CONNECT方法的HTTP请求,建立一条通过Proxy服务器,到达Origin服务器的连接隧道,即两个TCP连接串联来实时转发数据,通过这个连接隧道,进行TLS/SSL的安全握手、认证、密钥交换、数据加密等,从而实现端到端的安全数据传输。
十三. eJet的Callback回调机制
13.1 eJet回调机制
eJet系统提供了HTTP请求消息交付给应用程序处理的回调机制,回调机制是事件驱动模型中底层系统异步调用上层处理函数的编程模式,上层应用系统需事先将函数实现设置到底层系统的回调函数指针中。
eJet系统提供了两种回调机制,一种是在启动eJet时,设置的全局回调函数,另一种是在系统配置文件中位于监听服务下的动态库配置回调机制。
13.2 eJet全局回调函数
全局回调函数的设置是在启动eJet系统时,应用层可以实现HTTP消息处理函数,来处理所有HTTP请求的HTTPMsg,这是程序级的回调机制,需要将eJet代码嵌入到应用系统中来实现回调处理。
设置全局回调的API如下:
int http_set_reqhandler (void * httpmgmt, RequestHandler * reqhandler, void * cbobj);
其中,httpmgmt是eJet系统创建的全局管理入口HTTPMgmt对象实例, reqhandler是应用层实现的回调函数,cbobj是应用层回调函数的第一个回调参数,eJet每次调用回调函数时,必须携带的第一个参数就是cbobj。
应用层回调函数的原型如下:
typedef int RequestHandler (void * cbobj, void * vmsg);
其中,cbobj是设置全局回调函数时传递回调参数,vmsg是当前封装HTTP请求的HTTPMsg实例对象。
应用程序将系统管理所需的数据结构(包括应用层配置、数据库连接、用户管理等)封装好,创建并初始化一个cbobj对象,作为设置回调函数时的回调参数。通过回调参数,已经HTTPMsg请求对象,可以将请求信息和应用程序内的数据对象建立各种关联关系。
13.3 eJet动态库回调
eJet系统另外一种回调是使用动态库的回调方式,这是松耦合型的、修改配置文件就可以完成回调处理的方式。应用程序无需改动eJet的任何代码,只需在配置中添加含有路径的动态库文件名,即可以实现回调功能,其中动态库必须实现三个固定名称的函数,且遵循eJet约定的函数原型定义。
配置文件中添加动态库回调的位置:
listen = { local ip = *; port = 8181; request process library = reqhandle.so app.conf......
eJet系统启动期间,加载配置文件后,解析三层资源架构的第一步HTTPListen时,其配置项下的动态库会被加载,加载过程为:
加载配置项指定动态库文件;
根据函数名http_handle_init,获取动态库中的初始化函数指针;
根据函数名http_handle,获取动态库中的回调处理函数指针;
根据函数名http_handle_clean,获取动态库中的清除函数指针;
执行动态库初始化函数,并返回初始化后的回调参数对象。