ngx_conf_handler

定義在?src\core\ngx_conf_file.c

static ngx_int_t
ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{char           *rv;void           *conf, **confp;ngx_uint_t      i, found;ngx_str_t      *name;ngx_command_t  *cmd;name = cf->args->elts;found = 0;for (i = 0; cf->cycle->modules[i]; i++) {cmd = cf->cycle->modules[i]->commands;if (cmd == NULL) {continue;}for ( /* void */ ; cmd->name.len; cmd++) {if (name->len != cmd->name.len) {continue;}if (ngx_strcmp(name->data, cmd->name.data) != 0) {continue;}found = 1;if (cf->cycle->modules[i]->type != NGX_CONF_MODULE&& cf->cycle->modules[i]->type != cf->module_type){continue;}/* is the directive's location right ? */if (!(cmd->type & cf->cmd_type)) {continue;}if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" is not terminated by \";\"",name->data);return NGX_ERROR;}if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" has no opening \"{\"",name->data);return NGX_ERROR;}/* is the directive's argument count right ? */if (!(cmd->type & NGX_CONF_ANY)) {if (cmd->type & NGX_CONF_FLAG) {if (cf->args->nelts != 2) {goto invalid;}} else if (cmd->type & NGX_CONF_1MORE) {if (cf->args->nelts < 2) {goto invalid;}} else if (cmd->type & NGX_CONF_2MORE) {if (cf->args->nelts < 3) {goto invalid;}} else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {goto invalid;} else if (!(cmd->type & argument_number[cf->args->nelts - 1])){goto invalid;}}/* set up the directive's configuration context */conf = NULL;if (cmd->type & NGX_DIRECT_CONF) {conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];} else if (cmd->type & NGX_MAIN_CONF) {conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]);} else if (cf->ctx) {confp = *(void **) ((char *) cf->ctx + cmd->conf);if (confp) {conf = confp[cf->cycle->modules[i]->ctx_index];}}rv = cmd->set(cf, cmd, conf);if (rv == NGX_CONF_OK) {return NGX_OK;}if (rv == NGX_CONF_ERROR) {return NGX_ERROR;}ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"\"%s\" directive %s", name->data, rv);return NGX_ERROR;}}if (found) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"\"%s\" directive is not allowed here", name->data);return NGX_ERROR;}ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"unknown directive \"%s\"", name->data);return NGX_ERROR;invalid:ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"invalid number of arguments in \"%s\" directive",name->data);return NGX_ERROR;
}

ngx_conf_handler?是 Nginx 配置解析的核心函數,其主要作用是根據當前解析到的配置指令,找到對應的模塊命令并執行相關校驗和設置


    name = cf->args->elts;found = 0;

?name = cf->args->elts;
將當前配置指令的參數列表(數組)的起始地址賦值給 name 指針,以便后續遍歷和匹配指令名。

found = 0;
初始化標志變量 found 為 0,表示尚未找到與當前配置指令匹配的模塊命令。

found 是一個布爾標記,用于記錄是否在模塊的指令列表中成功匹配到當前指令名。
初始值為 0(未找到),在后續遍歷模塊的 commands 數組時,若匹配到指令名,則置為 1


此時

name->data=worker_processes


