Browse Source

[core] lowercase r->http_host, r->uri.authority

always lowercase r->http_host, r->uri.authority for consistency
master
Glenn Strauss 6 months ago
parent
commit
8c5acaae3c
  1. 1
      src/mod_extforward.c
  2. 50
      src/request.c

1
src/mod_extforward.c

@ -958,6 +958,7 @@ static handler_t mod_extforward_Forwarded (request_st * const r, plugin_data * c
else {
buffer_copy_string_len(r->http_host, s+v, vlen-v);
}
buffer_to_lower(r->http_host);
if (0 != http_request_host_policy(r->http_host,
r->conf.http_parseopts,

50
src/request.c

@ -227,6 +227,9 @@ int http_request_host_normalize(buffer * const b, const int scheme_port) {
}
int http_request_host_policy (buffer * const b, const unsigned int http_parseopts, const int scheme_port) {
/* caller should lowercase, as is done in http_request_header_set_Host(),
* for consistency in case the value is used prior to calling policy func */
/*buffer_to_lower(b);*/
return (((http_parseopts & HTTP_PARSEOPT_HOST_STRICT)
&& 0 != request_check_hostname(b))
|| ((http_parseopts & HTTP_PARSEOPT_HOST_NORMALIZE)
@ -262,6 +265,16 @@ static int http_request_header_char_invalid(request_st * const restrict r, const
}
__attribute_noinline__
static void http_request_header_set_Host(request_st * const restrict r, const char * const h, size_t hlen)
{
r->http_host = http_header_request_set_ptr(r, HTTP_HEADER_HOST,
CONST_STR_LEN("Host"));
buffer_copy_string_len(r->http_host, h, hlen);
buffer_to_lower(r->http_host);
}
int64_t
li_restricted_strtoint64 (const char *v, const uint32_t vlen, const char ** const err)
{
@ -291,8 +304,6 @@ li_restricted_strtoint64 (const char *v, const uint32_t vlen, const char ** cons
* returns 0 on success, HTTP status on error
*/
static int http_request_parse_single_header(request_st * const restrict r, const enum http_header_e id, const char * const restrict k, const size_t klen, const char * const restrict v, const size_t vlen) {
buffer **saveb = NULL;
/*
* Note: k might not be '\0'-terminated
* Note: v is not '\0'-terminated
@ -309,14 +320,18 @@ static int http_request_parse_single_header(request_st * const restrict r, const
break;
case HTTP_HEADER_HOST:
if (!light_btst(r->rqst_htags, HTTP_HEADER_HOST)) {
saveb = &r->http_host;
if (vlen >= 1024) { /*(expecting < 256)*/
return http_request_header_line_invalid(r, 400, "uri-authority too long -> 400");
}
/*(http_request_header_append() plus sets r->http_host)*/
http_request_header_set_Host(r, v, vlen);
return 0;
}
else if (NULL != r->http_host
&& buffer_is_equal_string(r->http_host, v, vlen)) {
&& (__builtin_expect( buffer_eq_slen(r->http_host, v, vlen), 1)
|| buffer_eq_icase_slen(r->http_host, v, vlen))) {
/* ignore all Host: headers if match authority in request line */
/* (expect Host to match case in :authority of HTTP/2 request) */
return 0; /* ignore header */
}
else {
@ -407,11 +422,6 @@ static int http_request_parse_single_header(request_st * const restrict r, const
}
http_header_request_append(r, id, k, klen, v, vlen);
if (saveb) {
*saveb = http_header_request_get(r, id, k, klen);
}
return 0;
}
@ -459,10 +469,8 @@ static const char * http_request_parse_reqline_uri(request_st * const restrict r
http_request_header_line_invalid(r, 400, "uri-authority empty or too long -> 400");
return NULL;
}
/* Insert as host header */
r->http_host = http_header_request_set_ptr(r, HTTP_HEADER_HOST,
CONST_STR_LEN("Host"));
buffer_copy_string_len(r->http_host, host, hostlen);
/* Insert as "Host" header */
http_request_header_set_Host(r, host, hostlen);
return nuri;
} else if (!(http_parseopts & HTTP_PARSEOPT_HEADER_STRICT) /*(!http_header_strict)*/
|| (HTTP_METHOD_CONNECT == r->http_method && (uri[0] == ':' || light_isdigit(uri[0])))
@ -492,7 +500,7 @@ http_request_validate_pseudohdrs (request_st * const restrict r, const int schem
return http_request_header_line_invalid(r, 400,
"missing pseudo-header method -> 400");
if (HTTP_METHOD_CONNECT != r->http_method) {
if (__builtin_expect( (HTTP_METHOD_CONNECT != r->http_method), 1)) {
if (!scheme)
return http_request_header_line_invalid(r, 400,
"missing pseudo-header scheme -> 400");
@ -516,7 +524,9 @@ http_request_validate_pseudohdrs (request_st * const restrict r, const int schem
if (!buffer_is_blank(&r->target) || scheme)
return http_request_header_line_invalid(r, 400,
"invalid pseudo-header with CONNECT -> 400");
/*(reuse uri and ulen to assign to r->target)*/
/* note: this copy occurs prior to http_request_host_policy()
* so any consumer handling CONNECT should normalize r->target
* as appropriate */
buffer_copy_buffer(&r->target, r->http_host);
}
buffer_copy_buffer(&r->target_orig, &r->target);
@ -623,11 +633,8 @@ http_request_parse_header (request_st * const restrict r, http_header_parse_ctx
if (vlen >= 1024) /*(expecting < 256)*/
return http_request_header_line_invalid(r, 400,
"invalid pseudo-header authority too long -> 400");
/* insert as host header */
r->http_host =
http_header_request_set_ptr(r, HTTP_HEADER_HOST,
CONST_STR_LEN("Host"));
buffer_copy_string_len(r->http_host, v, vlen);
/* insert as "Host" header */
http_request_header_set_Host(r, v, vlen);
return 0;
case HTTP_HEADER_H2_METHOD_GET: /*(any method, not only "GET")*/
case HTTP_HEADER_H2_METHOD_POST:
@ -1132,11 +1139,10 @@ http_request_parse (request_st * const restrict r, const int scheme_port)
/* check hostname field if it is set */
/*(r->http_host might not be set until after parsing request headers)*/
if (__builtin_expect( (r->http_host != NULL), 1)) {
buffer_copy_buffer(&r->uri.authority, r->http_host);
buffer_to_lower(&r->uri.authority);
if (0 != http_request_host_policy(r->http_host,
http_parseopts, scheme_port))
return http_request_header_line_invalid(r, 400, "Invalid Hostname -> 400");
buffer_copy_buffer(&r->uri.authority, r->http_host);
}
else {
buffer_copy_string_len(&r->uri.authority, CONST_STR_LEN(""));

Loading…
Cancel
Save