定义在 src\http\modules\ngx_http_index_module.c
static char *
ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_index_loc_conf_t *ilcf = conf;
ngx_str_t *value;
ngx_uint_t i, n;
ngx_http_index_t *index;
ngx_http_script_compile_t sc;
if (ilcf->indices == NULL) {
ilcf->indices = ngx_array_create(cf->pool, 2, sizeof(ngx_http_index_t));
if (ilcf->indices == NULL) {
return NGX_CONF_ERROR;
}
}
value = cf->args->elts;
for (i = 1; i < cf->args->nelts; i++) {
if (value[i].data[0] == '/' && i != cf->args->nelts - 1) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"only the last index in \"index\" directive "
"should be absolute");
}
if (value[i].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"index \"%V\" in \"index\" directive is invalid",
&value[1]);
return NGX_CONF_ERROR;
}
index = ngx_array_push(ilcf->indices);
if (index == NULL) {
return NGX_CONF_ERROR;
}
index->name.len = value[i].len;
index->name.data = value[i].data;
index->lengths = NULL;
index->values = NULL;
n = ngx_http_script_variables_count(&value[i]);
if (n == 0) {
if (ilcf->max_index_len < index->name.len) {
ilcf->max_index_len = index->name.len;
}
if (index->name.data[0] == '/') {
continue;
}
/* include the terminating '\0' to the length to use ngx_memcpy() */
index->name.len++;
continue;
}
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
sc.cf = cf;
sc.source = &value[i];
sc.lengths = &index->lengths;
sc.values = &index->values;
sc.variables = n;
sc.complete_lengths = 1;
sc.complete_values = 1;
if (ngx_http_script_compile(&sc) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
return NGX_CONF_OK;
}
ngx_http_index_set_index
函数是 Nginx 中处理index
配置指令的核心逻辑
if (ilcf->indices == NULL) {
ilcf->indices = ngx_array_create(cf->pool, 2, sizeof(ngx_http_index_t));
if (ilcf->indices == NULL) {
return NGX_CONF_ERROR;
}
}
通过
ilcf->indices == NULL
判断当前配置块的indices
数组是否未被初始化
ilcf->indices
是 Nginx 中用于 存储index
指令配置的索引文件列表 的核心数据结构它是一个动态数组(
ngx_array_t
类型),每个元素是ngx_http_index_t
结构体,表示一个索引文件(如index.html
)ngx_http_index_loc_conf_t-CSDN博客
此时
ilcf->indices= NULL
进入这个条件
value = cf->args->elts;
for (i = 1; i < cf->args->nelts; i++) {
if (value[i].data[0] == '/' && i != cf->args->nelts - 1) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"only the last index in \"index\" directive "
"should be absolute");
}
校验
index
指令参数的合法性 ,确保绝对路径的索引文件(以/
开头)只能作为最后一个参数
- Nginx 按顺序检查索引文件,一旦找到匹配的文件即停止搜索。
- 绝对路径通常指向固定位置,作为“最终回退选项”更合理。
- 如果绝对路径出现在中间参数,可能导致后续参数被忽略,引发配置逻辑错误
if (value[i].len == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"index \"%V\" in \"index\" directive is invalid",
&value[1]);
return NGX_CONF_ERROR;
}
校验
index
指令中每个索引文件名的合法性 ,确保文件名非空
index = ngx_array_push(ilcf->indices);
if (index == NULL) {
return NGX_CONF_ERROR;
}
在
ilcf->indices
数组末尾分配一个新元素
index->name.len = value[i].len;
index->name.data = value[i].data;
index->lengths = NULL;
index->values = NULL;
设置新元素的各个字段
index->name.len = value[i].len; // (1) 复制文件名长度
index->name.data = value[i].data; // (2) 复制文件名数据指针
index->lengths = NULL; // (3) 标记无需动态长度计算
index->values = NULL; // (4) 标记无需动态值生成
n = ngx_http_script_variables_count(&value[i]);
统计
index
指令参数中变量的数量此时 n=0
if (n == 0) {
if (ilcf->max_index_len < index->name.len) {
ilcf->max_index_len = index->name.len;
}
if (index->name.data[0] == '/') {
continue;
}
/* include the terminating '\0' to the length to use ngx_memcpy() */
index->name.len++;
continue;
}
if (n == 0) { // (1) 确认为静态文件名(无变量)
// (2) 更新最大文件名长度
if (ilcf->max_index_len < index->name.len) {
ilcf->max_index_len = index->name.len;
}// (3) 跳过绝对路径的特殊处理
if (index->name.data[0] == '/') {
continue;
}// (4) 包含终止符 '\0' 的长度调整
index->name.len++;continue; // (5) 跳出循环,避免动态编译逻辑
}
2次 continue 然后循环结束
return NGX_CONF_OK;
返回 NGX_CONF_OK