worker_processes?用于定義 Nginx 工作進程(Worker Processes)的數量

  • 每個 worker_process 是一個獨立的進程,負責處理客戶端請求。
  • 多進程設計 :通過啟用多個工作進程,Nginx 可以充分利用多核 CPU 的性能,實現高并發處理。
  • 默認值 1(但通常建議根據服務器 CPU 核心數調整)。

    for (i = 0; cf->cycle->modules[i]; i++) {cmd = cf->cycle->modules[i]->commands;if (cmd == NULL) {continue;}

?遍歷 Nginx 所有已加載的模塊,檢查每個模塊是否包含需要處理的配置指令。

獲取模塊的指令列表:cmd = cf->cycle->modules[i]->commands;
獲取當前模塊支持的配置指令列表(commands 數組),用于后續匹配當前解析的指令。

commands 是 ngx_module_t 結構體的成員,指向一個 ngx_command_t 數組,表示該模塊支持的配置指令。

cmd 是 ngx_command_t* 類型指針,指向當前模塊的指令列表。
后續內層循環會遍歷 cmd 數組,匹配當前配置指令名。

跳過無指令的模塊:if (cmd == NULL) { continue; }
如果當前模塊沒有定義任何配置指令(commands 為 NULL),則跳過該模塊,繼續檢查下一個模塊。
某些模塊可能不處理配置指令(例如僅提供功能的模塊),其 commands 字段會被設為 NULL。

意圖
遍歷所有模塊
通過外層循環,確保每個模塊都有機會檢查是否支持當前解析的配置指令。

篩選有效模塊
僅處理包含配置指令(commands 非空)的模塊,忽略無指令的模塊。

為內層循環做準備
每個模塊的 commands 數組將在內層循環中被遍歷,逐個匹配指令名


for ( /* void */ ; cmd->name.len; cmd++) {

?遍歷當前模塊的指令列表(commands?數組),逐個匹配當前解析的配置指令名。


cmd->name.len?為 0 時,表示已遍歷到指令列表的末尾(每個模塊的?commands?數組以?cmd->name.len = 0?的哨兵元素結束)。


?

            if (name->len != cmd->name.len) {continue;}

如果長度不同,說明指令名一定不匹配,直接跳過當前?cmd


            if (ngx_strcmp(name->data, cmd->name.data) != 0) {continue;}

?

比較當前配置指令名與模塊定義的指令名是否完全一致。

  • 返回值為 0 表示字符串內容完全相同,說明找到匹配的指令。

  • 若名稱不匹配,跳過當前指令,繼續檢查下一個?cmd


ngx_strcmp

ngx_strcmp-CSDN博客


found = 1;

?找到了 匹配的指令


此時

cf->cycle->modules[0]->name=ngx_core_module


?

            if (cf->cycle->modules[i]->type != NGX_CONF_MODULE&& cf->cycle->modules[i]->type != cf->module_type){continue;}

如果當前模塊類型?既不是通用配置模塊也不匹配當前配置階段的模塊類型cf->module_type),則跳過該指令


?此時

cf->cycle->modules[0]->type=0x45524F43
cf->module_type=0x45524F43
NGX_CONF_MODULE=0x464E4F43


0x45524F43 是?NGX_CORE_MODULE

./nginx-1.24.0/src/core/ngx_conf_file.h:70:#define NGX_CORE_MODULE      0x45524F43  /* "CORE" */

條件不成立


            /* is the directive's location right ? */if (!(cmd->type & cf->cmd_type)) {continue;}

驗證 配置指令出現的位置


cmd->type 表示該指令預期可以出現的位置

cf->cmd_type 表示當前配置文件中的位置


此時

cmd->type? ? ?=0x1010002
cf->cmd_type=0x1000000 (NGX_MAIN_CONF)

./nginx-1.24.0/src/core/ngx_conf_file.h:51:#define NGX_MAIN_CONF        0x01000000


?

            if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" is not terminated by \";\"",name->data);return NGX_ERROR;}
檢查非塊指令是否以分號結尾
  • cmd->type & NGX_CONF_BLOCK
    NGX_CONF_BLOCK?是塊指令標志,若未設置,說明當前指令是非塊指令
  • last != NGX_OK
    last?參數表示解析器的狀態:
    • NGX_OK:正常結束(指令以分號?;?結尾)。

#define NGX_CONF_BLOCK       0x00000100

此時

last=0 (NGX_OK



            if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"directive \"%s\" has no opening \"{\"",name->data);return NGX_ERROR;}

