MEDIUM: htx: Don't rely on h1_sl anymore except during H1 header parsing
Instead, we now use the htx_sl coming from the HTX message. It avoids to have
too H1 specific code in version-agnostic parts. Of course, the concept of the
start-line is higly influenced by the H1, but the structure htx_sl can be
adapted, if necessary. And many things depend on a start-line during HTTP
analyzis. Using the structure htx_sl also avoid boring conversions between HTX
version and H1 version.
diff --git a/src/http_htx.c b/src/http_htx.c
index 1a8e5bb..82f9497 100644
--- a/src/http_htx.c
+++ b/src/http_htx.c
@@ -17,44 +17,33 @@
#include <proto/htx.h>
/* Finds the start line in the HTX message stopping at the first
- * end-of-message. It returns an empty start line when not found, otherwise, it
- * returns the corresponding <struct h1_sl>.
+ * end-of-message. It returns NULL when not found, otherwise, it returns the
+ * pointer on the htx_sl structure. The HTX message may be updated if the
+ * start-line is returned following a lookup.
*/
-union h1_sl http_find_stline(const struct htx *htx)
+struct htx_sl *http_find_stline(struct htx *htx)
{
- struct htx_sl *htx_sl;
- union h1_sl sl;
+ struct htx_sl *sl = NULL;
int32_t pos;
+ sl = htx_get_stline(htx);
+ if (sl)
+ return sl;
+
for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
struct htx_blk *blk = htx_get_blk(htx, pos);
enum htx_blk_type type = htx_get_blk_type(blk);
- if (type == HTX_BLK_REQ_SL) {
- htx_sl = htx_get_blk_ptr(htx, blk);
- sl.rq.meth = htx_sl->info.req.meth;
- sl.rq.m = htx_sl_req_meth(htx_sl);
- sl.rq.u = htx_sl_req_uri(htx_sl);
- sl.rq.v = htx_sl_req_vsn(htx_sl);
- return sl;
- }
-
- if (type == HTX_BLK_RES_SL) {
- htx_sl = htx_get_blk_ptr(htx, blk);
- sl.st.status = htx_sl->info.res.status;
- sl.st.v = htx_sl_res_vsn(htx_sl);
- sl.st.c = htx_sl_res_code(htx_sl);
- sl.st.r = htx_sl_res_reason(htx_sl);
- return sl;
+ if (type == HTX_BLK_REQ_SL || type == HTX_BLK_RES_SL) {
+ sl = htx_get_blk_ptr(htx, blk);
+ htx->sl_off = blk->addr;
+ break;
}
if (type == HTX_BLK_EOH || type == HTX_BLK_EOM)
break;
}
- sl.rq.m = ist("");
- sl.rq.u = ist("");
- sl.rq.v = ist("");
return sl;
}
@@ -193,50 +182,24 @@
return 1;
}
-/* Replaces the request start line of the HTX message <htx> by <sl>. It returns
- * 1 on success, otherwise it returns 0. The start line must be found in the
+/* Replaces parts of the start-line of the HTX message <htx>. It returns 1 on
+ * success, otherwise it returns 0. The right block is search in the HTX
* message.
*/
-int http_replace_reqline(struct htx *htx, const union h1_sl sl)
+int http_replace_stline(struct htx *htx, const struct ist p1, const struct ist p2, const struct ist p3)
{
int32_t pos;
for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
- struct htx_blk *blk = htx_get_blk(htx, pos);
- enum htx_blk_type type = htx_get_blk_type(blk);
+ struct htx_blk *blk = htx_get_blk(htx, pos);
+ enum htx_blk_type type = htx_get_blk_type(blk);
- if (type == HTX_BLK_REQ_SL) {
- blk = htx_replace_reqline(htx, blk, sl);
- if (!blk)
+ if (htx->sl_off == blk->addr) {
+ if (!htx_replace_stline(htx, blk, p1, p2, p3))
return 0;
return 1;
}
- if (type == HTX_BLK_EOM)
- break;
- }
-
- return 0;
-}
-
-
-/* Replaces the response start line of the HTX message <htx> by <sl>. It returns
- * 1 on success, otherwise it returns 0. The start line must be found in the
- * message.
- */
-int http_replace_resline(struct htx *htx, const union h1_sl sl)
-{
- int32_t pos;
- for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
- struct htx_blk *blk = htx_get_blk(htx, pos);
- enum htx_blk_type type = htx_get_blk_type(blk);
-
- if (type == HTX_BLK_RES_SL) {
- blk = htx_replace_resline(htx, blk, sl);
- if (!blk)
- return 0;
- return 1;
- }
if (type == HTX_BLK_EOM)
break;
}
@@ -250,20 +213,19 @@
int http_replace_req_meth(struct htx *htx, const struct ist meth)
{
struct buffer *temp = get_trash_chunk();
- union h1_sl sl = http_find_stline(htx);
- union h1_sl new_sl;
+ struct htx_sl *sl = http_find_stline(htx);
+ struct ist uri, vsn;
/* Start by copying old uri and version */
- chunk_memcat(temp, sl.rq.u.ptr, sl.rq.u.len); /* uri */
- chunk_memcat(temp, sl.rq.v.ptr, sl.rq.v.len); /* vsn */
+ chunk_memcat(temp, HTX_SL_REQ_UPTR(sl), HTX_SL_REQ_ULEN(sl)); /* uri */
+ uri = ist2(temp->area, HTX_SL_REQ_ULEN(sl));
- /* create the new start line */
- new_sl.rq.meth = find_http_meth(meth.ptr, meth.len);
- new_sl.rq.m = meth;
- new_sl.rq.u = ist2(temp->area, sl.rq.u.len);
- new_sl.rq.v = ist2(temp->area + sl.rq.u.len, sl.rq.v.len);
+ chunk_memcat(temp, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl)); /* vsn */
+ vsn = ist2(temp->area + uri.len, HTX_SL_REQ_VLEN(sl));
- return http_replace_reqline(htx, new_sl);
+ /* create the new start line */
+ sl->info.req.meth = find_http_meth(meth.ptr, meth.len);
+ return http_replace_stline(htx, meth, uri, vsn);
}
/* Replace the request uri in the HTX message <htx> by <uri>. It returns 1 on
@@ -272,20 +234,18 @@
int http_replace_req_uri(struct htx *htx, const struct ist uri)
{
struct buffer *temp = get_trash_chunk();
- union h1_sl sl = http_find_stline(htx);
- union h1_sl new_sl;
+ struct htx_sl *sl = http_find_stline(htx);
+ struct ist meth, vsn;
/* Start by copying old method and version */
- chunk_memcat(temp, sl.rq.m.ptr, sl.rq.m.len); /* meth */
- chunk_memcat(temp, sl.rq.v.ptr, sl.rq.v.len); /* vsn */
+ chunk_memcat(temp, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl)); /* meth */
+ meth = ist2(temp->area, HTX_SL_REQ_MLEN(sl));
- /* create the new start line */
- new_sl.rq.meth = sl.rq.meth;
- new_sl.rq.m = ist2(temp->area, sl.rq.m.len);
- new_sl.rq.u = uri;
- new_sl.rq.v = ist2(temp->area + sl.rq.m.len, sl.rq.v.len);
+ chunk_memcat(temp, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl)); /* vsn */
+ vsn = ist2(temp->area + meth.len, HTX_SL_REQ_VLEN(sl));
- return http_replace_reqline(htx, new_sl);
+ /* create the new start line */
+ return http_replace_stline(htx, meth, uri, vsn);
}
/* Replace the request path in the HTX message <htx> by <path>. The host part
@@ -294,36 +254,31 @@
int http_replace_req_path(struct htx *htx, const struct ist path)
{
struct buffer *temp = get_trash_chunk();
- union h1_sl sl = http_find_stline(htx);
- union h1_sl new_sl;
- struct ist p, uri;
+ struct htx_sl *sl = http_find_stline(htx);
+ struct ist meth, uri, vsn, p;
size_t plen = 0;
- p = http_get_path(sl.rq.u);
+ uri = htx_sl_req_uri(sl);
+ p = http_get_path(uri);
if (!p.ptr)
- p = sl.rq.u;
+ p = uri;
while (plen < p.len && *(p.ptr + plen) != '?')
plen++;
/* Start by copying old method and version and create the new uri */
- chunk_memcat(temp, sl.rq.m.ptr, sl.rq.m.len); /* meth */
- chunk_memcat(temp, sl.rq.v.ptr, sl.rq.v.len); /* vsn */
+ chunk_memcat(temp, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl)); /* meth */
+ meth = ist2(temp->area, HTX_SL_REQ_MLEN(sl));
- chunk_memcat(temp, sl.rq.u.ptr, p.ptr - sl.rq.u.ptr); /* uri: host part */
+ chunk_memcat(temp, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl)); /* vsn */
+ vsn = ist2(temp->area + meth.len, HTX_SL_REQ_VLEN(sl));
+
+ chunk_memcat(temp, uri.ptr, p.ptr - uri.ptr); /* uri: host part */
chunk_memcat(temp, path.ptr, path.len); /* uri: new path */
chunk_memcat(temp, p.ptr + plen, p.len - plen); /* uri: QS part */
-
- /* Get uri ptr and len */
- uri.ptr = temp->area + sl.rq.m.len + sl.rq.v.len;
- uri.len = sl.rq.u.len - plen + path.len;
+ uri = ist2(temp->area + meth.len + vsn.len, uri.len - plen + path.len);
/* create the new start line */
- new_sl.rq.meth = sl.rq.meth;
- new_sl.rq.m = ist2(temp->area, sl.rq.m.len);
- new_sl.rq.u = uri;
- new_sl.rq.v = ist2(temp->area + sl.rq.m.len, sl.rq.v.len);
-
- return http_replace_reqline(htx, new_sl);
+ return http_replace_stline(htx, meth, uri, vsn);
}
/* Replace the request query-string in the HTX message <htx> by <query>. The
@@ -333,12 +288,12 @@
int http_replace_req_query(struct htx *htx, const struct ist query)
{
struct buffer *temp = get_trash_chunk();
- union h1_sl sl = http_find_stline(htx);
- union h1_sl new_sl;
- struct ist q, uri;
+ struct htx_sl *sl = http_find_stline(htx);
+ struct ist meth, uri, vsn, q;
int offset = 1;
- q = sl.rq.u;
+ uri = htx_sl_req_uri(sl);
+ q = uri;
while (q.len > 0 && *(q.ptr) != '?') {
q.ptr++;
q.len--;
@@ -355,23 +310,18 @@
offset = 0;
/* Start by copying old method and version and create the new uri */
- chunk_memcat(temp, sl.rq.m.ptr, sl.rq.m.len); /* meth */
- chunk_memcat(temp, sl.rq.v.ptr, sl.rq.v.len); /* vsn */
+ chunk_memcat(temp, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl)); /* meth */
+ meth = ist2(temp->area, HTX_SL_REQ_MLEN(sl));
- chunk_memcat(temp, sl.rq.u.ptr, q.ptr - sl.rq.u.ptr); /* uri: host + path part */
- chunk_memcat(temp, query.ptr + offset, query.len - offset); /* uri: new QS */
+ chunk_memcat(temp, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl)); /* vsn */
+ vsn = ist2(temp->area + meth.len, HTX_SL_REQ_VLEN(sl));
- /* Get uri ptr and len */
- uri.ptr = temp->area + sl.rq.m.len + sl.rq.v.len;
- uri.len = sl.rq.u.len - q.len + query.len - offset;
+ chunk_memcat(temp, uri.ptr, q.ptr - uri.ptr); /* uri: host + path part */
+ chunk_memcat(temp, query.ptr + offset, query.len - offset); /* uri: new QS */
+ uri = ist2(temp->area + meth.len + vsn.len, uri.len - q.len + query.len - offset);
/* create the new start line */
- new_sl.rq.meth = sl.rq.meth;
- new_sl.rq.m = ist2(temp->area, sl.rq.m.len);
- new_sl.rq.u = uri;
- new_sl.rq.v = ist2(temp->area + sl.rq.m.len, sl.rq.v.len);
-
- return http_replace_reqline(htx, new_sl);
+ return http_replace_stline(htx, meth, uri, vsn);
}
/* Replace the response status in the HTX message <htx> by <status>. It returns
@@ -380,20 +330,19 @@
int http_replace_res_status(struct htx *htx, const struct ist status)
{
struct buffer *temp = get_trash_chunk();
- union h1_sl sl = http_find_stline(htx);
- union h1_sl new_sl;
+ struct htx_sl *sl = http_find_stline(htx);
+ struct ist vsn, reason;
/* Start by copying old uri and version */
- chunk_memcat(temp, sl.st.v.ptr, sl.st.v.len); /* vsn */
- chunk_memcat(temp, sl.st.r.ptr, sl.st.r.len); /* reason */
+ chunk_memcat(temp, HTX_SL_RES_VPTR(sl), HTX_SL_RES_VLEN(sl)); /* vsn */
+ vsn = ist2(temp->area, HTX_SL_RES_VLEN(sl));
- /* create the new start line */
- new_sl.st.status = strl2ui(status.ptr, status.len);
- new_sl.st.v = ist2(temp->area, sl.st.v.len);
- new_sl.st.c = status;
- new_sl.st.r = ist2(temp->area + sl.st.v.len, sl.st.r.len);
+ chunk_memcat(temp, HTX_SL_RES_RPTR(sl), HTX_SL_RES_RLEN(sl)); /* reason */
+ reason = ist2(temp->area + vsn.len, HTX_SL_RES_RLEN(sl));
- return http_replace_resline(htx, new_sl);
+ /* create the new start line */
+ sl->info.res.status = strl2ui(status.ptr, status.len);
+ return http_replace_stline(htx, vsn, status, reason);
}
/* Replace the response reason in the HTX message <htx> by <reason>. It returns
@@ -402,20 +351,18 @@
int http_replace_res_reason(struct htx *htx, const struct ist reason)
{
struct buffer *temp = get_trash_chunk();
- union h1_sl sl = http_find_stline(htx);
- union h1_sl new_sl;
+ struct htx_sl *sl = http_find_stline(htx);
+ struct ist vsn, status;
/* Start by copying old uri and version */
- chunk_memcat(temp, sl.st.v.ptr, sl.st.v.len); /* vsn */
- chunk_memcat(temp, sl.st.c.ptr, sl.st.c.len); /* code */
+ chunk_memcat(temp, HTX_SL_RES_VPTR(sl), HTX_SL_RES_VLEN(sl)); /* vsn */
+ vsn = ist2(temp->area, HTX_SL_RES_VLEN(sl));
- /* create the new start line */
- new_sl.st.status = sl.st.status;
- new_sl.st.v = ist2(temp->area, sl.st.v.len);
- new_sl.st.c = ist2(temp->area + sl.st.v.len, sl.st.c.len);
- new_sl.st.r = reason;
+ chunk_memcat(temp, HTX_SL_RES_CPTR(sl), HTX_SL_RES_CLEN(sl)); /* code */
+ status = ist2(temp->area + vsn.len, HTX_SL_RES_CLEN(sl));
- return http_replace_resline(htx, new_sl);
+ /* create the new start line */
+ return http_replace_stline(htx, vsn, status, reason);
}
/* Replaces a part of a header value referenced in the context <ctx> by