13.3 初始化请求
Nginx与客户端建立TCP连接后,将会回调ngx_mail_init_connection方法开始初始化邮件协议,这是在处理每个邮件请求前必须要做的工作。其中,初始化请求时将会创建类似于HTTP请求中的ngx_http_request_t这样的核心结构体:ngx_mail_session_t,在13.3.1节中将会对它进行介绍。另外,在13.3.2节中会说明TCP连接建立成功时ngx_mail_init_connection方法到底做了哪些工作。
13.3.1 描述邮件请求的ngx_mail_session_t结构体
ngx_mail_session_t结构体保存了一个邮件请求的生命周期里所有可能用到的元素,如下所示。
typedef struct{
//目前未使用
uint32_t signature;
//下游客户端与Nginx之间的连接
ngx_connection_t*connection;
//out中可以存放需要向下游客户端发送的内容
ngx_str_t out;
/这个缓冲区用于接收来自客户端的请求。这个缓冲区中所使用的内存大小与请求是有关系的,对于POP3请求固定为128字节,对于SMTP请求,由nginx.conf配置文件中的smtp_client_buffer配置项决定,对于IMAP请求,则由imap_client_buffer配置项决定/
ngx_buf_t*buffer;
/ctx将指向一个指针数组,它的含义与HTTP请求的ngx_http_request_t结构体中的ctx一致,保存着这个请求中各个邮件模块的上下文结构体指针/
void**ctx;
//main级别配置结构体组成的指针数组
void**main_conf;
/srv级别配置结构体组成的指针数组,这两个指针数组的意义与第10章介绍过的HTTP框架中的同名数组基本一致,只是它们是用于main{}配置块下的配置结构体/
void**srv_conf;
//解析主机域名
ngx_resolver_ctx_t*resolver_ctx;
/请求经过认证后,Nginx就开始代理客户端与邮件服务器间的通信了,这时会生成proxy上下文用于此目的,详见13.5节/
ngx_mail_proxy_ctx_t*proxy;
/表示与邮件服务器交互时,当前处理哪种状态。对于POP3请求来说,会隶属于ngx_pop3_state_e定义的7种状态;对于IMAP请求来说,会隶属于ngx_imap_state_e定义的8种状态;对于SMTP请求来说,会隶属于ngx_smtp_state_e定义的13种状态/
ngx_uint_t mail_state;
//邮件协议类型目前仅有以下3个
//#define NGX_MAIL_POP3_PROTOCOL 0
//#define NGX_MAIL_IMAP_PROTOCOL 1
//#define NGX_MAIL_SMTP_PROTOCOL 2
unsigned protocol:3;
//标志位。blocked为1时表示当前的读或写操作需要被阻塞
unsigned blocked:1;
//标志位。quit为1时表示请求需要结束
unsigned quit:1;
//以下3个标志位仅在解析具体的邮件协议时由邮件框架使用
unsigned quoted:1;
unsigned backslash:1;
unsigned no_sync_literal:1;
/当使用SSL协议时,该标志位为1说明使用TLS传输层安全协议。由于本书不涉及SSL,故略过/
unsigned starttls:1;
/*表示与认证服务器交互时的记录认证方式。目前有6个预设值,分别是:
define NGX_MAIL_AUTH_PLAIN
0
define NGX_MAIL_AUTH_LOGIN
1
define NGX_MAIL_AUTH_LOGIN_USERNAME
2
define NGX_MAIL_AUTH_APOP
3
define NGX_MAIL_AUTH_CRAM_MD5
4
define NGX_MAIL_AUTH_NONE
5*/
unsigned auth_method:3;
/用于认证服务器的标志位,为1时表示得知认证服务器要求暂缓接收响应,这时Nginx会继续等待认证服务器的后续响应/
unsigned auth_wait:1;
/用于验证的用户名,在与认证服务器交互后会被设为认证服务器返回的响应中的Auth-User头部/
ngx_str_t login;
/相对于login用户名的密码,在与认证服务器交互后会被设为认证服务器返回的响应中的Auth-Pass头部/
ngx_str_t passwd;
//作为Auth-Salt验证的信息
ngx_str_t salt;
//以下3个成员仅用于IMAP通信
ngx_str_t tag;
ngx_str_t tagged_line;
ngx_str_t text;
//当前连接上对应的Nginx服务器地址
ngx_str_t*addr_text;
//主机地址
ngx_str_t host;
//以下4个成员仅用于SMTP的通信
unsigned esmtp:1;
ngx_str_t smtp_helo;
ngx_str_t smtp_from;
ngx_str_t smtp_to;
/在与邮件服务器交互时(即与认证服务器交互之后,透传上下游TCP流之前),command表示解析自邮件服务器的消息类型/
ngx_uint_t command;
//args动态数组中会存放来自下游客户端的邮件协议中的参数
ngx_array_t args;
//当前请求尝试访问认证服务器验证的次数
ngx_uint_t login_attempt;
//以下成员用于解析POP3/IMAP/SMTP等协议的命令行
ngx_uint_t state;
u_char*cmd_start;
u_char*arg_start;
u_char*arg_end;
ngx_uint_t literal_len;
}ngx_mail_session_t;
想要了解邮件框架的处理流程,离不开ngx_mail_session_t结构体的帮助。如果在阅读邮件请求的处理过程中遇到ngx_mail_session_t结构体的成员,那么可以返回本章查询其意义。