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;

};