当前位置 主页 > 服务器问题 > nginx问题汇总 >

    全面了解Nginx中的HTTP协议相关模块配置(2)

    栏目:nginx问题汇总 时间:2018-09-28 16:35

    这个函数中,为所有的 http 模块都分配并创建了配置结构,同时,调用了每个模块相应的初始化回调。

    最后,调用 ngx_http_optimize_servers 创建了 http 连接,加入 cycle 的监听数组,并设为监听状态。

    nginx 配置文件对 http 模块的配置分为三层:main、sever、location,因此,http 模块上下文 ngx_http_module_t 中定义了以下六个回调函数,用来创建和保存配置信息:

    create_main_conf init_main_conf create_srv_conf merge_srv_conf create_loc_conf merge_loc_conf

    在 ngx_http_block 中,循环调用了所有 NGX_HTTP_MODULE 的这六个回调函数,创建相关的配置结构。

    server、location 配置解析 -- ngx_http_core_server、ngx_http_core_location
    在调用所有 HTTP 模块的 create_main_conf、create_srv_conf、create_loc_conf 后,所有需要配置结构的模块都完成了配置结构的创建,于是在调用所有模块的 preconfiguration 回调函数后,配置解析工作正式展开

    通过调用 ngx_conf_parse 函数,开始了 http 配置块的解析,并通过解析到的命令调用相应的函数

    在首个 NGX_HTTP_MODULE ngx_http_core_module 的 ngx_command_t 域中包含了大量的配置指令,它们都是在http{}块中出现的,其中包括两个重要的指令:

    { ngx_string("listen"), NGX_HTTP_SRV_CONF|NGX_CONF_1MORE, ngx_http_core_listen, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL },{ ngx_string("server"), NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_http_core_server, 0, 0, NULL },{ ngx_string("location"), NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_http_core_location, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL },

    这里配置了 listen、server 与 location 块的解析函数 ngx_http_core_listen、ngx_http_core_server 和 ngx_http_core_location.


    server 块解析 -- ngx_http_core_server

    // static char *// ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)// http server 块解析 {{{static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy){  char            *rv;  void            *mconf;  ngx_uint_t          i;  ngx_conf_t          pcf;  ngx_http_module_t      *module;  struct sockaddr_in     *sin;  ngx_http_conf_ctx_t     *ctx, *http_ctx;  ngx_http_listen_opt_t    lsopt;  ngx_http_core_srv_conf_t  *cscf, **cscfp;  ngx_http_core_main_conf_t  *cmcf;  ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));  if (ctx == NULL) {    return NGX_CONF_ERROR;  }  http_ctx = cf->ctx;  ctx->main_conf = http_ctx->main_conf;  /* the server{}'s srv_conf */ // 为所有 HTTP 模块分配空间存储 srv_conf  ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);  if (ctx->srv_conf == NULL) {    return NGX_CONF_ERROR;  }  /* the server{}'s loc_conf */ // 为所有 HTTP 模块分配空间存储 loc_conf  ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);  if (ctx->loc_conf == NULL) {    return NGX_CONF_ERROR;  } // 循环调用每个模块的 create_srv_conf 与 create_loc_conf 回调,创建配置结构  for (i = 0; ngx_modules[i]; i++) {    if (ngx_modules[i]->type != NGX_HTTP_MODULE) {      continue;    }    module = ngx_modules[i]->ctx;    if (module->create_srv_conf) {      mconf = module->create_srv_conf(cf);      if (mconf == NULL) {        return NGX_CONF_ERROR;      }      ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;    }    if (module->create_loc_conf) {      mconf = module->create_loc_conf(cf);      if (mconf == NULL) {        return NGX_CONF_ERROR;      }      ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;    }  }  /* the server configuration context */  cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];  cscf->ctx = ctx;  cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];  cscfp = ngx_array_push(&cmcf->servers);  if (cscfp == NULL) {    return NGX_CONF_ERROR;  }  *cscfp = cscf;  /* parse inside server{} */  pcf = *cf;  cf->ctx = ctx;  cf->cmd_type = NGX_HTTP_SRV_CONF; // 解析 server 块配置  rv = ngx_conf_parse(cf, NULL);  *cf = pcf; // 如果没有监听任何端口,则监听默认的 80 或 8000端口  if (rv == NGX_CONF_OK && !cscf->listen) {    ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));    sin = &lsopt.u.sockaddr_in;    sin->sin_family = AF_INET;#if (NGX_WIN32)    sin->sin_port = htons(80);#else    sin->sin_port = htons((getuid() == 0) ? 80 : 8000);#endif    sin->sin_addr.s_addr = INADDR_ANY;    lsopt.socklen = sizeof(struct sockaddr_in);    lsopt.backlog = NGX_LISTEN_BACKLOG;    lsopt.rcvbuf = -1;    lsopt.sndbuf = -1;#if (NGX_HAVE_SETFIB)    lsopt.setfib = -1;#endif#if (NGX_HAVE_TCP_FASTOPEN)    lsopt.fastopen = -1;#endif    lsopt.wildcard = 1;    (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr,               NGX_SOCKADDR_STRLEN, 1);    if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {      return NGX_CONF_ERROR;    }  }  return rv;} // }}}