MINOR: http_htx: Add functions to replace part of the start-line
diff --git a/include/proto/http_htx.h b/include/proto/http_htx.h
index 1ca7902..c9f730e 100644
--- a/include/proto/http_htx.h
+++ b/include/proto/http_htx.h
@@ -33,6 +33,12 @@
int http_add_header(struct htx *htx, const struct ist n, const struct ist v);
int http_replace_reqline(struct htx *htx, const union h1_sl sl);
int http_replace_resline(struct htx *htx, const union h1_sl sl);
+int http_replace_req_meth(struct htx *htx, const struct ist meth);
+int http_replace_req_uri(struct htx *htx, const struct ist uri);
+int http_replace_req_path(struct htx *htx, const struct ist path);
+int http_replace_req_query(struct htx *htx, const struct ist query);
+int http_replace_res_status(struct htx *htx, const struct ist status);
+int http_replace_res_reason(struct htx *htx, const struct ist reason);
int http_replace_header_value(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist data);
int http_replace_header(struct htx *htx, struct http_hdr_ctx *ctx, const struct ist name, const struct ist value);
int http_remove_header(struct htx *htx, struct http_hdr_ctx *ctx);
diff --git a/src/http_htx.c b/src/http_htx.c
index 47e36c8..36a2793 100644
--- a/src/http_htx.c
+++ b/src/http_htx.c
@@ -241,6 +241,180 @@
return 0;
}
+/* Replace the request method in the HTX message <htx> by <meth>. It returns 1
+ * on success, otherwise 0.
+ */
+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;
+
+ /* 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 */
+
+ /* 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);
+
+ return http_replace_reqline(htx, new_sl);
+}
+
+/* Replace the request uri in the HTX message <htx> by <uri>. It returns 1 on
+ * success, otherwise 0.
+ */
+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;
+
+ /* 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 */
+
+ /* 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);
+}
+
+/* Replace the request path in the HTX message <htx> by <path>. The host part
+ * and the query string are preserved. It returns 1 on success, otherwise 0.
+ */
+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;
+ size_t plen = 0;
+
+ p = http_get_path(sl.rq.u);
+ if (!p.ptr)
+ p = sl.rq.u;
+ 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, sl.rq.u.ptr, p.ptr - sl.rq.u.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;
+
+ /* 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);
+}
+
+/* Replace the request query-string in the HTX message <htx> by <query>. The
+ * host part and the path are preserved. It returns 1 on success, otherwise
+ * 0.
+ */
+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;
+ int offset = 1;
+
+ q = sl.rq.u;
+ while (q.len > 0 && *(q.ptr) != '?') {
+ q.ptr++;
+ q.len--;
+ }
+
+ /* skip the question mark or indicate that we must insert it
+ * (but only if the format string is not empty then).
+ */
+ if (q.len) {
+ q.ptr++;
+ q.len--;
+ }
+ else if (query.len > 1)
+ 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, 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 */
+
+ /* 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;
+
+ /* 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);
+}
+
+/* Replace the response status in the HTX message <htx> by <status>. It returns
+ * 1 on success, otherwise 0.
+*/
+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;
+
+ /* 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 */
+
+ /* 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);
+
+ return http_replace_resline(htx, new_sl);
+}
+
+/* Replace the response reason in the HTX message <htx> by <reason>. It returns
+ * 1 on success, otherwise 0.
+*/
+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;
+
+ /* 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 */
+
+ /* 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;
+
+ return http_replace_resline(htx, new_sl);
+}
+
/* Replaces a part of a header value referenced in the context <ctx> by
* <data>. It returns 1 on success, otherwise it returns 0. The context is
* updated if necessary.