MINOR: qpack: generate headers list on decoder
TMP -> non-free strdup
TMP -> currently only support indexed field line or literal field line
with name reference
diff --git a/include/haproxy/qpack-dec.h b/include/haproxy/qpack-dec.h
index 517d617..f45246f 100644
--- a/include/haproxy/qpack-dec.h
+++ b/include/haproxy/qpack-dec.h
@@ -24,6 +24,7 @@
#include <haproxy/mux_quic-t.h>
struct h3_uqs;
+struct http_hdr;
/* Internal QPACK processing errors.
*Nothing to see with the RFC.
@@ -43,7 +44,8 @@
uint64_t krc;
};
-int qpack_decode_fs(const unsigned char *buf, uint64_t len, struct buffer *tmp);
+int qpack_decode_fs(const unsigned char *buf, uint64_t len, struct buffer *tmp,
+ struct http_hdr *list);
int qpack_decode_enc(struct h3_uqs *h3_uqs, void *ctx);
int qpack_decode_dec(struct h3_uqs *h3_uqs, void *ctx);
diff --git a/src/h3.c b/src/h3.c
index c90e63a..78d43a7 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -121,6 +121,8 @@
{
struct buffer *rxbuf = &qcs->rx.buf;
struct h3 *h3 = ctx;
+ struct http_hdr list[global.tune.max_http_hdr];
+ int hdr_idx;
h3_debug_printf(stderr, "%s: STREAM ID: %llu\n", __func__, qcs->by_id.key);
if (!b_data(rxbuf))
@@ -152,7 +154,7 @@
size_t len = b_data(rxbuf);
struct buffer *tmp = get_trash_chunk();
- if (qpack_decode_fs(buf, len, tmp) < 0) {
+ if (qpack_decode_fs(buf, len, tmp, list) < 0) {
h3->err = QPACK_DECOMPRESSION_FAILED;
return -1;
}
diff --git a/src/qpack-dec.c b/src/qpack-dec.c
index 95ec720..54e7f16 100644
--- a/src/qpack-dec.c
+++ b/src/qpack-dec.c
@@ -29,8 +29,10 @@
#include <haproxy/h3.h>
#include <haproxy/qpack-t.h>
#include <haproxy/qpack-dec.h>
+#include <haproxy/qpack-tbl.h>
#include <haproxy/hpack-huff.h>
#include <haproxy/hpack-tbl.h>
+#include <haproxy/http-hdr.h>
#include <haproxy/tools.h>
#define DEBUG_HPACK
@@ -177,12 +179,14 @@
/* Decode a field section from <len> bytes length <raw> buffer.
* Produces the output into <tmp> buffer.
*/
-int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp)
+int qpack_decode_fs(const unsigned char *raw, size_t len, struct buffer *tmp,
+ struct http_hdr *list)
{
uint64_t enc_ric, db;
int s;
unsigned int efl_type;
int ret;
+ int hdr_idx = 0;
qpack_debug_hexdump(stderr, "[QPACK-DEC-FS] ", (const char *)raw, 0, len);
@@ -227,7 +231,8 @@
/* XXX Value string XXX */
raw += length;
len -= length;
- } else if (efl_type == QPACK_IFL_WPBI) {
+ }
+ else if (efl_type == QPACK_IFL_WPBI) {
/* Indexed field line with post-base index */
uint64_t index;
@@ -240,7 +245,8 @@
}
qpack_debug_printf(stderr, " index=%llu", (unsigned long long)index);
- } else if (efl_type & QPACK_IFL_BIT) {
+ }
+ else if (efl_type & QPACK_IFL_BIT) {
/* Indexed field line */
uint64_t index;
unsigned int t;
@@ -254,8 +260,12 @@
goto out;
}
+ if (t)
+ list[hdr_idx++] = qpack_sht[index];
+
qpack_debug_printf(stderr, " t=%d index=%llu", !!t, (unsigned long long)index);
- } else if (efl_type & QPACK_LFL_WNR_BIT) {
+ }
+ else if (efl_type & QPACK_LFL_WNR_BIT) {
/* Literal field line with name reference */
uint64_t index, length;
unsigned int t, n, h;
@@ -270,6 +280,9 @@
goto out;
}
+ if (t)
+ list[hdr_idx] = qpack_sht[index];
+
qpack_debug_printf(stderr, " n=%d t=%d index=%llu", !!n, !!t, (unsigned long long)index);
h = *raw & 0x80;
length = qpack_get_varint(&raw, &len, 7);
@@ -298,11 +311,14 @@
}
qpack_debug_printf(stderr, " [name huff %d->%d '%s']", (int)length, (int)nlen, trash);
+ list[hdr_idx].v = ist(strdup(trash));
}
/* XXX Value string XXX */
raw += length;
len -= length;
- } else if (efl_type & QPACK_LFL_WLN_BIT) {
+ ++hdr_idx;
+ }
+ else if (efl_type & QPACK_LFL_WLN_BIT) {
/* Literal field line with literal name */
unsigned int n, hname, hvalue;
uint64_t name_len, value_len;
@@ -338,6 +354,9 @@
qpack_debug_printf(stderr, "\n");
}
+ /* put an end marker */
+ list[hdr_idx].n = list[hdr_idx].v = IST_NULL;
+
out:
qpack_debug_printf(stderr, "-- done: ret=%d\n", ret);
return ret;