From: Christopher Faulet Date: Tue, 8 Oct 2019 14:38:42 +0000 (+0200) Subject: CLEANUP: h1-htx: Move htx-to-h1 formatting functions from htx.c to h1_htx.c X-Git-Tag: v2.1-dev3~76 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=53a899b946f1762194d8cbf1bb31e3736df72749;p=thirdparty%2Fhaproxy.git CLEANUP: h1-htx: Move htx-to-h1 formatting functions from htx.c to h1_htx.c The functions "htx_*_to_h1()" have been renamed into "h1_format_htx_*()" and moved in the file h1_htx.c. It is the right place for such functions. --- diff --git a/include/common/htx.h b/include/common/htx.h index da035b9a7c..5527a473fc 100644 --- a/include/common/htx.h +++ b/include/common/htx.h @@ -255,11 +255,6 @@ size_t htx_add_data(struct htx *htx, const struct ist data); struct htx_blk *htx_add_last_data(struct htx *htx, struct ist data); void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk **ref); -int htx_reqline_to_h1(const struct htx_sl *sl, struct buffer *chk); -int htx_stline_to_h1(const struct htx_sl *sl, struct buffer *chk); -int htx_hdr_to_h1(const struct ist n, const struct ist v, struct buffer *chk); -int htx_data_to_h1(const struct ist data, struct buffer *chk, int chunked); - /* Functions and macros to get parts of the start-line or legnth of these * parts. Request and response start-lines are both composed of 3 parts. */ diff --git a/include/proto/h1_htx.h b/include/proto/h1_htx.h index 51db02c243..e77663b928 100644 --- a/include/proto/h1_htx.h +++ b/include/proto/h1_htx.h @@ -35,6 +35,11 @@ int h1_parse_msg_data(struct h1m *h1m, struct htx **dsthtx, int h1_parse_msg_tlrs(struct h1m *h1m, struct htx *dsthtx, struct buffer *srcbuf, size_t ofs, size_t max); +int h1_format_htx_reqline(const struct htx_sl *sl, struct buffer *chk); +int h1_format_htx_stline(const struct htx_sl *sl, struct buffer *chk); +int h1_format_htx_hdr(const struct ist n, const struct ist v, struct buffer *chk); +int h1_format_htx_data(const struct ist data, struct buffer *chk, int chunked); + #endif /* _PROTO_H1_HTX_H */ /* diff --git a/src/h1_htx.c b/src/h1_htx.c index 9ecabf0439..48bfae5448 100644 --- a/src/h1_htx.c +++ b/src/h1_htx.c @@ -603,6 +603,146 @@ int h1_parse_msg_tlrs(struct h1m *h1m, struct htx *dsthtx, return 0; } + +/* Appends the H1 representation of the request line to the chunk . It + * returns 1 if data are successfully appended, otherwise it returns 0. + */ +int h1_format_htx_reqline(const struct htx_sl *sl, struct buffer *chk) +{ + struct ist uri; + size_t sz = chk->data; + + uri = htx_sl_req_uri(sl); + if (sl->flags & HTX_SL_F_NORMALIZED_URI) { + uri = http_get_path(uri); + if (unlikely(!uri.len)) { + if (sl->info.req.meth == HTTP_METH_OPTIONS) + uri = ist("*"); + else + uri = ist("/"); + } + } + + if (!chunk_memcat(chk, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl)) || + !chunk_memcat(chk, " ", 1) || + !chunk_memcat(chk, uri.ptr, uri.len) || + !chunk_memcat(chk, " ", 1)) + goto full; + + if (sl->flags & HTX_SL_F_VER_11) { + if (!chunk_memcat(chk, "HTTP/1.1", 8)) + goto full; + } + else { + if (!chunk_memcat(chk, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl))) + goto full; + } + + if (!chunk_memcat(chk, "\r\n", 2)) + goto full; + + return 1; + + full: + chk->data = sz; + return 0; +} + +/* Appends the H1 representation of the status line to the chunk . It + * returns 1 if data are successfully appended, otherwise it returns 0. + */ +int h1_format_htx_stline(const struct htx_sl *sl, struct buffer *chk) +{ + size_t sz = chk->data; + + if (HTX_SL_LEN(sl) + 4 > b_room(chk)) + return 0; + + if (sl->flags & HTX_SL_F_VER_11) { + if (!chunk_memcat(chk, "HTTP/1.1", 8)) + goto full; + } + else { + if (!chunk_memcat(chk, HTX_SL_RES_VPTR(sl), HTX_SL_RES_VLEN(sl))) + goto full; + } + if (!chunk_memcat(chk, " ", 1) || + !chunk_memcat(chk, HTX_SL_RES_CPTR(sl), HTX_SL_RES_CLEN(sl)) || + !chunk_memcat(chk, " ", 1) || + !chunk_memcat(chk, HTX_SL_RES_RPTR(sl), HTX_SL_RES_RLEN(sl)) || + !chunk_memcat(chk, "\r\n", 2)) + goto full; + + return 1; + + full: + chk->data = sz; + return 0; +} + +/* Appends the H1 representation of the header witht the value to the + * chunk . It returns 1 if data are successfully appended, otherwise it + * returns 0. + */ +int h1_format_htx_hdr(const struct ist n, const struct ist v, struct buffer *chk) +{ + size_t sz = chk->data; + + if (n.len + v.len + 4 > b_room(chk)) + return 0; + + if (!chunk_memcat(chk, n.ptr, n.len) || + !chunk_memcat(chk, ": ", 2) || + !chunk_memcat(chk, v.ptr, v.len) || + !chunk_memcat(chk, "\r\n", 2)) + goto full; + + return 1; + + full: + chk->data = sz; + return 0; +} + +/* Appends the H1 representation of the data to the chunk . If + * is non-zero, it emits HTTP/1 chunk-encoded data. It returns 1 if + * data are successfully appended, otherwise it returns 0. + */ +int h1_format_htx_data(const struct ist data, struct buffer *chk, int chunked) +{ + size_t sz = chk->data; + + if (chunked) { + uint32_t chksz; + char tmp[10]; + char *beg, *end; + + chksz = data.len; + + beg = end = tmp+10; + *--beg = '\n'; + *--beg = '\r'; + do { + *--beg = hextab[chksz & 0xF]; + } while (chksz >>= 4); + + if (!chunk_memcat(chk, beg, end - beg) || + !chunk_memcat(chk, data.ptr, data.len) || + !chunk_memcat(chk, "\r\n", 2)) + goto full; + } + else { + if (!chunk_memcat(chk, data.ptr, data.len)) + return 0; + } + + return 1; + + full: + chk->data = sz; + return 0; +} + /* * Local variables: * c-indent-level: 8 diff --git a/src/http_fetch.c b/src/http_fetch.c index 0989b99cc2..bf4c006809 100644 --- a/src/http_fetch.c +++ b/src/http_fetch.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -447,7 +448,7 @@ static int smp_fetch_hdrs(const struct arg *args, struct sample *smp, const char struct ist n = htx_get_blk_name(htx, blk); struct ist v = htx_get_blk_value(htx, blk); - if (!htx_hdr_to_h1(n, v, temp)) + if (!h1_format_htx_hdr(n, v, temp)) return 0; } else if (type == HTX_BLK_EOH) { @@ -559,7 +560,7 @@ static int smp_fetch_body(const struct arg *args, struct sample *smp, const char if (type == HTX_BLK_EOM || type == HTX_BLK_TLR || type == HTX_BLK_EOT) break; if (type == HTX_BLK_DATA) { - if (!htx_data_to_h1(htx_get_blk_value(htx, blk), temp, 0)) + if (!h1_format_htx_data(htx_get_blk_value(htx, blk), temp, 0)) return 0; } } @@ -1800,7 +1801,7 @@ static int smp_fetch_body_param(const struct arg *args, struct sample *smp, cons if (type == HTX_BLK_EOM || type == HTX_BLK_TLR || type == HTX_BLK_EOT) break; if (type == HTX_BLK_DATA) { - if (!htx_data_to_h1(htx_get_blk_value(htx, blk), temp, 0)) + if (!h1_format_htx_data(htx_get_blk_value(htx, blk), temp, 0)) return 0; } } diff --git a/src/htx.c b/src/htx.c index bdca69b380..139f3c096b 100644 --- a/src/htx.c +++ b/src/htx.c @@ -1040,142 +1040,3 @@ void htx_move_blk_before(struct htx *htx, struct htx_blk **blk, struct htx_blk * *blk = cblk; *ref = pblk; } - -/* Appends the H1 representation of the request line to the chunk . It - * returns 1 if data are successfully appended, otherwise it returns 0. - */ -int htx_reqline_to_h1(const struct htx_sl *sl, struct buffer *chk) -{ - struct ist uri; - size_t sz = chk->data; - - uri = htx_sl_req_uri(sl); - if (sl->flags & HTX_SL_F_NORMALIZED_URI) { - uri = http_get_path(uri); - if (unlikely(!uri.len)) { - if (sl->info.req.meth == HTTP_METH_OPTIONS) - uri = ist("*"); - else - uri = ist("/"); - } - } - - if (!chunk_memcat(chk, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl)) || - !chunk_memcat(chk, " ", 1) || - !chunk_memcat(chk, uri.ptr, uri.len) || - !chunk_memcat(chk, " ", 1)) - goto full; - - if (sl->flags & HTX_SL_F_VER_11) { - if (!chunk_memcat(chk, "HTTP/1.1", 8)) - goto full; - } - else { - if (!chunk_memcat(chk, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl))) - goto full; - } - - if (!chunk_memcat(chk, "\r\n", 2)) - goto full; - - return 1; - - full: - chk->data = sz; - return 0; -} - -/* Appends the H1 representation of the status line to the chunk . It - * returns 1 if data are successfully appended, otherwise it returns 0. - */ -int htx_stline_to_h1(const struct htx_sl *sl, struct buffer *chk) -{ - size_t sz = chk->data; - - if (HTX_SL_LEN(sl) + 4 > b_room(chk)) - return 0; - - if (sl->flags & HTX_SL_F_VER_11) { - if (!chunk_memcat(chk, "HTTP/1.1", 8)) - goto full; - } - else { - if (!chunk_memcat(chk, HTX_SL_RES_VPTR(sl), HTX_SL_RES_VLEN(sl))) - goto full; - } - if (!chunk_memcat(chk, " ", 1) || - !chunk_memcat(chk, HTX_SL_RES_CPTR(sl), HTX_SL_RES_CLEN(sl)) || - !chunk_memcat(chk, " ", 1) || - !chunk_memcat(chk, HTX_SL_RES_RPTR(sl), HTX_SL_RES_RLEN(sl)) || - !chunk_memcat(chk, "\r\n", 2)) - goto full; - - return 1; - - full: - chk->data = sz; - return 0; -} - -/* Appends the H1 representation of the header witht the value to the - * chunk . It returns 1 if data are successfully appended, otherwise it - * returns 0. - */ -int htx_hdr_to_h1(const struct ist n, const struct ist v, struct buffer *chk) -{ - size_t sz = chk->data; - - if (n.len + v.len + 4 > b_room(chk)) - return 0; - - if (!chunk_memcat(chk, n.ptr, n.len) || - !chunk_memcat(chk, ": ", 2) || - !chunk_memcat(chk, v.ptr, v.len) || - !chunk_memcat(chk, "\r\n", 2)) - goto full; - - return 1; - - full: - chk->data = sz; - return 0; -} - -/* Appends the H1 representation of the data to the chunk . If - * is non-zero, it emits HTTP/1 chunk-encoded data. It returns 1 if - * data are successfully appended, otherwise it returns 0. - */ -int htx_data_to_h1(const struct ist data, struct buffer *chk, int chunked) -{ - size_t sz = chk->data; - - if (chunked) { - uint32_t chksz; - char tmp[10]; - char *beg, *end; - - chksz = data.len; - - beg = end = tmp+10; - *--beg = '\n'; - *--beg = '\r'; - do { - *--beg = hextab[chksz & 0xF]; - } while (chksz >>= 4); - - if (!chunk_memcat(chk, beg, end - beg) || - !chunk_memcat(chk, data.ptr, data.len) || - !chunk_memcat(chk, "\r\n", 2)) - goto full; - } - else { - if (!chunk_memcat(chk, data.ptr, data.len)) - return 0; - } - - return 1; - - full: - chk->data = sz; - return 0; -} diff --git a/src/mux_h1.c b/src/mux_h1.c index 935c925dc6..ac520a42df 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -1588,7 +1588,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun sl = htx_get_blk_ptr(chn_htx, blk); h1s->meth = sl->info.req.meth; h1_parse_req_vsn(h1m, sl); - if (!htx_reqline_to_h1(sl, &tmp)) + if (!h1_format_htx_reqline(sl, &tmp)) goto full; h1m->flags |= H1_MF_XFER_LEN; if (sl->flags & HTX_SL_F_BODYLESS) @@ -1603,7 +1603,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun sl = htx_get_blk_ptr(chn_htx, blk); h1s->status = sl->info.res.status; h1_parse_res_vsn(h1m, sl); - if (!htx_stline_to_h1(sl, &tmp)) + if (!h1_format_htx_stline(sl, &tmp)) goto full; if (sl->flags & HTX_SL_F_XFER_LEN) h1m->flags |= H1_MF_XFER_LEN; @@ -1650,7 +1650,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun /* Try to adjust the case of the header name */ if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV)) h1_adjust_case_outgoing_hdr(h1s, h1m, &n); - if (!htx_hdr_to_h1(n, v, &tmp)) + if (!h1_format_htx_hdr(n, v, &tmp)) goto full; skip_hdr: h1m->state = H1_MSG_HDR_L2_LWS; @@ -1672,7 +1672,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun /* Try to adjust the case of the header name */ if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV)) h1_adjust_case_outgoing_hdr(h1s, h1m, &n); - if (!htx_hdr_to_h1(n, v, &tmp)) + if (!h1_format_htx_hdr(n, v, &tmp)) goto full; } h1s->flags |= H1S_F_HAVE_O_CONN; @@ -1690,7 +1690,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun v = ist("chunked"); if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV)) h1_adjust_case_outgoing_hdr(h1s, h1m, &n); - if (!htx_hdr_to_h1(n, v, &tmp)) + if (!h1_format_htx_hdr(n, v, &tmp)) goto full; TRACE_STATE("add \"Transfer-Encoding: chunked\"", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1c->conn, h1s); h1m->flags |= H1_MF_CHNK; @@ -1708,7 +1708,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun /* Try to adjust the case of the header name */ if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV)) h1_adjust_case_outgoing_hdr(h1s, h1m, &n); - if (!htx_hdr_to_h1(n, v, &tmp)) + if (!h1_format_htx_hdr(n, v, &tmp)) goto full; } TRACE_STATE("add server name header", H1_EV_TX_DATA|H1_EV_TX_HDRS, h1c->conn, h1s); @@ -1793,7 +1793,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun } v = htx_get_blk_value(chn_htx, blk); v.len = vlen; - if (!htx_data_to_h1(v, &tmp, !!(h1m->flags & H1_MF_CHNK))) + if (!h1_format_htx_data(v, &tmp, !!(h1m->flags & H1_MF_CHNK))) goto full; if (h1m->state == H1_MSG_DATA) @@ -1829,7 +1829,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun /* Try to adjust the case of the header name */ if (h1c->px->options2 & (PR_O2_H1_ADJ_BUGCLI|PR_O2_H1_ADJ_BUGSRV)) h1_adjust_case_outgoing_hdr(h1s, h1m, &n); - if (!htx_hdr_to_h1(n, v, &tmp)) + if (!h1_format_htx_hdr(n, v, &tmp)) goto full; } break;