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);

}

}