(2)向Origin服务器转发Proxy代理请求
eJet收到HTTP客户请求时,如果是Proxy请求,则调用http_proxy_cache_open检测并打开缓存,先根据请求URL对应的HTTPLoc配置信息或正向代理对应的send request配置信息,决定当前代理模式下的HTTP请求是否启用了Cache功能,如果启用了Cache功能,并且Cache File变量设置了正确的Raw缓存文件名,将该缓存文件名保存在HTTPMsg对象的res_file_name中。
检查该缓存文件是否存在,如果存在则直接将该缓存文件返回给客户端即可。注:在没有收到全部字节数据之前Raw缓存文件名是实际缓存文件后加.tmp做扩展名。
如果该文件不存在,以该缓存文件名为参数,调用cache_info_open打开CacheInfo对象,如果不存在缓存信息对象CacheInfo,则返回并直接将客户端请求转发到Origin服务器。
如果存在CacheInfo对象,也就是存在以.tmp为扩展名的Raw缓存文件和以.cacinf为扩展名的缓存信息文件,则判断当前请求的内容(Range规范指定的请求区域)是否全部包含在Raw缓存文件中,如果包含了,则直接将该部分内容返回给客户端,无需向Origin服务器发送HTTP下载请求;如果不包含,则需要向Origin服务器发送请求,但本地缓存中已经有的内容不必重新请求,而是将客户端请求的区域(Range规范指定的范围)中尚未缓存到本地的起始位置和长度计算出来,组成新的Range规范,向Origin发送HTTP请求。
(3)处理Origin服务器返回的响应头
当HTTP请求转发到Origin服务器并返回响应后,正常情况是将Proxy代理请求HTTPMsg中所有的响应头全部复制一份到源请求HTTPMsg的响应头中,包括状态码也复制过去。
但对于启用了Cache=on并且CacheInfo也已经打开的情况,则需要修正源请求HTTPMsg的响应头,即调用http_cache_response_header来完成:删除掉不必要的响应头,修正HTTP响应体的内容传输格式,即选择Content-Length方式还是Transfer-Encoding: chunked方式,并将状态码修改成206还是200,修改Content-Range的值内容,因为源请求的Range和向Origin服务器发起的Proxy代理请求的Range不一定是一致的。并根据CacheInfo信息决定是否增加Expires和Cache-Control等响应头,等等
随后,对Origin服务器返回的HTTP响应头进行解析,调用http_proxy_cache_parse来完成:分别解析Expires、ETag、Last-Modified、Cache-Control等响应头,基于这些响应头信息,再次判断当前响应内容是否需要缓存Cache=on。
如果不需要缓存:则将Cache设置为off,并关闭已经打开的CacheInfo(甚至删除掉CacheInfo文件和Raw缓存文件),最主要的是检查源请求的Range范围和Proxy代理请求的Range范围是否一致,如果不一致,则需要重新将源HTTP请求原样再发送一次,并清除当前Proxy代理请求的所有信息。由于将源HTTP请求HTTPMsg中Cache设置为off了,后续重新发送的Proxy代理请求将不启用缓存功能,直接使用实时转发模式。如果两个请求的Range一致,则直接将当前代理请求的响应体内容采用实时转发模式,发送给客户端。
如果需要缓存:解析出响应头中的Content-Range中的信息,如果之前用cache_info_open打开CacheInfo对象失败,则此时需调用cache_info_create来创建CacheInfo对象,如果创建失败(内存不够、目录不存在等)则关闭缓存功能,用实时转发模式发送响应。随后,提取此次响应的信息,并保存到CacheInfo对象中,打开或创建Raw缓存文件,最重要的几点是:打开或创建的Raw缓存文件句柄存放在源请求的HTTPMsg中,并将该文件seek写定位到Range或Content-Range头中指定的偏移位置上,在此位置上存放Proxy代理请求中的响应体。最后,将CacheInfo对象的最新内容写入到缓存信息文件中。
(4)存储Origin服务器返回的响应体
任何开启了Cache功能的HTTP请求,只要请求的内容不在本地缓存中,都需要向Origin服务器以Proxy模式转发HTTP请求,在处理完代理请求的响应头后,需要将响应体存储到Raw缓存文件适当位置,将存储位置信息更新到缓存信息文件中,并启动向客户端发送响应。
存储Proxy代理请求的响应体是调用http_proxy_srv_cache_store来实现的:先验证当前源HTTPMsg是否为pipeline后面的请求消息,是否Cache=on等。将代理请求HTTPcon接收缓冲区中的内容作为要存储的响应体内容,进行简单解析判断,
(a)如果响应体是Content-Length格式:计算还剩余多少内容没收到,并对比接收缓冲区内容。如果剩余内容为0,则已经全部收到了请求的内容,关闭当前HTTP代理消息,并将res_body_chunk设置为结束。如果还有很多剩余内容没收到,则将接收缓冲区写入到.tmp的Raw缓存文件中,写文件句柄在源HTTPMsg对象中,将写入成功数据块的文件位置和长度信息,追加到CacheInfo对象中,并更新到缓存信息文件里,将代理请求HTTPCon缓冲区中已经写入Raw缓存文件的内容删除掉。最后再判断,刚才从缓冲区追加写入到文件的内容是否全部收齐了,如果收齐了,关闭当前HTTP代理消息。