Ubuntu 下 nginx-1.24.0 源码分析 - ngx_show_version_info函数

ops/2025/2/13 0:36:09/

声明

在 nginx.c 开头

static void ngx_show_version_info(void);

实现

static void
ngx_show_version_info(void)
{ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED);if (ngx_show_help) {ngx_write_stderr("Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]" NGX_LINEFEED"             [-e filename] [-c filename] [-g directives]"NGX_LINEFEED NGX_LINEFEED"Options:" NGX_LINEFEED"  -?,-h         : this help" NGX_LINEFEED"  -v            : show version and exit" NGX_LINEFEED"  -V            : show version and configure options then exit"NGX_LINEFEED"  -t            : test configuration and exit" NGX_LINEFEED"  -T            : test configuration, dump it and exit"NGX_LINEFEED"  -q            : suppress non-error messages ""during configuration testing" NGX_LINEFEED"  -s signal     : send signal to a master process: ""stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX"  -p prefix     : set prefix path (default: " NGX_PREFIX ")"NGX_LINEFEED
#else"  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
#endif"  -e filename   : set error log file (default: "
#ifdef NGX_ERROR_LOG_STDERR"stderr)" NGX_LINEFEED
#elseNGX_ERROR_LOG_PATH ")" NGX_LINEFEED
#endif"  -c filename   : set configuration file (default: " NGX_CONF_PATH")" NGX_LINEFEED"  -g directives : set global directives out of configuration ""file" NGX_LINEFEED NGX_LINEFEED);}if (ngx_show_configure) {#ifdef NGX_COMPILERngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED);
#endif#if (NGX_SSL)if (ngx_strcmp(ngx_ssl_version(), OPENSSL_VERSION_TEXT) == 0) {ngx_write_stderr("built with " OPENSSL_VERSION_TEXT NGX_LINEFEED);} else {ngx_write_stderr("built with " OPENSSL_VERSION_TEXT" (running with ");ngx_write_stderr((char *) (uintptr_t) ngx_ssl_version());ngx_write_stderr(")" NGX_LINEFEED);}
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAMEngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED);
#elsengx_write_stderr("TLS SNI support disabled" NGX_LINEFEED);
#endif
#endifngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED);}
}

这段代码的作用是显示 Nginx 的版本信,帮助信息和编译配置  

当用户运行 Nginx 并带上特定的参数(比如 -v-h)时,

这段代码会告诉用户 Nginx 的版本号

这段代码主要做了两件事:

  1. 显示版本信息:告诉用户 Nginx 的版本号。

  2. 显示帮助信息:如果用户需要,就显示如何使用 Nginx 的各种参数。

static void ngx_show_version_info(void)

 static 是一个关键字,表示这个函数只能在当前文件中使用,外部文件无法调用它

void 表示这个函数没有返回值,没有参数

{ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED);

向标准错误流(stderr)写入 Nginx 的版本信息。

无论用户是否请求帮助(-h)或详细配置(-V),版本信息始终显示

 

ngx_write_stderr 是一个函数,用来把信息写到标准错误输出(通常是屏幕)

NGINX_VER_BUILD 是一个宏,包含了 Nginx 的版本信息。

