13.5 邮件认证
邮件认证工作由ngx_mail_auth方法执行。邮件认证服务器的地址在nginx.conf文件的auth_http配置项中设置(参见13.1节),这一认证流程相对独立,其认证功能是由ngx_mail_auth_http_module邮件模块提供的。在与认证邮件服务器打交道的过程中,结构体ngx_mail_auth_http_ctx_t会贯穿其始终,它保存有连接、请求内容、响应内容、解析状态等必要的成员,在认证完邮件后将会通过销毁内存池来销毁这个结构体。
13.5.1 ngx_mail_auth_http_ctx_t结构体
ngx_mail_auth_http_ctx_t结构体是在其成员pool指向的内存池中分配的,它的地址实际上保存在ngx_mail_session_t的ctx指针数组中(实际上,在ngx_mail_auth_http_module模块ctx_index成员指出的序号对应的ctx数组元素中,相当于该模块的上下文结构体)。邮件框架提供给各个邮件模块的两个方法用于在ctx指针数组中设置、取出上下文结构体的地址,如下所示。
define ngx_mail_get_module_ctx(s,module)
(s)->ctx[module.ctx_index]
define ngx_mail_set_ctx(s,c,module)
s->ctx[module.ctx_index]=c;
其实际用法跟HTTP框架中的ngx_http_set_ctx方法非常相似。例如,假设指针ctx就是刚刚分配的ngx_mail_auth_http_ctx_t结构体地址,而s是每个请求的ngx_mail_session_t结构体指针,那么可以这样设置到请求的ctx数组中:
ngx_mail_set_ctx(s,ctx,ngx_mail_auth_http_module);
下面详细介绍ngx_mail_auth_http_ctx_t结构体中的每个成员。
typedef struct ngx_mail_auth_http_ctx_s ngx_mail_auth_http_ctx_t;
//解析认证服务器HTTP响应的方法指针
typedef void(ngx_mail_auth_http_handler_pt)(ngx_mail_session_ts,ngx_mail_auth_http_ctx_t*ctx);
struct ngx_mail_auth_http_ctx_s{
/request缓冲区保存着发往认证服务器的请求。它是根据解析客户端请求得到的ngx_mail_session_t,使用ngx_mail_auth_http_create_request方法构造出的内存缓冲区。这里的请求是一种类HTTP的请求/
ngx_buf_t*request;
//保存认证服务器返回的类HTTP响应的缓冲区。缓冲区指向的内存大小固定为1KB
ngx_buf_t*response;
//Nginx与认证服务器间的连接
ngx_peer_connection_t peer;
/解析来自认证服务器类HTTP的响应行、头部的方法(参见图13-6),默认为ngx_mail_auth_http_ignore_status_line方法/
ngx_mail_auth_http_handler_pt handler;
/在使用状态机解析认证服务器返回的类HTTP响应时,使用state表示解析状态/
ngx_uint_t state;
/ngx_mail_auth_http_parse_header_line方法负责解析认证服务器发来的响应中类HTTP的头部,以下4个成员用于解析响应头部/
u_char*header_name_start;
u_char*header_name_end;
u_char*header_start;
u_char*header_end;
//认证服务器返回的Auth-Server头部
ngx_str_t addr;
//认证服务器返回的Auth-Port头部
ngx_str_t port;
//错误信息
ngx_str_t err;
//错误信息构成的字符串
ngx_str_t errmsg;
/错误码构成的字符串。如果认证服务器返回的头部里有Auth-Error-Code,那么将会设置到errcode中。errmsg和errcode在发生错误时会直接将其作为响应发给客户端/
ngx_str_t errcode;
/认证服务器返回Auth-Wait头部时带的时间戳将会被设到sleep成员中,而Nginx等待的时间也将由sleep维护,当sleep降为0时将会设置quit标志位为1,表示请求非正常结束,把错误码返回给用户/
time_t sleep;
//用于邮件认证的独立内存池,它的初始大小为2KB
ngx_pool_t*pool;
};