if (!httpd__meta_build_path(con, req, conf, token, NULL, &lim, &ref))
if (!httpd__meta_build_path(con, req, conf, token, NULL, &canon, &lim, &ref))
static int httpd__conf_req_d1(struct Con *con, struct Httpd_req_data *req,                              time_t file_timestamp,                              Conf_parse *conf, Conf_token *token, int clist){  if (0) { }  else if (OPT_SERV_SYM_EQ("match-init"))    OPT_SERV_SC_MATCH_INIT(req->policy->s->beg,                           httpd__conf_req_d1(con, req, file_timestamp,                                              conf, token, clist));    else if (OPT_SERV_SYM_EQ("return"))  {    unsigned int code = 0;        if (conf_sc_token_parse_uint(conf, token, &code))    {      if (0) { }      else if (OPT_SERV_SYM_EQ("<perm>") ||               OPT_SERV_SYM_EQ("<perm-redirect>") ||               OPT_SERV_SYM_EQ("<permenant>") ||               OPT_SERV_SYM_EQ("<permenant-redirect>"))        code = 301;      else if (OPT_SERV_SYM_EQ("<found>"))        code = 302;      else if (OPT_SERV_SYM_EQ("<other>") || OPT_SERV_SYM_EQ("<see-other>"))        code = 303;      else if (OPT_SERV_SYM_EQ("<tmp>") || OPT_SERV_SYM_EQ("<tmp-redirect>") ||               OPT_SERV_SYM_EQ("<temp>") ||               OPT_SERV_SYM_EQ("<temp-redirect>") ||               OPT_SERV_SYM_EQ("<temporary>") ||               OPT_SERV_SYM_EQ("<temporary-redirect>"))        code = 307;      else if (OPT_SERV_SYM_EQ("<bad>") || OPT_SERV_SYM_EQ("<bad-request>"))        code = 400;      else if (OPT_SERV_SYM_EQ("<not-auth>") ||               OPT_SERV_SYM_EQ("<not-authenticated>"))        code = 403;      else if (OPT_SERV_SYM_EQ("<not-found>"))        code = 404;      else if (OPT_SERV_SYM_EQ("<gone>"))        code = 410;      else if (OPT_SERV_SYM_EQ("<error>") ||               OPT_SERV_SYM_EQ("<internal-server-error>"))        code = 500;      else if (OPT_SERV_SYM_EQ("<service-unavailable>"))        code = 503;      else        return (FALSE);    }        req->user_return_error_code = TRUE;    ASSERT(!req->error_code);    req->error_code = 0;    switch (code)    {      case 301: if (!req->error_code && req->direct_uri) HTTPD_ERR_301(req);      case 302: if (!req->error_code && req->direct_uri) HTTPD_ERR_302(req);      case 303: if (!req->error_code && req->direct_uri) HTTPD_ERR_303(req);      case 307: if (!req->error_code && req->direct_uri) HTTPD_ERR_307(req);      default:        if (req->error_code)          httpd_req_absolute_uri(con, req, req->fname, 1, req->fname->len);        else          req->user_return_error_code = FALSE;        return (FALSE);              case 400: HTTPD_ERR_RET(req, 400, FALSE);      case 403: HTTPD_ERR_RET(req, 403, FALSE);      case 404: HTTPD_ERR_RET(req, 404, FALSE);      case 410: HTTPD_ERR_RET(req, 410, FALSE);      case 500: HTTPD_ERR_RET(req, 500, FALSE);      case 503: HTTPD_ERR_RET(req, 503, FALSE);    }  }  else if (OPT_SERV_SYM_EQ("Location:"))  {    unsigned int lim = HTTPD_POLICY_PATH_LIM_NONE;    Vstr_ref *ref = NULL;    size_t orig_len = 0;    int bp_type = HTTPD_CONF_REQ__TYPE_BUILD_PATH_SKIP;        if (req->direct_filename)      return (FALSE);        CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);    if (!httpd__meta_build_path(con, req, conf, token, NULL, &lim, &ref))    {      vstr_ref_del(ref);      return (FALSE);    }    if (!req->direct_uri)    {      if (lim == HTTPD_POLICY_PATH_LIM_NONE)        orig_len = req->fname->len; /* don't do more than we need */      else if (!vstr_sub_vstr(req->fname, 1, req->fname->len,                              con->evnt->io_r, req->path_pos, req->path_len, 0))      {        vstr_ref_del(ref);        return (FALSE);      }    }    if (!httpd__build_path(con, req, conf, token,                           req->fname, 1, req->fname->len,                           lim, FALSE, ref, TRUE, &bp_type))      return (FALSE);    if (!req->direct_uri && (lim == HTTPD_POLICY_PATH_LIM_NONE) &&        (bp_type != HTTPD_CONF_REQ__TYPE_BUILD_PATH_ASSIGN))    { /* we needed to do the above sub */      if (!vstr_sub_vstr(req->fname, 1, orig_len,                         con->evnt->io_r, req->path_pos, req->path_len, 0))        return (FALSE);    }        req->direct_uri = TRUE;    HTTPD_CONF_REQ__X_HDR_CHK(req->fname, 1, req->fname->len);  }  else if (OPT_SERV_SYM_EQ("Cache-Control:"))  {     unsigned int num = 1;    unsigned int tmp = 0;    unsigned int num_flags = VSTR_FLAG02(PARSE_NUM, OVERFLOW, SEP);    size_t num_len = 0;        HTTPD_CONF_REQ__X_CONTENT_VSTR(cache_control);    tmp = vstr_parse_uint(HTTP__CONTENT_PARAMS(req, cache_control),                          num_flags, &num_len, NULL);    if (req->cache_control_len != num_len) /* reset, as though we didn't try */      num_len = 0;    else    {      num = tmp;      HTTPD_CONF_REQ__X_CONTENT_VSTR(cache_control);    }        if (!num_len && vstr_cmp_cstr_eq(HTTP__CONTENT_PARAMS(req, cache_control),                                     "<expires-now>"))      httpd__conf_req_reset_cache_control(req, 0);    else if (HTTPD__EXPIRES_CMP(cache_control, "expire-minute"))      httpd__conf_req_reset_cache_control(req, (num * 60 *  1));    else if (HTTPD__EXPIRES_CMP(cache_control, "expire-hour"))      httpd__conf_req_reset_cache_control(req, (num * 60 * 60));    else if (HTTPD__EXPIRES_CMP(cache_control, "expire-day"))      httpd__conf_req_reset_cache_control(req, (num * 60 * 60 * 24));    else if (HTTPD__EXPIRES_CMP(cache_control, "expire-week"))      httpd__conf_req_reset_cache_control(req, (num * 60 * 60 * 24 * 7));    else if (!num_len &&             vstr_cmp_cstr_eq(HTTP__CONTENT_PARAMS(req, cache_control),                              "<expires-never>"))      httpd__conf_req_reset_cache_control(req, (60 * 60 * 24 * 365));    else if (num_len)      return (FALSE);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(cache_control);  }  else if (OPT_SERV_SYM_EQ("Content-Disposition:"))  {    HTTPD_CONF_REQ__X_CONTENT_VSTR(content_disposition);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_disposition);  }  else if (OPT_SERV_SYM_EQ("Content-Language:"))  {    HTTPD_CONF_REQ__X_CONTENT_VSTR(content_language);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_language);  }  else if (OPT_SERV_SYM_EQ("Content-Location:"))  {    unsigned int lim = HTTPD_POLICY_PATH_LIM_NONE;    size_t pos = 0;    size_t len = 0;    Vstr_ref *ref = NULL;    if (req->direct_uri || req->direct_filename)      return (FALSE);    if (!req->xtra_content && !(req->xtra_content = vstr_make_base(NULL)))      return (FALSE);      if (req->content_location_vs1)    {      if (!httpd__content_location_valid(req, &pos, &len))        return (FALSE);    }    else    {      pos = req->xtra_content->len + 1;      if (!HTTPD_APP_REF_VSTR(req->xtra_content,                              con->evnt->io_r, req->path_pos, req->path_len))        return (FALSE);      ASSERT(pos <= req->xtra_content->len);      len = vstr_sc_posdiff(pos, req->xtra_content->len);    }        CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);    if (!httpd__meta_build_path(con, req, conf, token, NULL, &lim, &ref))    {      vstr_ref_del(ref);      return (FALSE);    }    if (!httpd__build_path(con, req, conf, token, req->xtra_content, pos, len,                           lim, FALSE, ref, TRUE, NULL))      return (FALSE);        len = vstr_sc_posdiff(pos, req->xtra_content->len);        req->content_location_vs1 = req->xtra_content;    req->content_location_pos = pos;    req->content_location_len = len;    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_location);  }  else if (OPT_SERV_SYM_EQ("Content-MD5:") ||           OPT_SERV_SYM_EQ("identity/Content-MD5:"))  {    req->content_md5_time = file_timestamp;    HTTPD_CONF_REQ__X_CONTENT_VSTR(content_md5);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_md5);  }  else if (OPT_SERV_SYM_EQ("gzip/Content-MD5:"))  {     req->content_md5_time = file_timestamp;    HTTPD_CONF_REQ__X_CONTENT_VSTR(gzip_content_md5);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(gzip_content_md5);  }  else if (OPT_SERV_SYM_EQ("bzip2/Content-MD5:"))  {     req->content_md5_time = file_timestamp;    HTTPD_CONF_REQ__X_CONTENT_VSTR(bzip2_content_md5);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(bzip2_content_md5);  }  else if (OPT_SERV_SYM_EQ("Content-Type:"))  {    HTTPD_CONF_REQ__X_CONTENT_VSTR(content_type);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_type);  }  else if (OPT_SERV_SYM_EQ("ETag:") ||           OPT_SERV_SYM_EQ("identity/ETag:"))  {    req->etag_time = file_timestamp;    HTTPD_CONF_REQ__X_CONTENT_VSTR(etag);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(etag);  }  else if (OPT_SERV_SYM_EQ("gzip/ETag:"))  {    req->etag_time = file_timestamp;    HTTPD_CONF_REQ__X_CONTENT_VSTR(gzip_etag);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(gzip_etag);  }  else if (OPT_SERV_SYM_EQ("bzip2/ETag:"))  {    req->etag_time = file_timestamp;    HTTPD_CONF_REQ__X_CONTENT_VSTR(bzip2_etag);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(bzip2_etag);  }  else if (OPT_SERV_SYM_EQ("Expires:"))  { /* note that rfc2616 says only go upto a year into the future */    unsigned int num = 1;    unsigned int tmp = 0;    unsigned int num_flags = VSTR_FLAG02(PARSE_NUM, OVERFLOW, SEP);    size_t num_len = 0;        HTTPD_CONF_REQ__X_CONTENT_VSTR(expires);    tmp = vstr_parse_uint(HTTP__CONTENT_PARAMS(req, expires),                          num_flags, &num_len, NULL);    if (req->expires_len != num_len) /* reset, as though we didn't try */      num_len = 0;    else    {      num = tmp;      HTTPD_CONF_REQ__X_CONTENT_VSTR(expires);    }        HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(expires);    /* if we dynamically generate use current timestamp, else filetimestamp */    req->expires_time = req->now;    if (!num_len &&        vstr_cmp_cstr_eq(HTTP__CONTENT_PARAMS(req, expires), "<now>"))      httpd__conf_req_reset_expires(req, 0);    else if (HTTPD__EXPIRES_CMP(expires, "minute"))      httpd__conf_req_reset_expires(req, (num * 60 *  1));    else if (HTTPD__EXPIRES_CMP(expires, "hour"))      httpd__conf_req_reset_expires(req, (num * 60 * 60));    else if (HTTPD__EXPIRES_CMP(expires, "day"))      httpd__conf_req_reset_expires(req, (num * 60 * 60 * 24));    else if (HTTPD__EXPIRES_CMP(expires, "week"))      httpd__conf_req_reset_expires(req, (num * 60 * 60 * 24 * 7));    else if (!num_len &&             vstr_cmp_cstr_eq(HTTP__CONTENT_PARAMS(req, expires), "<never>"))      httpd__conf_req_reset_expires(req, (60 * 60 * 24 * 365));    else if (num_len) /* must be one of the above symbols */      return (FALSE);    else      req->expires_time = file_timestamp;  }  else if (OPT_SERV_SYM_EQ("Link:")) /* rfc2068 -- old, but still honored */  {    HTTPD_CONF_REQ__X_CONTENT_VSTR(link);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(link);  }  else if (OPT_SERV_SYM_EQ("P3P:")) /* http://www.w3.org/TR/P3P/ */  {    HTTPD_CONF_REQ__X_CONTENT_VSTR(p3p);    HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(p3p);  }  else if (OPT_SERV_SYM_EQ("filename"))  {    int full = req->skip_document_root;    unsigned int lim = HTTPD_POLICY_PATH_LIM_NAME_FULL;    Vstr_ref *ref = NULL;        if (req->direct_uri)      return (FALSE);    CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);    if (!httpd__meta_build_path(con, req, conf, token, &full, &lim, &ref))    {      vstr_ref_del(ref);      return (FALSE);    }    if (!httpd__build_path(con, req, conf, token,                           req->fname, 1, req->fname->len,                           lim, full, ref, FALSE, NULL))      return (FALSE);    if (!req->skip_document_root &&        !(req->conf_flags & HTTPD_CONF_REQ_FLAGS_PARSE_FILE_DIRECT) &&        (!req->fname->len || !vstr_cmp_cstr_eq(req->fname, 1, 1, "/")))      vstr_add_cstr_ptr(req->fname, 0, "/");    req->direct_filename = TRUE;  }  else if (OPT_SERV_SYM_EQ("parse-accept"))    OPT_SERV_X_TOGGLE(req->parse_accept);  else if (OPT_SERV_SYM_EQ("parse-accept-language"))    OPT_SERV_X_TOGGLE(req->parse_accept_language);  else if (OPT_SERV_SYM_EQ("allow-accept-encoding"))    OPT_SERV_X_TOGGLE(req->allow_accept_encoding);  else if (OPT_SERV_SYM_EQ("Vary:_*"))    OPT_SERV_X_TOGGLE(req->vary_star);  else if (OPT_SERV_SYM_EQ("Vary:_Accept"))    OPT_SERV_X_TOGGLE(req->vary_a);  else if (OPT_SERV_SYM_EQ("Vary:_Accept-Charset"))    OPT_SERV_X_TOGGLE(req->vary_ac);  else if (OPT_SERV_SYM_EQ("Vary:_Accept-Language"))    OPT_SERV_X_TOGGLE(req->vary_al);  else if (OPT_SERV_SYM_EQ("Vary:_Referer") ||           OPT_SERV_SYM_EQ("Vary:_Referrer"))    OPT_SERV_X_TOGGLE(req->vary_rf);  else if (OPT_SERV_SYM_EQ("Vary:_User-Agent"))    OPT_SERV_X_TOGGLE(req->vary_ua);  else if (OPT_SERV_SYM_EQ("content-lang-ext") ||           OPT_SERV_SYM_EQ("content-language-ext") ||           OPT_SERV_SYM_EQ("content-language-extension"))    HTTPD_CONF_REQ__X_CONTENT_VSTR(ext_vary_al);  else if (OPT_SERV_SYM_EQ("content-type-ext") ||           OPT_SERV_SYM_EQ("content-type-extension"))    HTTPD_CONF_REQ__X_CONTENT_VSTR(ext_vary_a);  else if (OPT_SERV_SYM_EQ("content-type-neg") ||           OPT_SERV_SYM_EQ("content-type-negotiate") ||           OPT_SERV_SYM_EQ("negotiate-content-type"))  {    if (req->neg_content_type_done)      return (FALSE);    HTTPD__NEG_BEG(req->policy->max_neg_A_nodes);    qual = http_parse_accept(req, conf->data, val->pos, val->len);    HTTPD__NEG_END();        req->neg_content_type_done = TRUE;    req->vary_a = TRUE;    if (qual_num)    {      unsigned int last = token->num;      req->parse_accept = FALSE;      *token = save;      conf_parse_num_token(conf, token, qual_num);      HTTPD_CONF_REQ__X_CONTENT_VSTR(content_type);      HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_type);      HTTPD_CONF_REQ__X_CONTENT_VSTR(ext_vary_a);      conf_parse_num_token(conf, token, last);    }  }  else if (OPT_SERV_SYM_EQ("negotiate-charset"))    return (FALSE);  else if (OPT_SERV_SYM_EQ("content-lang-neg") ||           OPT_SERV_SYM_EQ("content-lang-negotiate") ||           OPT_SERV_SYM_EQ("content-language-negotiate") ||           OPT_SERV_SYM_EQ("negotiate-content-language"))  {    if (req->neg_content_lang_done)      return (FALSE);    HTTPD__NEG_BEG(req->policy->max_neg_AL_nodes);    qual = http_parse_accept_language(req, conf->data, val->pos, val->len);    HTTPD__NEG_END();    req->neg_content_lang_done = TRUE;    req->vary_al = TRUE;    if (qual_num)    {      unsigned int last = token->num;      req->parse_accept_language = FALSE;      *token = save;      conf_parse_num_token(conf, token, qual_num);      HTTPD_CONF_REQ__X_CONTENT_VSTR(content_language);      HTTPD_CONF_REQ__X_CONTENT_HDR_CHK(content_language);      HTTPD_CONF_REQ__X_CONTENT_VSTR(ext_vary_al);      conf_parse_num_token(conf, token, last);    }  }  else    return (FALSE);    return (TRUE);}