NGX_LINEFEED 是一个宏,跨平台换行符(Windows用\r\n,Linux用\n

ngx_write_stderr

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_write_stderr函数-CSDN博客

NGINX_VER_BUILD

nginx.h 中:

#ifdef NGX_BUILD
#define NGINX_VER_BUILD    NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD    NGINX_VER
#endif

NGX_BUILD 

NGX_BUILD 是一个可选的宏,用于定义 Nginx 的构建信息

它通常在编译时通过 ./configure --build=name 命令设置。例如,如果在编译时指定了 --build=stable,那么 NGX_BUILD 的值将会是 "stable"

我这里当前是没有 定义 NGX_BUILD 的

  • 如果定义了NGX_BUILD

    • 将版本号与构建信息拼接,格式为:NGINX_VER (NGX_BUILD)

    • 示例:nginx/1.25.3 (2023-10-01 OpenSSL 1.1.1)

  • 如果未定义NGX_BUILD

    • 直接使用NGINX_VER,仅显示基础版本号。

    • 示例:nginx/1.25.3

NGINX_VER

是一个宏,用于定义 Nginx 的版本信息

它通常由字符串 "nginx/" 和另一个宏 NGINX_VERSION 拼接而成。例如,如果 NGINX_VERSION 被定义为 "1.21.0",那么 NGINX_VER 的值将会是 "nginx/1.21.0"

nginx.h 中:

#define nginx_version      1024000
#define NGINX_VERSION      "1.24.0"
#define NGINX_VER          "nginx/" NGINX_VERSION

 

NGX_LINEFEED

ngx_files.h 中:

#define NGX_LINEFEED             "\x0a"

换行符“\n”在ASCII编码中的值是10

在C语言中,相邻的字符串字面量会在编译阶段自动合并为一个字符串 

当代码中的宏被展开后

"nginx version: " "1.24.0" "\n"

C 语言在编译时会自动将这些相邻的字符串拼接起来,形成完整的字符串

"nginx version: 1.24.0\n"
    if (ngx_show_help) {

处理帮助信息(-h 或 -?) 

if 是一个条件语句,用来判断某个条件是否成立。ngx_show_help 是一个变量,如果用户请求帮助信息,这个变量会被设置为真。 

这行代码的意思是:如果用户需要帮助信息,就执行下面的代码块。

用户通过-h-?参数触发,全局变量ngx_show_help被设置为1

        ngx_write_stderr("Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]" NGX_LINEFEED"             [-e filename] [-c filename] [-g directives]"NGX_LINEFEED NGX_LINEFEED"Options:" NGX_LINEFEED"  -?,-h         : this help" NGX_LINEFEED"  -v            : show version and exit" NGX_LINEFEED"  -V            : show version and configure options then exit"NGX_LINEFEED"  -t            : test configuration and exit" NGX_LINEFEED"  -T            : test configuration, dump it and exit"NGX_LINEFEED"  -q            : suppress non-error messages ""during configuration testing" NGX_LINEFEED"  -s signal     : send signal to a master process: ""stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX"  -p prefix     : set prefix path (default: " NGX_PREFIX ")"NGX_LINEFEED
#else"  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
#endif"  -e filename   : set error log file (default: "
#ifdef NGX_ERROR_LOG_STDERR"stderr)" NGX_LINEFEED
#elseNGX_ERROR_LOG_PATH ")" NGX_LINEFEED
#endif"  -c filename   : set configuration file (default: " NGX_CONF_PATH")" NGX_LINEFEED"  -g directives : set global directives out of configuration ""file" NGX_LINEFEED NGX_LINEFEED);

使用 ngx_write_stderr 逐行拼接多段字符串,避免一次性分配大内存

如果用户需要帮助,这段代码会列出所有可以用的命令参数和它们的含义。比如 -v 表示显示版本号并退出,-h 表示显示帮助信息。

#ifdef NGX_PREFIX:根据编译时的 --prefix 参数显示默认安装路径(如/usr/local/nginx/

#ifdef NGX_ERROR_LOG_STDERR:根据配置决定错误日志默认输出到 stderr 还是文件

例如:

NGX_PREFIX

objs/ngx_auto_config.h 中:

#ifndef NGX_PREFIX
#define NGX_PREFIX  "/usr/local/nginx/"
#endif

NGX_PREFIX 宏在 Nginx 的源代码中被用来确定各种文件的默认路径,例如配置文件、日志文件等。

可以在编译时设置 --prefix=

如果没有指定 --prefix 参数,NGX_PREFIX 宏的默认值通常是 /usr/local/nginx

NGX_ERROR_LOG_STDERR

NGX_ERROR_LOG_STDERR 宏用于指定错误日志的输出目标为标准错误输出(stderr)

当 Nginx 需要记录错误日志时,如果配置了 NGX_ERROR_LOG_STDERR,则错误日志信息会被输出到标准错误流,而不是写入到文件或其他日志存储位置

我这里没有定义 NGX_ERROR_LOG_STDERR, 因为在编译前指定了--error-log-path 参数

NGX_ERROR_LOG_PATH

在 objs\ngx_auto_config.h 中:

#ifndef NGX_ERROR_LOG_PATH
#define NGX_ERROR_LOG_PATH  "/home/wsd/桌面/nginx/LOG/error.log"
#endif

NGX_ERROR_LOG_PATH 就是 --error-log-path= 参数这里指定的

NGX_CONF_PATH

objs\ngx_auto_config.h 中:


#ifndef NGX_CONF_PATH
#define NGX_CONF_PATH  "/home/wsd/桌面/nginx/conf/nginx.conf"
#endif

NGX_CONF_PATH 宏用于指定 Nginx 配置文件 nginx.conf 的路径

可以在编译时通过 --conf-path 参数指定

./configure --conf-path=/path/to/your/nginx.conf

    if (ngx_show_configure) {

处理详细配置信息(-V

输出编译环境和配置选项

if 是条件语句,ngx_show_configure 是一个变量,如果用户请求显示配置信息,这个变量会被设置为真 

这行代码的意思是:如果用户需要查看配置信息(-V),就执行下面的代码块

用户通过-V参数触发,全局变量ngx_show_configure被设置为1

#ifdef NGX_COMPILERngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED);
#endif

fdef 是预处理指令,用来判断是否定义了 NGX_COMPILER 宏。

NGX_COMPILER 是一个宏,包含了编译 Nginx 的编译器信息。 

如果定义了 NGX_COMPILER,就输出编译 Nginx 的编译器信息

NGX_COMPILER

objs\ngx_auto_config.h

#ifndef NGX_COMPILER
#define NGX_COMPILER  "gcc 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) "
#endif

NGX_COMPILER 宏用于记录编译 Nginx 时所使用的编译器信息

#if (NGX_SSL)if (ngx_strcmp(ngx_ssl_version(), OPENSSL_VERSION_TEXT) == 0) {ngx_write_stderr("built with " OPENSSL_VERSION_TEXT NGX_LINEFEED);} else {ngx_write_stderr("built with " OPENSSL_VERSION_TEXT" (running with ");ngx_write_stderr((char *) (uintptr_t) ngx_ssl_version());ngx_write_stderr(")" NGX_LINEFEED);}
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAMEngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED);
#elsengx_write_stderr("TLS SNI support disabled" NGX_LINEFEED);
#endif
#endif

if 是预处理指令,用来判断是否定义了 NGX_SSL

ngx_strcmp 是一个函数,用来比较两个字符串是否相等

ngx_ssl_version 是一个函数,用来获取 SSL 的版本信息

NGX_SSL 表示启用了 SSL 模块。

ngx_ssl_version() 返回运行时 OpenSSL 版本,OPENSSL_VERSION_TEXT 是编译时版本。

如果版本不一致,提示用户(可能导致兼容性问题)

输出 SNI 支持状态

显示是否支持 TLS SNI(Server Name Indication)。

SSL_CTRL_SET_TLSEXT_HOSTNAME 宏的存在表示支持 SNI。

SNI 是托管多个 HTTPS 站点的关键功能,用户需知晓支持状态

NGX_SSL

objs\ngx_auto_config.h 中:

#ifndef NGX_SSL
#define NGX_SSL  1
#endif

 NGX_SSL 宏用于指示 Nginx 是否启用了 SSL/TLS 支持

在编译 Nginx 时,可以通过 --with-http_ssl_module 参数启用 SSL/TLS 支持

ngx_strcmp

ngx_string.h 中

#define ngx_strcmp(s1, s2)  strcmp((const char *) s1, (const char *) s2)

本质就是 strcmp

在 C 语言中,strcmp 是一个标准库函数,用于比较两个字符串的大小。它在 <string.h> 头文件中定义。

  • 如果第一个字符串大于第二个字符串,返回正值。

  • 如果两个字符串相等,返回 0。

  • 如果第一个字符串小于第二个字符串,返回负值。

ngx_ssl_version

获取 SSL 的版本信息         Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_version 函数-CSDN博客

OPENSSL_VERSION_TEXT

OPENSSL_VERSION_TEXT 是 OpenSSL 库中定义的一个宏,用于获取 OpenSSL 的完整描述性版本文本,包括版本号和发布日期

可以用以下 代码 输出一下 OPENSSL_VERSION_TEXT 的值

gcc test.c -o test -lcrypto -lssl

#include <openssl/opensslv.h>
#include <stdio.h>int main() {printf("OpenSSL version text: %s\n", OPENSSL_VERSION_TEXT);return 0;
}

SSL_CTRL_SET_TLSEXT_HOSTNAME

SSL_CTRL_SET_TLSEXT_HOSTNAME 是 OpenSSL 中的一个宏,用于设置 TLS 扩展中的 Server Name Indication (SNI) 主机名。

可以用下面的代码输出一下 SSL_CTRL_SET_TLSEXT_HOSTNAME  的值

gcc test.c -o test -lcrypto -lssl

#include <openssl/ssl.h>
#include <stdio.h>int main() {// 输出 SSL_CTRL_SET_TLSEXT_HOSTNAME 的值printf("SSL_CTRL_SET_TLSEXT_HOSTNAME 的值是: %d\n", SSL_CTRL_SET_TLSEXT_HOSTNAME);return 0;
}

        ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED);

NGX_CONFIGURE 是一个宏,包含了编译 Nginx 时的配置参数

这行代码会输出编译 Nginx 时用到的配置参数

 例如:

NGX_CONFIGURE

在 objs\ngx_auto_config.h 中:

#define NGX_CONFIGURE " --sbin-path=/home/wsd/桌面/nginx/nginx --conf-path=/home/wsd/桌面/nginx/conf/nginx.conf --error-log-path=/home/wsd/桌面/nginx/LOG/error.log --http-log-path=/home/wsd/桌面/nginx/LOG/access.log --with-pcre --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module"


http://www.ppmy.cn/ops/157906.html

相关文章

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图&#xff0c;我的百度网盘已登录设备列表&#xff0c;有一个手机&#xff0c;2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的&#xff1f;下面分别给出android APP中采集手机信…

安全行业大模型SecLLM技术白皮书

在ChatGPT 呈现全球现象级热度时&#xff0c;通用大语言模型&#xff08;Large Language Model, LLM&#xff09;技术成为了推动创新和变革的关键驱动力。但由于安全行业的特殊性和复杂性&#xff0c;LLM 并不能满足其应用需求。安全行业大模型(Security Large Language Model,…

社区版IDEA中配置TomCat(详细版)

文章目录 1、下载Smart TomCat2、配置TomCat3、运行代码 1、下载Smart TomCat 由于小编的是社区版&#xff0c;没有自带的tomcat server&#xff0c;所以在设置的插件里面搜索&#xff0c;安装第一个&#xff08;注意&#xff1a;安装时一定要关闭外网&#xff0c;小编因为这个…

利用HTML和css技术编写学校官网页面

目录 一&#xff0c;图例展示 二&#xff0c;代码说明 1&#xff0c;html部分&#xff1a; 【第一张图片】 【第二张图片】 【第三张图片】 2&#xff0c;css部分&#xff1a; 【第一张图片】 【第二张图片】 【第三张图片】 三&#xff0c;程序代码 一&#xff0c;…

e2studio开发RA2E1(12)----打印函数(printf、 sprintf)的实现

e2studio开发RA2E1.12--打印函数printf、 sprintf的实现 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uar…

EtherNet/IP转Modbus TCP实现三菱变频器与西门子PLC通讯的配置案例

EtherNet/IP转Modbus TCP实现三菱变频器与西门子PLC通讯的配置案例 一、案例背景 某汽车制造公司拥有一条高度自动化的生产线&#xff0c;该生产线集成了来自不同品牌的机器人、传感器和检测设备。这些设备分别采用MODBUS TCP和EtherNet/IP协议进行通信&#xff0c;但由于协议…

疯狂前端面试题(二)

一、Webpack的理解 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。Webpack 能够将各种资源&#xff08;JavaScript、CSS、图片、字体等&#xff09;视为模块&#xff0c;并通过依赖关系图将这些模块打包成一个或多个最终的输出文件&#xff08;通常是一个或几个…

Java算法技术文章:深入解析排序、搜索与数据结构

引言 在软件开发的世界里&#xff0c;算法不仅是程序设计的基础&#xff0c;更是提升软件性能、优化用户体验的关键。Java&#xff0c;作为一种广泛使用的编程语言&#xff0c;提供了丰富的API和标准库来支持各种算法的实现。本文将深入探讨Java中的排序算法、搜索算法以及一些…