?若指令是塊類型,但未以?{?開始(last?非?NGX_CONF_BLOCK_START),則觸發錯誤:


#define NGX_CONF_BLOCK_START 1

?

當前指令不是塊類型


?

            /* is the directive's argument count right ? */if (!(cmd->type & NGX_CONF_ANY)) {

檢查指令的參數數量


NGX_CONF_ANY?表示指令允許任意數量參數

不是?允許任意數量參數?

進入進一步的檢查


此時條件成立

cf->args->nelts=2


                if (cmd->type & NGX_CONF_FLAG) {if (cf->args->nelts != 2) {goto invalid;}}

?

  • NGX_CONF_FLAG?表示指令需要一個布爾值參數。
  • 布爾指令的完整格式為?指令名 參數,參數數量必須為 2(例如?rewrite_log on;)

此時條件不成立


            else if (cmd->type & NGX_CONF_1MORE) {if (cf->args->nelts < 2) {goto invalid;}} 

NGX_CONF_1MORE?表示指令需要至少 1 個參數


此時條件不成立


                } else if (cmd->type & NGX_CONF_2MORE) {if (cf->args->nelts < 3) {goto invalid;}}

NGX_CONF_2MORE?表示指令需要至少 2 個參數


此時條件不成立


                } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {goto invalid;}

檢查參數總數是否超過允許的最大值


此時條件不成立


                } else if (!(cmd->type & argument_number[cf->args->nelts - 1])){goto invalid;}

?精確匹配參數數量(當前指令的參數數量是固定的而不是 至少一個這種不固定的)

argument_number?是一個預定義的數組,將參數數量映射到對應的標志位。例如

static ngx_uint_t argument_number[] = {NGX_CONF_NOARGS,  // 0 參數(僅指令名)NGX_CONF_TAKE1,   // 1 參數NGX_CONF_TAKE2,   // 2 參數// ... 其他
};

cf->args->nelts - 1?將參數總數轉換為實際參數數量(減去指令名)


此時條件不成立

通過了參數數量的校驗


?

            /* set up the directive's configuration context */conf = NULL;if (cmd->type & NGX_DIRECT_CONF) {conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];

為指令(cmd)設置配置上下文(conf),并調用指令的?set?方法將配置值寫入上下文。
根據指令類型選擇不同的配置存儲位置,最終處理?set?方法的返回值。


NGX_DIRECT_CONF 是一種指令類型,用于定義必須直接出現在配置文件頂層(全局作用域)的指令,而不是嵌套在 httpserverlocation 等子配置塊中?


NGX_DIRECT_CONF?指令的配置結構指針直接存儲在模塊的配置數組中


此時 條件成立

cf->cycle->modules[0]->index=0


rv = cmd->set(cf, cmd, conf);

?調用指令的?set?方法,解析指令,然后設置其所在配置結構的對應字段


當前指令是 worker_processes

worker_processes 指令的 set 函數

worker_processes 指令的 set 函數-CSDN博客


            if (rv == NGX_CONF_OK) {return NGX_OK;}

?返回 NGX_OK ,代表 指令處理成功

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75632.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75632.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75632.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu系統美化

Ubuntu系統美化 一、Grub設置 1. 安裝Grub Customizer【推薦】 Grub Customizer是一個用于自定義 GRUB 引導菜單的實用程序 sudo add-apt-repository ppa:danielrichter2007/grub-customizer && sudo apt update && sudo apt install -y grub-customizer2.…

零基礎HTML·筆記(持續更新…)

基礎認知 HTML標簽的結構 <strong>文字變粗</strong> &#xff1c;開始標簽&#xff1e;內容&#xff1c;結束標簽&#xff1e; 結構說明&#xff1a; 標簽由<、>、1、英文單詞或字母組成。并且把標簽中<>包括起來的英文單詞或字母稱為標簽名。常…

nmcli創建wpa-psk2 wifi熱點

