如果SSL_read返回0,则当前连接出现故障,需关闭连接。如果返回值小于0,则调用SSL_get_error来处理错误码,对于SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE两种情况需要调用ePump接口设置添加读写就绪监听。
在SSL连接上发送数据
eJet系统中发送数据流程一般是用chunk_t数据结构管理数据,调用writev和sendfile将数据通过网络发送给对方,在SSL连接情况下,eJet系统同样封装了两个类似的函数:
int http_con_writev (void * vcon, void * piov, int iovcnt, int * num, int * err);int http_con_sendfile (void * vcon, int filefd, int64 pos, int64 size, int * num, int * err);
这两个函数同时兼容有SSL连接和没有SSL连接这两种情况,在没有SSL连接情况下,直接调用tcp_writev和tcp_sendfile。
在有SSL连接情况下,调用SSL_write函数,要写入的明文数据调用SSL_write后被加密并传输给对方。如果发送成功返回的是写入数据的长度,如果返回0,则当前连接出现故障,需关闭连接。如果返回值小于0,则需要调用SSL_get_error来处理错误码,对于SSL_ERROR_WANT_READ和SSL_ERROR_WANT_WRITE两种情况需要调用ePump接口设置添加读写就绪监听。
关闭SSL连接
在处理完成数据读写操作,或者网络错误等情况,当前HTTPCon会被关闭,如果是SSL连接则需释放SSL实例,分别调用SSL_shutdown和SSL_free来完成资源释放。
以上九个步骤是eJet系统作为HTTP服务器时使用SSL连接来传输数据的基本流程,对于eJet系统作为HTTP客户端情形,过程基本类似,这里不再赘述。
八. Chunk传输编码解析
HTTP 1.1协议增加了Transfer-Encoding: chunked的头类型,表示消息体的内容长度不能确定,需采用分块传输编码方式,将消息体发送给对方。
Chunked Transfer Coding分块传输编码是由多个Chunk块组成,每个Chunk块包括两部分,十六进制的分块数据长度加上可选的分块扩展加上rn、实际分块数据加上rn,分块传输编码的结尾是以分块数据长度为0的分块组成。
分块传输数据格式如下:
chunked body = chunk-size[; chunk-ext-nanme [= chunk-ext-value]]rn ... 0rn [footer] rn
chunk size是以16进制表示的长度,footer一般是以rn结尾的entity-header,一般都忽略掉。
eJet系统使用HTTPChunk数据结构来解析chunk分块传输编码的消息体数据,使用chunk_t数据结构来打包分块传输编码。HTTPChunk数据结构包含chunk_t成员实例,用于存储解析成功的Chunk数据块,每一个Chunk数据块解析状态和信息用ChunkItem来存储管理,HTTPChunk中用item_list来管理多个ChunkItem。
采用chunk分块传输编码的消息体,实际情况是一边传输一边解析,解析过程要充分考虑到当前接收缓冲区内容的不完整性,这是由HTTPChunk里的http_chunk_add_bufptr来实现的,函数定义如下:
int http_chunk_add_bufptr (void * vchk, void * vbgn, int len, int * rmlen);
vbgn和len指向需解析的消息体数据,rmlen是解析成功后实际用于chunk分块传输编码的字节数量。
eJet在遇到chunk分块传输编码的消息体时,每次收到读事件,就将数据读取到缓冲区,将缓冲区所有数据交给这个解析函数解析处理,返回的rmlen值是被解析和处理的字节数,将处理完的数据从缓冲区移除掉。通过http_chunk_gotall来判断是否接收到全部chunk分块传输编码的所有数据,如果没有,循环地用新接收的数据调用该函数来解析和处理,直至成功接收完毕。
九. 反向代理和正向代理
9.1 判断是否为代理请求
反向代理是将不同的Origin服务器代理给客户端,客户端不做任何代理配置发起正常的HTTP请求到反向代理服务器,反向代理服务器根据配置的路径规则,代理访问不同的Origin服务器并将响应结果返回给客户端,让客户端认为反向代理服务器就是其访问的Origin服务器。
正向代理需要求客户端设置正向代理服务器地址,明确给定Origin服务器地址,要求正向代理服务器想给定的Origin服务器转发请求和响应。
上面描述的反向代理服务器,在这里就是eJet Web服务器,除了充当Web服务器功能外,还可以充当正向代理服务器和反向代理服务器。
eJet系统在HTTPMsg实例化完成后,首先要检查的是当前请求是否为Proxy代理请求: