定义在 src\http\ngx_http_core_module.c
static char *
ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_core_srv_conf_t *prev = parent;
ngx_http_core_srv_conf_t *conf = child;
ngx_str_t name;
ngx_http_server_name_t *sn;
/* TODO: it does not merge, it inits only */
ngx_conf_merge_size_value(conf->connection_pool_size,
prev->connection_pool_size, 64 * sizeof(void *));
ngx_conf_merge_size_value(conf->request_pool_size,
prev->request_pool_size, 4096);
ngx_conf_merge_msec_value(conf->client_header_timeout,
prev->client_header_timeout, 60000);
ngx_conf_merge_size_value(conf->client_header_buffer_size,
prev->client_header_buffer_size, 1024);
ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
prev->large_client_header_buffers,
4, 8192);
if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the \"large_client_header_buffers\" size must be "
"equal to or greater than \"connection_pool_size\"");
return NGX_CONF_ERROR;
}
ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);
ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
ngx_conf_merge_value(conf->underscores_in_headers,
prev->underscores_in_headers, 0);
if (conf->server_names.nelts == 0) {
/* the array has 4 empty preallocated elements, so push cannot fail */
sn = ngx_array_push(&conf->server_names);
#if (NGX_PCRE)
sn->regex = NULL;
#endif
sn->server = conf;
ngx_str_set(&sn->name, "");
}
sn = conf->server_names.elts;
name = sn[0].name;
#if (NGX_PCRE)
if (sn->regex) {
name.len++;
name.data--;
} else
#endif
if (name.data[0] == '.') {
name.len--;
name.data++;
}
conf->server_name.len = name.len;
conf->server_name.data = ngx_pstrdup(cf->pool, &name);
if (conf->server_name.data == NULL) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
函数作用
合并 HTTP 核心模块的父级配置 (
parent
,通常来自http
块)和子级配置 (child
,通常来自server
块),处理默认值、约束条件和server_name
的规范化。
ngx_http_core_srv_conf_t *prev = parent;
ngx_http_core_srv_conf_t *conf = child;
ngx_str_t name;
ngx_http_server_name_t *sn;
prev
和conf
分别指向父级和子级的配置结构体。name
用于临时存储处理后的server_name
。sn
是指向server_names
数组元素的指针。
ngx_conf_merge_size_value(conf->connection_pool_size, prev->connection_pool_size, 64 * sizeof(void *));
- 作用 :合并
connection_pool_size
(连接内存池大小)。- 逻辑 :如果子配置未设置,继承父配置;若父配置也未设置,使用默认值
64 * sizeof(void *)
。- 意义 :确保每个连接的内存池大小合理,避免内存浪费或不足。
ngx_conf_merge_size_value-****博客
conf->connection_pool_size=-1
prev->connection_pool_size=-1执行后
conf->connection_pool_size=512
ngx_conf_merge_size_value(conf->request_pool_size, prev->request_pool_size, 4096);
- 作用 :合并
request_pool_size
(请求内存池大小)- 默认值 :4096
conf->request_pool_size=-1
prev->request_pool_size=-1执行后
conf->request_pool_size=4096
ngx_conf_merge_msec_value(conf->client_header_timeout, prev->client_header_timeout, 60000);
- 作用 :合并
client_header_timeout
(客户端头超时时间)- 默认值 :60,000 毫秒(60 秒)
ngx_conf_merge_msec_value-****博客
conf->client_header_timeout=18446744073709551615 (无符号长整型 -1,表示未设置)
prev->client_header_timeout=18446744073709551615
执行后
conf->client_header_timeout=60000
ngx_conf_merge_size_value(conf->client_header_buffer_size, prev->client_header_buffer_size, 1024);
- 作用 :合并
client_header_buffer_size
(客户端头缓冲区大小)。- 默认值 :1024
conf->client_header_buffer_size=-1
prev->client_header_buffer_size=-1
执行后
conf->client_header_buffer_size=1024
ngx_conf_merge_bufs_value(conf->large_client_header_buffers, prev->large_client_header_buffers, 4, 8192);
- 作用 :合并
large_client_header_buffers
(大头缓冲区配置)。- 默认值 :4 个缓冲区,每个 8KB。
ngx_conf_merge_bufs_value-****博客
conf->large_client_header_buffers.num=0
conf->large_client_header_buffers.size=0
prev->large_client_header_buffers.num=0
prev->large_client_header_buffers.size=0
执行后
conf->large_client_header_buffers.num=4
conf->large_client_header_buffers.size=8192
if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
ngx_conf_log_error(...);
return NGX_CONF_ERROR;
}
作用 :检查
large_client_header_buffers
的大小是否 ≥connection_pool_size
。逻辑 :若不满足,记录错误并终止配置合并。
意义 :确保大头缓冲区足够容纳连接内存池,避免内存越界。
conf->large_client_header_buffers.size=8192
conf->connection_pool_size=512条件不成立
ngx_conf_merge_value(conf->ignore_invalid_headers, prev->ignore_invalid_headers, 1);
作用 :合并
ignore_invalid_headers
(是否忽略无效头)默认值 :1(启用)
ngx_conf_merge_value-****博客
conf->ignore_invalid_headers=-1
prev->ignore_invalid_headers=-1
执行后
conf->ignore_invalid_headers=1
ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
作用 :合并 merge_slashes(是否合并连续斜杠)。
默认值 :1(启用)。conf->merge_slashes=-1
prev->merge_slashes=-1
执行后
conf->merge_slashes=1
ngx_conf_merge_value(conf->underscores_in_headers, prev->underscores_in_headers, 0);
作用 :合并
underscores_in_headers
(是否允许头字段包含下划线)默认值 :0(禁用)
conf->underscores_in_headers=-1
prev->underscores_in_headers=-1
执行后
conf->underscores_in_headers=0
if (conf->server_names.nelts == 0) {
/* the array has 4 empty preallocated elements, so push cannot fail */
sn = ngx_array_push(&conf->server_names);
#if (NGX_PCRE)
sn->regex = NULL;
#endif
sn->server = conf;
ngx_str_set(&sn->name, "");
}
作用 :若未配置
server_name
,添加默认空名称。逻辑 :向
server_names
数组添加一个元素,名称设为空字符串。意义 :确保每个虚拟主机至少有一个
server_name
(即使为空)。此时
conf->server_names.nelts=1
条件不成立
sn = conf->server_names.elts;
name = sn[0].name;
- 作用 :获取第一个
server_name
的名称。此时
name.data=localhost
#if (NGX_PCRE)
if (sn->regex) {
name.len++;
name.data--;
} else
#endif
作用 :如果使用正则表达式(PCRE),调整名称指针和长度。
逻辑 :正则表达式匹配的名称可能以特殊字符(如
~
)开头,需跳过。此时
sn->regex=(nil)
条件不成立
if (name.data[0] == '.') {
name.len--;
name.data++;
}
作用 :处理通配符域名(如
.example.com
)。逻辑 :去掉开头的点,转换为
example.com
,避免重复匹配。此时
name.data=localhost
条件不成立
conf->server_name.len = name.len;
conf->server_name.data = ngx_pstrdup(cf->pool, &name);
if (conf->server_name.data == NULL) {
return NGX_CONF_ERROR;
}
作用 :规范化后的
server_name
存入配置。逻辑 :使用
ngx_pstrdup
复制字符串到内存池新分配的内存意义 :主
server_name
用于日志、错误信息等场景。conf->server_name.len=9
conf->server_name.data=localhost
return NGX_CONF_OK;
返回 NGX_CONF_OK