HTTP: fix segfault reading a request header with no cache slot
Reading a request header via r.headersIn[name] could crash the worker
with SIGSEGV. The header in question was "Proxy-Connection", but any
header that nginx registers without a dedicated ngx_table_elt_t * slot
was affected.
The getter mapped an arbitrary header name through ngx_hash_find() and
treated (char *) &r->headers_in + hh->offset as a pointer to a cache
slot. This only holds for headers whose parser stores into such a
slot. "Proxy-Connection" is registered in ngx_http_headers_in[] with
offset 0 and a handler that stores nothing, so the getter aliased the
ngx_list_t at the start of ngx_http_headers_in_t and followed its elts
pointer as a bogus ngx_table_elt_t.
The fix is to walk the parsed header list by name, as it is always safe.
The single-value and semicolon-join flags moved into the per-name header
table, and the now-unused slot pointer argument and its branch were
dropped from the generic getter.
The slot lookup that is removed was only an optimization for the names
in ngx_http_headers_in[]; for any other header it missed the hash and
walked the list anyway, so dropping it is not a performance regression.