情景:
開發了一個http模塊,掛在conten-phase階段,
static char * ngx_http_ivms(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf; clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); /* 設置回調函數。當請求http://127.0.0.1/ivms的時候,會調用此回調函數 */ clcf->handler = ngx_http_ivms_loc_handler; return NGX_CONF_OK; }
在ngx_http_ivms_loc_handler中讀取包體,回調為ngx_http_ivms_handler;
static ngx_int_t ngx_http_ivms_loc_handler(ngx_http_request_t *r) { ngx_int_t rc; rc = ngx_http_read_client_request_body(r, ngx_http_ivms_handler); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } // return NGX_OK; return NGX_DONE; }
在ngx_http_ivms_handler中處理包體並返回。
問題:
我想在處理完包體后銷毀這個request,調用ngx_http_finalize_request()之后發現連接沒法再次接收請求,原因是r->main->count =2;在銷毀請求過程中減一,發現還有引用,所以沒有銷毀請求而是直接返回了。
cgdb調試nginx,watch r->main->count(沒有子請求,所以這就是r->count),發現在創建r的時候r->count++,在ngx_http_read_client_request_body的時候r->count++;
解決:
我查看了nginx中ngx_http_read_client_request_body的使用,在其回調函數中並沒有找到r->count--,聽說在別的地方有減,但是我直接在其回調中r->count--,問題解決。
總結:
debug的時候發現,https://blog.csdn.net/ApeLife/article/details/74780059 這篇博文說的對:“到此,需要正常的關閉http請求了,但會不會馬上就關閉請求要看引用計數,引用計數為0則會關閉請求,但並不一定會馬上關閉tcp連接,因為有可能開啟了keepalive機制或者延遲關閉機制。也就是說引用計數決定是否需要關閉http請求,而keepalive機制或者延遲關閉機制則決定是否需要關閉tcp連接。”
請求中Connection: close,則r->keepalive =1時,不會直接銷毀會話,需要設置r->cln,當銷毀同一個connection的request的時候,會調用之前r->cln->handler,做清理工作;
請求中Connection: close,則r->keepalive=0時,request處理完,直接銷毀會話。