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结构体的成员,那么可以返回本章查询其意义。