1. 創建新的WiFi連接&#xff1a; sudo nmcli connection add type wifi ifname wlan0 con-name WiFi名稱 autoconnect yes ssid WiFi名稱 2. 配置接入點模式和IP共享&#xff1a; sudo nmcli connection modify WiFi名稱 802-11-wireless.mode ap 802-11-wireless.band …

【消息隊列kafka_中間件】一、快速入門分布式消息隊列

在當今大數據和分布式系統盛行的時代&#xff0c;消息隊列作為一種關鍵的中間件技術&#xff0c;發揮著舉足輕重的作用。其中&#xff0c;Apache Kafka 以其卓越的性能、高可擴展性和強大的功能&#xff0c;成為眾多企業構建分布式應用的首選消息隊列解決方案。本篇文章將帶你深…

在線地圖支持天地圖和騰訊地圖,儀表板和數據大屏支持發布功能,DataEase開源BI工具v2.10.7 LTS版本發布

2025年4月11日&#xff0c;人人可用的開源BI工具DataEase正式發布v2.10.7 LTS版本。 這一版本的功能變動包括&#xff1a;數據源方面&#xff0c;Oracle數據源支持獲取和查詢物化視圖&#xff1b;圖表方面&#xff0c;在線地圖支持天地圖、騰訊地圖&#xff1b;新增子彈圖&…

【Linux實踐系列】:匿名管道收尾+完善shell外殼程序

&#x1f525; 本文專欄&#xff1a;Linux Linux實踐項目 &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 人生總會有自己能力所不及的范圍&#xff0c;但是如果你在你能力所及的范圍盡了全部的努力&#xff0c;那你還有什么遺…

【C++初學】課后作業匯總復習(七) 指針-深淺copy

1、 HugeInt類:構造、、cout Description: 32位整數的計算機可以表示整數的范圍近似為&#xff0d;20億到&#xff0b;20億。在這個范圍內操作一般不會出現問題&#xff0c;但是有的應用程序可能需要使用超出上述范圍的整數。C可以滿足這個需求&#xff0c;創建功能強大的新的…

【C++】 —— 筆試刷題day_16

刷題_day16&#xff0c;繼續加油啊 一、字符串替換 題目解析 這道題是一道簡單的字符題目&#xff0c;題目給我們一個字符串A&#xff0c;和n表示A字符串的長度&#xff0c;再給出一個字符數組arg&#xff0c;m表示arg中是數據個數。 然我們在字符串A中找到%s然后替換成arg中的…

n8n 本地部署及實踐應用,實現零成本自動化運營 Telegram 頻道(保證好使)

n8n 本地部署及實踐應用&#xff0c;實現零成本自動化運營 Telegram 頻道&#xff08;保證好使&#xff09; 簡介 n8n 介紹 一、高度可定制性 二、豐富的連接器生態 三、自托管部署&#xff08;本地部署&#xff09; 四、社區驅動 n8n 的部署 一、前期準備 二、部署步…

flutter 桌面應用之系統托盤

系統托盤(Tray) 系統托盤就是狀態欄里面對應的圖標點擊菜單 主要有兩款框架 框架一句話評價tray_manager輕量、簡單、易用&#xff0c;適合常規托盤功能system_tray更底層、更強大、支持圖標/菜單/消息彈窗等更多功能&#xff0c;但復雜度更高 &#x1f9f1; 基礎能力對比 …

修改idea/android studio等編輯器快捷注釋從當前行開頭的反人類行為

不知道什么時候開始&#xff0c;idea編輯的快捷注釋開始從當前行開頭出現了&#xff0c;顯得實在是難受&#xff0c;我只想讓在當前行代碼的部份開始縮進兩個字符開始&#xff0c;這樣才會顯得更舒服。不知道有沒有強迫癥的猴子和我一樣&#xff0c;就像下面的效果&#xff1a;…

