ngx_http_wait_request_handler函數解析

在普通的http請求過程中,ngx_event_accept函數中ls->handler(c);調用了ngx_http_init_connection函數,ngx_http_init_connection函數會調用ngx_http_wait_request_handler。主要代碼和解析如下。

   

查看事件是否已過期,如果已過期,直接斷開連接

if (rev->timedout) {
    ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
    ngx_http_close_connection(c);
    return;
}

調用recv函數,接收數據。函數原型在ngx_recv.c中定義,根據是否使用kqueue(一種i/o複用技術),有兩種函數定義。

n = c->recv(c, b->last, size);
if (n == NGX_AGAIN) 
{
    尚未有數據道來,由於Nginx的事件驅動機制,程序不會阻塞,註冊讀事件並返回。
    if (ngx_handle_read_event(rev, 0) != NGX_OK) 
    {
        ngx_http_close_connection(c);
        return;
    }
    連接有可能什麼實質性工作都不做,所以暫且釋放內存。
    if (ngx_pfree(c->pool, b->start) == NGX_OK) 
    {
        b->start = NULL;
    }
    return;
}

recv函數返回了錯誤,直接斷開連接並返回。

if (n == NGX_ERROR) {
    ngx_http_close_connection(c);
    return;
}

client主動斷開了連接。

if (n == 0) {
    ngx_log_error(NGX_LOG_INFO, c->log, 0,
                  "client closed connection");
    ngx_http_close_connection(c);
    return;
}

如果有類似於“listen 80 proxy_protocol;”的配置,尚未仔細研究

if (hc->proxy_protocol) {
        ...
}
ngx_reusable_connection(c, 0);

調用ngx_http_create_request函數初始化一個ngx_http_request_t結構體。

c->data = ngx_http_create_request(c);
if (c->data == NULL) {
    ngx_http_close_connection(c);
    return;
}

將目標連接的讀事件回調函數設置爲處理處理請求行

rev->handler = ngx_http_process_request_line;

獲取已經有數據到達,所以馬上執行處理請求行函數,在ngx_http_process_request_line中循環調用recv函數,從緩衝區中取東西出來。ngx_thttp_process_request_line函數可能會被調用多次。

ngx_http_process_request_line(rev);




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章