当前位置: 首页 > news >正文

ngx_http_core_server_name

定义在 src\http\ngx_http_core_module.c

static char *
ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_core_srv_conf_t *cscf = conf;

    u_char                   ch;
    ngx_str_t               *value;
    ngx_uint_t               i;
    ngx_http_server_name_t  *sn;

    value = cf->args->elts;

    for (i = 1; i < cf->args->nelts; i++) {

        ch = value[i].data[0];

        if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
            || (ch == '.' && value[i].len < 2))
        {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "server name \"%V\" is invalid", &value[i]);
            return NGX_CONF_ERROR;
        }

        if (ngx_strchr(value[i].data, '/')) {
            ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                               "server name \"%V\" has suspicious symbols",
                               &value[i]);
        }

        sn = ngx_array_push(&cscf->server_names);
        if (sn == NULL) {
            return NGX_CONF_ERROR;
        }

#if (NGX_PCRE)
        sn->regex = NULL;
#endif
        sn->server = cscf;

        if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) {
            sn->name = cf->cycle->hostname;

        } else {
            sn->name = value[i];
        }

        if (value[i].data[0] != '~') {
            ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
            continue;
        }

#if (NGX_PCRE)
        {
        u_char               *p;
        ngx_regex_compile_t   rc;
        u_char                errstr[NGX_MAX_CONF_ERRSTR];

        if (value[i].len == 1) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "empty regex in server name \"%V\"", &value[i]);
            return NGX_CONF_ERROR;
        }

        value[i].len--;
        value[i].data++;

        ngx_memzero(&rc, sizeof(ngx_regex_compile_t));

        rc.pattern = value[i];
        rc.err.len = NGX_MAX_CONF_ERRSTR;
        rc.err.data = errstr;

        for (p = value[i].data; p < value[i].data + value[i].len; p++) {
            if (*p >= 'A' && *p <= 'Z') {
                rc.options = NGX_REGEX_CASELESS;
                break;
            }
        }

        sn->regex = ngx_http_regex_compile(cf, &rc);
        if (sn->regex == NULL) {
            return NGX_CONF_ERROR;
        }

        sn->name = value[i];
        cscf->captures = (rc.captures > 0);
        }
#else
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "using regex \"%V\" "
                           "requires PCRE library", &value[i]);

        return NGX_CONF_ERROR;
#endif
    }

    return NGX_CONF_OK;
}

ngx_http_core_server_name 函数是 Nginx 中处理 HTTP 服务器配置指令 server_name 的核心实现


    value = cf->args->elts;

 获取配置指令的参数列表

    for (i = 1; i < cf->args->nelts; i++) {

从第1个参数开始(跳过指令名本身)

        ch = value[i].data[0];

取当前参数的第一个字符

        if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
            || (ch == '.' && value[i].len < 2))
        {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "server name \"%V\" is invalid", &value[i]);
            return NGX_CONF_ERROR;
        }

server_name* 开头时,需满足以下任一情况即判定为非法:

长度不足 value[i].len < 3

格式错误 value[i].data[1] != '.'
(如 *example.com,第二个字符是 e 而非 .

*. 表示匹配任意子域名(. 为字面量)

server_name. 开头且长度不足 2 时判定为非法

        if (ngx_strchr(value[i].data, '/')) {
            ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                               "server name \"%V\" has suspicious symbols",
                               &value[i]);
        }

 检查是否存在 / 符号

HTTP 协议中,Host 头字段的合法格式为 hostname[:port]不允许包含路径符号 /

        sn = ngx_array_push(&cscf->server_names);
        if (sn == NULL) {
            return NGX_CONF_ERROR;
        }

#if (NGX_PCRE)
        sn->regex = NULL;
#endif
        sn->server = cscf;

 将解析后的 server_name添加到当前服务器配置的 server_names 数组中 

cscf->server_names 数组末尾动态分配一个 ngx_http_server_name_t 结构体,并返回其指针 sn

若编译时启用了 PCRE 库(NGX_PCRE 宏定义存在),则将 sn->regex 初始化为 NULL,表示当前名称尚未关联正则表达式

sn->server 指向当前服务器配置块(ngx_http_core_srv_conf_t 类型)

当请求匹配到该服务器名称时,Nginx 可通过 sn->server 快速定位到对应的虚拟主机配置(如监听端口、根目录、location 块等)

        if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) {
            sn->name = cf->cycle->hostname;

        } else {
            sn->name = value[i];
        }

 server_name 中的 $hostname 替换为 Nginx 进程的主机名 ,实现动态服务器名称配置。
例如,若 Nginx 运行在主机 web-server01 上,则 server_name $hostname; 等效于 server_name web-server01;

        if (value[i].data[0] != '~') {
            ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
            continue;
        }

 将非正则表达式的 server_name 转换为全小写格式,确保请求的 Host 头匹配时不区分大小写

若服务器名称以 ~ 开头(表示正则表达式),则跳过小写转换,进入正则编译流程

此时 条件成立,进入下一次循环,但当前 server_name 的参数只有一个,所以循环结束

return NGX_CONF_OK;

返回 NGX_CONF_OK

相关文章:

  • 文献分享: ColXTR——将ColBERTv2的优化引入ColXTR
  • [动手学习深度学习]28. 批量归一化
  • AF3 Rotation类的map_tensor_fn 方法解读
  • Oracle 23ai Vector Search 系列之1 架构基础
  • RT-Thread CI编译产物artifacts自动上传功能介绍
  • python socket模块学习记录
  • KPMG 与 SAP Joule:引领 AI 驱动咨询的新时代
  • 什么情况下spring的事务会失效
  • 私域电商的进化逻辑与技术赋能:基于开源AI大模型与S2B2C商城的创新融合研究
  • C#设计模式快速回顾
  • C语言- 工厂模式详解与实践
  • 常见中间件漏洞攻略-Apache篇
  • datetime“陷阱”与救赎:扒“时间差值”证道
  • Pytorch实现之对称卷积神经网络结构实现超分辨率
  • Pytorch深度学习教程_9_nn模块构建神经网络
  • 数据结构——哈夫曼编码、哈夫曼树
  • SAP-ABAP:SAP BW模块架构与实战应用详解
  • 使用Python将视频转化为gif
  • AF3 Rotation 类解读
  • stc8g1k08a+cd4017红绿灯
  • 沪喀同心|为新疆青少年提供科普大餐,“小小博物家(喀什版)”启动
  • 陕西河南山西等地将现“干热风”灾害,小麦产区如何防范?
  • 中国巴西关于乌克兰危机的联合声明
  • 三亚通报救护车省外拉警报器开道旅游:违规违法,责令公司停业整顿
  • 白玉兰奖征片综述丨综艺市场破局焕新,多元赛道重塑价值坐标
  • 超新星|罚丢点球的那道坎,刘诚宇靠自己迈了过去