MySQL慢查詢全攻略:定位、分析與優化實戰

&#x1f680; MySQL慢查詢全攻略&#xff1a;定位、分析與優化實戰 #數據庫優化 #性能調優 #SQL優化 #MySQL實戰 一、慢查詢定位&#xff1a;找到性能瓶頸 1.1 開啟慢查詢日志 -- 查看當前配置 SHOW VARIABLES LIKE %slow_query%; -- 動態開啟&#xff08;重啟失效&…

當原型圖與文字說明完全不同時,測試要怎么做?

當測試遇上左右手互搏的需求&#xff0c;怎么辦&#xff1f; "這個彈窗樣式怎么和文檔寫的不一樣&#xff1f;"、"按鈕位置怎么跑到左邊去了&#xff1f;"——根據Deloitte的調查&#xff0c;62%的項目存在原型圖與需求文檔不一致的情況。這種"精神分…

關于量化交易在拉盤砸盤方面應用的部分思考

關于“砸盤”的深層解析與操盤邏輯 ??一、砸盤的本質與市場含義?? ??砸盤??指通過集中拋售大量籌碼導致價格快速下跌的行為&#xff0c;其核心目標是??制造恐慌、清洗浮籌或實現利益再分配??。不同場景下的砸盤含義不同&#xff1a; ??主動砸盤&#xff08;操控…

【項目管理】第12章 項目質量管理-- 知識點整理

項目管理-相關文檔,希望互相學習,共同進步 風123456789~-CSDN博客 (一)知識總覽 項目管理知識域 知識點: (項目管理概論、立項管理、十大知識域、配置與變更管理、績效域) 對應:第6章-第19章 第6章 項目管理概論 4分第13章 項目資源管理 3-4分第7章 項目…

一個好看的圖集展示html頁面源碼

源碼介紹 一個好看的圖集展示html頁面源碼&#xff0c;適合展示自己的作品&#xff0c;頁面美觀大氣&#xff0c;也可以作為產品展示或者個人引導頁等等 源碼由HTMLCSSJS組成&#xff0c;記事本打開源碼文件可以進行內容文字之類的修改&#xff0c; 雙擊html文件可以本地運行…

2021第十二屆藍橋杯大賽軟件賽省賽C/C++ 大學 B 組

記錄刷題的過程、感悟、題解。 希望能幫到&#xff0c;那些與我一同前行的&#xff0c;來自遠方的朋友&#x1f609; 大綱&#xff1a; 1、空間-&#xff08;題解&#xff09;-字節單位轉換 2、卡片-&#xff08;題解&#xff09;-可以不用當組合來寫&#xff0c;思維題 3、直…

LabVIEW 中 JSON 數據與簇的轉換

在 LabVIEW 編程中&#xff0c;數據格式的處理與轉換是極為關鍵的環節。其中&#xff0c;將數據在 JSON 格式與 LabVIEW 的簇結構之間進行轉換是一項常見且重要的操作。這里展示的程序片段就涉及到這一關鍵功能&#xff0c;以下將詳細介紹。 一、JSON 數據與簇的轉換功能 &am…

藍橋杯大模板

init.c void System_Init() {P0 0x00; //關閉蜂鳴器和繼電器P2 P2 & 0x1f | 0xa0;P2 & 0x1f;P0 0x00; //關閉LEDP2 P2 & 0x1f | 0x80;P2 & 0x1f; } led.c #include <LED.H>idata unsigned char temp_1 0x00; idata unsigned char temp_old…

通過HTTP協議實現Git免密操作的解決方案

工作中會遇到這樣的問題的。 通過HTTP協議實現Git免密操作的解決方案 方法一&#xff1a;啟用全局憑據存儲&#xff08;推薦&#xff09; 配置憑證存儲? 執行以下命令&#xff0c;讓Git永久保存賬號密碼&#xff08;首次操作后生效&#xff09;&#xff1a; git config --g…