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

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

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

    location 块解析 -- ngx_http_core_location

    // static char *// ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)// location 块配置解析 {{{static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy){  char           *rv;  u_char          *mod;  size_t           len;  ngx_str_t         *value, *name;  ngx_uint_t         i;  ngx_conf_t         save;  ngx_http_module_t     *module;  ngx_http_conf_ctx_t    *ctx, *pctx;  ngx_http_core_loc_conf_t *clcf, *pclcf;  ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));  if (ctx == NULL) {    return NGX_CONF_ERROR;  }  pctx = cf->ctx;  ctx->main_conf = pctx->main_conf;  ctx->srv_conf = pctx->srv_conf;  ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);  if (ctx->loc_conf == NULL) {    return NGX_CONF_ERROR;  }  for (i = 0; ngx_modules[i]; i++) {    if (ngx_modules[i]->type != NGX_HTTP_MODULE) {      continue;    }    module = ngx_modules[i]->ctx;    if (module->create_loc_conf) {      ctx->loc_conf[ngx_modules[i]->ctx_index] =                          module->create_loc_conf(cf);      if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {         return NGX_CONF_ERROR;      }    }  }  clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];  clcf->loc_conf = ctx->loc_conf;  value = cf->args->elts;  if (cf->args->nelts == 3) {    len = value[1].len;    mod = value[1].data;    name = &value[2];    if (len == 1 && mod[0] == '=') {      clcf->name = *name;      clcf->exact_match = 1;    } else if (len == 2 && mod[0] == '^' && mod[1] == '~') {      clcf->name = *name;      clcf->noregex = 1;    } else if (len == 1 && mod[0] == '~') {      if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {        return NGX_CONF_ERROR;      }    } else if (len == 2 && mod[0] == '~' && mod[1] == '*') {      if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {        return NGX_CONF_ERROR;      }    } else {      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                "invalid location modifier \"%V\"", &value[1]);      return NGX_CONF_ERROR;    }  } else {    name = &value[1];    if (name->data[0] == '=') {      clcf->name.len = name->len - 1;      clcf->name.data = name->data + 1;      clcf->exact_match = 1;    } else if (name->data[0] == '^' && name->data[1] == '~') {      clcf->name.len = name->len - 2;      clcf->name.data = name->data + 2;      clcf->noregex = 1;    } else if (name->data[0] == '~') {      name->len--;      name->data++;      if (name->data[0] == '*') {        name->len--;        name->data++;        if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {          return NGX_CONF_ERROR;        }      } else {        if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {          return NGX_CONF_ERROR;        }      }    } else {      clcf->name = *name;      if (name->data[0] == '@') {        clcf->named = 1;      }    }  }  pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];  if (pclcf->name.len) {    /* nested location */#if 0    clcf->prev_location = pclcf;#endif    if (pclcf->exact_match) {      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                "location \"%V\" cannot be inside "                "the exact location \"%V\"",                &clcf->name, &pclcf->name);      return NGX_CONF_ERROR;    }    if (pclcf->named) {      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                "location \"%V\" cannot be inside "                "the named location \"%V\"",                &clcf->name, &pclcf->name);      return NGX_CONF_ERROR;    }    if (clcf->named) {      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                "named location \"%V\" can be "                "on the server level only",                &clcf->name);      return NGX_CONF_ERROR;    }    len = pclcf->name.len;#if (NGX_PCRE)    if (clcf->regex == NULL      && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)#else    if (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)#endif    {      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                "location \"%V\" is outside location \"%V\"",                &clcf->name, &pclcf->name);      return NGX_CONF_ERROR;    }  } // 将 location 配置加入到 locations 配置链表中  if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {    return NGX_CONF_ERROR;  }  save = *cf;  cf->ctx = ctx;  cf->cmd_type = NGX_HTTP_LOC_CONF;  rv = ngx_conf_parse(cf, NULL);  *cf = save;  return rv;} // }}}