if (req->policy->use_x2_hdr_chk && got_content_length)
if (req->policy->use_hdrs_no_x2 && got_content_length)
static int http__parse_hdrs(struct Con *con, Httpd_req_data *req){  Vstr_base *data = con->evnt->io_r;  struct Http_hdrs *http_hdrs = req->http_hdrs;  unsigned int num = 3; /* skip "method URI version" */  int got_content_length = FALSE;  int got_content_lang = FALSE;  int got_content_type = FALSE;  int got_transfer_encoding = FALSE;    while (++num <= req->sects->num)  {    size_t pos = VSTR_SECTS_NUM(req->sects, num)->pos;    size_t len = VSTR_SECTS_NUM(req->sects, num)->len;    size_t hdr_val_pos = 0;    if (0) { /* nothing */ }    HDR__EQ_SET("User-Agent",                ua);    HDR__EQ_SET("Referer",                   referer);    HDR__EQ_SET("Expect",                    expect);    HDR__EQ_SET("Host",                      host);    HDR__EQ_SET("If-Modified-Since",         if_modified_since);    HDR__EQ_SET("If-Range",                  if_range);    HDR__EQ_SET("If-Unmodified-Since",       if_unmodified_since);    HDR__EQ_SET("Authorization",             authorization);    /* allow continuations over multiple headers... *sigh* */    HDR__EQ_MULTI_SET("Accept",              accept);    HDR__EQ_MULTI_SET("Accept-Charset",      accept_charset);    HDR__EQ_MULTI_SET("Accept-Encoding",     accept_encoding);    HDR__EQ_MULTI_SET("Accept-Language",     accept_language);    HDR__EQ_MULTI_SET("Connection",          connection);    HDR__EQ_MULTI_SET("If-Match",            if_match);    HDR__EQ_MULTI_SET("If-None-Match",       if_none_match);    HDR__EQ_MULTI_SET("Range",               range);    /* allow a 0 (zero) length content-length, some clients do send these */    else if (HDR__EQ("Content-Length"))    {      unsigned int num_flags = 10 | (VSTR_FLAG_PARSE_NUM_NO_BEG_PM |                                     VSTR_FLAG_PARSE_NUM_OVERFLOW);      unsigned int num_val = 0;      size_t num_len = 0;            if (req->policy->use_x2_hdr_chk && got_content_length)        HTTPD_ERR_MSG_RET(req, 400, "Double header Content-Length", FALSE);      got_content_length = TRUE;      http__hdr_fixup(data, &pos, &len, hdr_val_pos);      num_val = vstr_parse_uint(data, pos, len, num_flags, &num_len, NULL);      if (num_len != len)        HTTPD_ERR_MSG_RET(req, 400, "Content-Length is not a number", FALSE);      if (num_val)        HTTPD_ERR_MSG_RET(req, 413, "Content-Length is not zero", FALSE);    }    HDR__EQ_IGNORE("Content-Type",     content_type);    HDR__EQ_IGNORE("Content-Language", content_lang);        /* in theory ,,identity;foo=bar;baz="zoom",, is ok ... who cares */    else if (HDR__EQ("Transfer-Encoding"))    {      if (req->policy->use_x2_hdr_chk && got_transfer_encoding)        HTTPD_ERR_MSG_RET(req, 400, "Double header Transfer-Encoding", FALSE);      got_transfer_encoding = TRUE;      http__hdr_fixup(data, &pos, &len, hdr_val_pos);      if (!VEQ(data, pos, len, "identity")) /* 3.6 says 501 */        HTTPD_ERR_MSG_RET(req, 501, "Transfer-Encoding is not identity", FALSE);    }    else    { /* we can't x2 check ... as some might be multi headers */      size_t tmp = 0;      /* all headers _must_ contain a ':' */      tmp = vstr_srch_chr_fwd(data, pos, len, ':');      if (!tmp)        HTTPD_ERR_MSG_RET(req, 400, "No ':' after header", FALSE);      /* make sure unknown header is whitespace "valid" */      tmp = vstr_sc_posdiff(pos, tmp);      if (req->policy->use_non_spc_hdrs &&          (vstr_cspn_cstr_chrs_fwd(data, pos, tmp, HTTP_LWS) != tmp))        HTTPD_ERR_MSG_RET(req, 400, "Spaces before ':' after header", FALSE);    }  }  if (got_content_type && !got_content_length) /* FIXME: config. ? */    HTTPD_ERR_MSG_RET(req, 400, "Type but no Length", FALSE);  if (got_content_lang && !got_content_length)    HTTPD_ERR_MSG_RET(req, 400, "Language but no Length", FALSE);  return (TRUE);}