13.5.3 发送请求到认证服务器
ngx_mail_auth_http_write_handler会发送request缓冲区中的请求到认证服务器,它的代码非常简单,如下所示。
static void ngx_mail_auth_http_write_handler(ngx_event_t*wev)
{
ssize_t n,size;
ngx_connection_t*c;
ngx_mail_session_t*s;
ngx_mail_auth_http_ctx_t*ctx;
ngx_mail_auth_http_conf_t*ahcf;
//写事件上的data成员存放的是Nginx与认证服务器间的TCP连接
c=wev->data;
//连接的date成员指向ngx_mail_session_t结构体
s=c->data;
//获得描述认证过程的ngx_mail_auth_http_ctx_t结构体
ctx=ngx_mail_get_module_ctx(s,ngx_mail_auth_http_module);
/如果向认证服务器发送请求超时,则关闭连接、销毁内存池,并向客户端发送错误响应/
if(wev->timedout){
ngx_close_connection(c);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
}
/计算还剩下多少字节的请求没有发送出去,pos和last之间的内容就是待发送的请求/
size=ctx->request->last-ctx->request->pos;
//向认证服务器发送请求
n=ngx_send(c,ctx->request->pos,size);
//如果发送失败,则关闭连接、销毁内存池,并向客户端发送错误响应if(n==NGX_ERROR){
ngx_close_connection(c);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
}
//如果成功发送了请求
if(n>0){
//更新request缓冲区
ctx->request->pos+=n;
/size表示还需要发送的请求长度,n表示本次发送的请求长度,当它们相等时,意味着已经将全部响应发送到认证服务器/
if(n==size){
/将Nginx与认证服务器间连接的写事件回调方法设为任何事情都不做的ngx_mail_auth_http_dummy_handler方法/
wev->handler=ngx_mail_auth_http_dummy_handler;
/由于不再需要发送请求,所以不需要再监控发送是否超时。如果写事件还在定时器中,则移除/
if(wev->timer_set){
ngx_del_timer(wev);
}
//将写事件添加到epoll中
if(ngx_handle_write_event(wev,0)!=NGX_OK){
ngx_close_connection(c);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
}
return;
}
}
//如果定时器中没有写事件,那么把它添加到定时器中监控发送请求是否超时
if(!wev->timer_set){
ahcf=ngx_mail_get_module_srv_conf(s,ngx_mail_auth_http_module);
ngx_add_timer(wev,ahcf->timeout);
}
}