Nginx服务器中location配置的一些基本要点解析

2019-10-17 20:01:03王旭

static ngx_int_t 
ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf, 
  ngx_http_core_loc_conf_t *pclcf) 
{ 
 ... 
  locations = pclcf->locations; 
 
 ... 
  /* 按照类型排序location,排序完后的队列: (exact_match 或 inclusive) (排序好的,如果某个exact_match名字和inclusive location相同,exact_match排在前面) 
    | regex(未排序)| named(排序好的) | noname(未排序)*/ 
  ngx_queue_sort(locations, ngx_http_cmp_locations); 
 
  named = NULL; 
  n = 0; 
#if (NGX_PCRE) 
  regex = NULL; 
  r = 0; 
#endif 
 
  for (q = ngx_queue_head(locations); 
     q != ngx_queue_sentinel(locations); 
     q = ngx_queue_next(q)) 
  { 
    lq = (ngx_http_location_queue_t *) q; 
 
    clcf = lq->exact ? lq->exact : lq->inclusive; 
    /* 由于可能存在nested location,也就是location里面嵌套的location,这里需要递归的处理一下当前location下面的nested location */ 
    if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) { 
      return NGX_ERROR; 
    } 
 
#if (NGX_PCRE) 
 
    if (clcf->regex) { 
      r++; 
 
      if (regex == NULL) { 
        regex = q; 
      } 
 
      continue; 
    } 
 
#endif 
 
    if (clcf->named) { 
      n++; 
 
      if (named == NULL) { 
        named = q; 
      } 
 
      continue; 
    } 
 
    if (clcf->noname) { 
      break; 
    } 
  } 
 
  if (q != ngx_queue_sentinel(locations)) { 
    ngx_queue_split(locations, q, &tail); 
  } 
  /* 如果有named location,将它们保存在所属server的named_locations数组中 */ 
  if (named) { 
    clcfp = ngx_palloc(cf->pool, 
              (n + 1) * sizeof(ngx_http_core_loc_conf_t **)); 
    if (clcfp == NULL) { 
      return NGX_ERROR; 
    } 
 
    cscf->named_locations = clcfp; 
 
    for (q = named; 
       q != ngx_queue_sentinel(locations); 
       q = ngx_queue_next(q)) 
    { 
      lq = (ngx_http_location_queue_t *) q; 
 
      *(clcfp++) = lq->exact; 
    } 
 
    *clcfp = NULL; 
 
    ngx_queue_split(locations, named, &tail); 
  } 
 
#if (NGX_PCRE) 
  /* 如果有正则匹配location,将它们保存在所属server的http core模块的loc配置的regex_locations 数组中, 
    这里和named location保存位置不同的原因是由于named location只能存在server里面,而regex location可以作为nested location */ 
  if (regex) { 
 
    clcfp = ngx_palloc(cf->pool, 
              (r + 1) * sizeof(ngx_http_core_loc_conf_t **)); 
    if (clcfp == NULL) { 
      return NGX_ERROR; 
    } 
 
    pclcf->regex_locations = clcfp; 
 
    for (q = regex; 
       q != ngx_queue_sentinel(locations); 
       q = ngx_queue_next(q)) 
    { 
      lq = (ngx_http_location_queue_t *) q; 
 
      *(clcfp++) = lq->exact; 
    } 
 
    *clcfp = NULL; 
 
    ngx_queue_split(locations, regex, &tail); 
  } 
 
#endif 
 
  return NGX_OK; 
} 

          
       上面的步骤将正则匹配的location保存好了,location tree的建立在ngx_http_init_static_location_trees中进行: