mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MINOR: h2: add h2_make_htx_trailers to turn H2 headers to HTX trailers
This function is usable to transform a list of H2 header fields to a HTX trailers block. It takes care of rejecting forbidden headers and pseudo-headers when performing the conversion. It also emits the trailing CRLF that is currently needed in the HTX trailers block.
This commit is contained in:
parent
52610e905d
commit
1e1f27c5c1
@ -182,6 +182,7 @@ int h2_make_h1_trailers(struct http_hdr *list, char *out, int osize);
|
||||
int h2_parse_cont_len_header(unsigned int *msgf, struct ist *value, unsigned long long *body_len);
|
||||
int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *msgf);
|
||||
int h2_make_htx_response(struct http_hdr *list, struct htx *htx, unsigned int *msgf);
|
||||
int h2_make_htx_trailers(struct http_hdr *list, struct htx *htx);
|
||||
|
||||
/*
|
||||
* Some helpful debugging functions.
|
||||
|
81
src/h2.c
81
src/h2.c
@ -894,3 +894,84 @@ int h2_make_htx_response(struct http_hdr *list, struct htx *htx, unsigned int *m
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Takes an H2 headers list <list> terminated by a name being <NULL,0> and
|
||||
* emits the equivalent HTX trailers block not including the empty line. The
|
||||
* output contents are emitted in <htx>, and a positive value is returned if
|
||||
* some bytes were emitted. In case of error, a negative error code is
|
||||
* returned. The caller must have verified that the message in the buffer is
|
||||
* compatible with receipt of trailers. Note that for now the HTX trailers
|
||||
* block is in fact an H1 block and it must contain the trailing CRLF.
|
||||
*
|
||||
* The headers list <list> must be composed of :
|
||||
* - n.name != NULL, n.len > 0 : literal header name
|
||||
* - n.name == NULL, n.len > 0 : indexed pseudo header name number <n.len>
|
||||
* among H2_PHDR_IDX_* (illegal here)
|
||||
* - n.name ignored, n.len == 0 : end of list
|
||||
* - in all cases except the end of list, v.name and v.len must designate a
|
||||
* valid value.
|
||||
*/
|
||||
int h2_make_htx_trailers(struct http_hdr *list, struct htx *htx)
|
||||
{
|
||||
struct htx_blk *blk;
|
||||
char *out;
|
||||
uint32_t idx;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
len = 2; // CRLF
|
||||
for (idx = 0; list[idx].n.len != 0; idx++) {
|
||||
if (!list[idx].n.ptr) {
|
||||
/* This is an indexed pseudo-header (RFC7540#8.1.2.1) */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* RFC7540#8.1.2: upper case not allowed in header field names */
|
||||
for (i = 0; i < list[idx].n.len; i++)
|
||||
if ((uint8_t)(list[idx].n.ptr[i] - 'A') < 'Z' - 'A')
|
||||
goto fail;
|
||||
|
||||
if (h2_str_to_phdr(list[idx].n) != 0) {
|
||||
/* This is a pseudo-header (RFC7540#8.1.2.1) */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* these ones are forbidden in trailers (RFC7540#8.1.2.2) */
|
||||
if (isteq(list[idx].n, ist("host")) ||
|
||||
isteq(list[idx].n, ist("content-length")) ||
|
||||
isteq(list[idx].n, ist("connection")) ||
|
||||
isteq(list[idx].n, ist("proxy-connection")) ||
|
||||
isteq(list[idx].n, ist("keep-alive")) ||
|
||||
isteq(list[idx].n, ist("upgrade")) ||
|
||||
isteq(list[idx].n, ist("te")) ||
|
||||
isteq(list[idx].n, ist("transfer-encoding")))
|
||||
goto fail;
|
||||
|
||||
len += list[idx].n.len + 2 + list[idx].v.len + 2;
|
||||
}
|
||||
|
||||
blk = htx_add_blk_type_size(htx, HTX_BLK_TLR, len);
|
||||
if (!blk)
|
||||
goto fail;
|
||||
|
||||
out = htx_get_blk_ptr(htx, blk);
|
||||
for (idx = 0; list[idx].n.len != 0; idx++) {
|
||||
/* copy "name: value" */
|
||||
memcpy(out, list[idx].n.ptr, list[idx].n.len);
|
||||
out += list[idx].n.len;
|
||||
*(out++) = ':';
|
||||
*(out++) = ' ';
|
||||
|
||||
memcpy(out, list[idx].v.ptr, list[idx].v.len);
|
||||
out += list[idx].v.len;
|
||||
*(out++) = '\r';
|
||||
*(out++) = '\n';
|
||||
}
|
||||
*(out++) = '\r';
|
||||
*(out++) = '\n';
|
||||
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user