]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proto_htx: Add functions htx_req_replace_stline and htx_res_set_status
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 24 Oct 2018 09:27:39 +0000 (11:27 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 18 Nov 2018 21:08:56 +0000 (22:08 +0100)
It is more or less the same than legacy versions but adapted to be called from
HTX analyzers. In the legacy versions of these functions, we switch on the HTX
code when applicable.

include/proto/proto_http.h
src/proto_http.c
src/proto_htx.c

index 0d126d6b5c6e860748a4bfdcf4a03ef12337b8ac..0598df8f8d42f023342139e954d9a435f71fb254 100644 (file)
@@ -70,6 +70,9 @@ void htx_adjust_conn_mode(struct stream *s, struct http_txn *txn);
 int htx_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struct http_txn *txn);
 int htx_transform_header_str(struct stream* s, struct channel *chn, struct htx *htx,
                             struct ist name, const char *str, struct my_regex *re, int action);
+int htx_req_replace_stline(int action, const char *replace, int len,
+                          struct proxy *px, struct stream *s);
+void htx_res_set_status(unsigned int status, const char *reason, struct stream *s);
 void htx_server_error(struct stream *s, struct stream_interface *si, int err, int finst, const struct buffer *msg);
 void htx_reply_and_close(struct stream *s, short status, struct buffer *msg);
 
index 0f71e83ed40219f326a9afb53562465551d13c53..8b35ac5a724c096728feb1b0d0f544b59ae6dcd6 100644 (file)
@@ -7812,6 +7812,9 @@ int http_replace_req_line(int action, const char *replace, int len,
        int offset = 0;
        int delta;
 
+       if (IS_HTX_STRM(s))
+               return htx_req_replace_stline(action, replace, len, px, s);
+
        switch (action) {
        case 0: // method
                cur_ptr = ci_head(&s->req);
@@ -7895,6 +7898,9 @@ void http_set_status(unsigned int status, const char *reason, struct stream *s)
        const char *msg = reason;
        int msg_len;
 
+       if (IS_HTX_STRM(s))
+               return htx_res_set_status(status, reason, s);
+
        chunk_reset(&trash);
 
        res = ultoa_o(status, trash.area, trash.size);
index ef1fe2d0a5f72a20bf38f53c0383f09807740902..fda08d65529e945272e5999a92453c23702f469f 100644 (file)
@@ -2585,6 +2585,72 @@ static int htx_transform_header(struct stream* s, struct channel *chn, struct ht
        return ret;
 }
 
+/* This function executes one of the set-{method,path,query,uri} actions. It
+ * takes the string from the variable 'replace' with length 'len', then modifies
+ * the relevant part of the request line accordingly. Then it updates various
+ * pointers to the next elements which were moved, and the total buffer length.
+ * It finds the action to be performed in p[2], previously filled by function
+ * parse_set_req_line(). It returns 0 in case of success, -1 in case of internal
+ * error, though this can be revisited when this code is finally exploited.
+ *
+ * 'action' can be '0' to replace method, '1' to replace path, '2' to replace
+ * query string and 3 to replace uri.
+ *
+ * In query string case, the mark question '?' must be set at the start of the
+ * string by the caller, event if the replacement query string is empty.
+ */
+int htx_req_replace_stline(int action, const char *replace, int len,
+                          struct proxy *px, struct stream *s)
+{
+       struct htx *htx = htx_from_buf(&s->req.buf);
+
+       switch (action) {
+               case 0: // method
+                       if (!http_replace_req_meth(htx, ist2(replace, len)))
+                               return -1;
+                       break;
+
+               case 1: // path
+                       if (!http_replace_req_path(htx, ist2(replace, len)))
+                               return -1;
+                       break;
+
+               case 2: // query
+                       if (!http_replace_req_query(htx, ist2(replace, len)))
+                               return -1;
+                       break;
+
+               case 3: // uri
+                       if (!http_replace_req_uri(htx, ist2(replace, len)))
+                               return -1;
+                       break;
+
+               default:
+                       return -1;
+       }
+       return 0;
+}
+
+/* This function replace the HTTP status code and the associated message. The
+ * variable <status> contains the new status code. This function never fails.
+ */
+void htx_res_set_status(unsigned int status, const char *reason, struct stream *s)
+{
+       struct htx *htx = htx_from_buf(&s->res.buf);
+       char *res;
+
+       chunk_reset(&trash);
+       res = ultoa_o(status, trash.area, trash.size);
+       trash.data = res - trash.area;
+
+       /* Do we have a custom reason format string? */
+       if (reason == NULL)
+               reason = http_get_reason(status);
+
+       if (!http_replace_res_status(htx, ist2(trash.area, trash.data)))
+               http_replace_res_reason(htx, ist2(reason, strlen(reason)));
+}
+
 /* This function terminates the request because it was completly analyzed or
  * because an error was triggered during the body forwarding.
  */