]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: http: move http_get_path() to http.c
authorWilly Tarreau <w@1wt.eu>
Mon, 10 Sep 2018 15:45:34 +0000 (17:45 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 11 Sep 2018 08:30:25 +0000 (10:30 +0200)
This function is purely HTTP once http_txn is put aside. So the original
one was renamed to http_txn_get_path() and it extracts the relevant offsets
from the txn to pass them to http_get_path(). One benefit of the new version
is that it returns the length at the same time so that allowed to slightly
simplify http_get_path_from_string() which had to look up the end pointer
previously and which is not needed anymore.

include/common/http.h
include/proto/proto_http.h
src/cache.c
src/hlua.c
src/http.c
src/proto_http.c

index d283e2977b357dc66a97d57a28220908781de25f..4184a47f9cc4e9998ecb98244e5af65a5c626714 100644 (file)
@@ -114,6 +114,7 @@ extern const char *HTTP_302;
 extern const char *HTTP_303;
 
 enum http_meth_t find_http_meth(const char *str, const int len);
+struct ist http_get_path(const struct ist uri);
 
 #endif /* _COMMON_HTTP_H */
 
index b537d45344eedd32c7b6a78ecea9c7b9554cd511..9eba1448d79b42e82c6cde1f3aaac783c708ef98 100644 (file)
@@ -100,7 +100,7 @@ void http_capture_bad_message(struct proxy *proxy, struct stream *s,
 unsigned int http_get_hdr(const struct http_msg *msg, const char *hname, int hlen,
                          struct hdr_idx *idx, int occ,
                          struct hdr_ctx *ctx, char **vptr, size_t *vlen);
-char *http_get_path(struct http_txn *txn);
+char *http_txn_get_path(const struct http_txn *txn);
 const char *get_reason(unsigned int status);
 
 struct http_txn *http_alloc_txn(struct stream *s);
index f58c3cc4ad4ddad09f69b226e6910925928290f5..3abb46cea98f42642f50239dddb99a76c71d8dfd 100644 (file)
@@ -650,7 +650,7 @@ int sha1_hosturi(struct http_txn *txn)
 
        /* now retrieve the path */
        end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
-       path = http_get_path(txn);
+       path = http_txn_get_path(txn);
        if (!path)
                return 0;
        chunk_strncat(trash, path, end - path);
index f07df4708d513a59cc2d66968ffddf7371f87e84..6f001d54df12dcec523857b1c1613030dab474d7 100644 (file)
@@ -3945,7 +3945,7 @@ static int hlua_applet_http_new(lua_State *L, struct appctx *ctx)
        lua_settable(L, -3);
 
        /* Get path and qs */
-       path = http_get_path(txn);
+       path = http_txn_get_path(txn);
        if (path) {
                end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
                p = path;
index ad620a9f22938e633fe32c1e0c29da209b205251..66a91dba776c7b2d2bfd26a99546baf448883abe 100644 (file)
@@ -183,3 +183,53 @@ enum http_meth_t find_http_meth(const char *str, const int len)
        else if (isteq(m, ist("TRACE")))   return HTTP_METH_TRACE;
        else                               return HTTP_METH_OTHER;
 }
+
+/* Parse the URI from the given transaction (which is assumed to be in request
+ * phase) and look for the "/" beginning the PATH. If not found, ist2(0,0) is
+ * returned. Otherwise the pointer and length are returned.
+ */
+struct ist http_get_path(const struct ist uri)
+{
+       const char *ptr, *end;
+
+       if (!uri.len)
+               goto not_found;
+
+       ptr = uri.ptr;
+       end = ptr + uri.len;
+
+       /* RFC7230, par. 2.7 :
+        * Request-URI = "*" | absuri | abspath | authority
+        */
+
+       if (*ptr == '*')
+               goto not_found;
+
+       if (isalpha((unsigned char)*ptr)) {
+               /* this is a scheme as described by RFC3986, par. 3.1 */
+               ptr++;
+               while (ptr < end &&
+                      (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
+                       ptr++;
+               /* skip '://' */
+               if (ptr == end || *ptr++ != ':')
+                       goto not_found;
+               if (ptr == end || *ptr++ != '/')
+                       goto not_found;
+               if (ptr == end || *ptr++ != '/')
+                       goto not_found;
+       }
+       /* skip [user[:passwd]@]host[:[port]] */
+
+       while (ptr < end && *ptr != '/')
+               ptr++;
+
+       if (ptr == end)
+               goto not_found;
+
+       /* OK, we got the '/' ! */
+       return ist2(ptr, end - ptr);
+
+ not_found:
+       return ist2(NULL, 0);
+}
index b153b141333731172437c7bfcbf0b0bfd4141b81..047e270df6b26d63b4a50dcee9107ed71ad9b057 100644 (file)
@@ -914,87 +914,13 @@ http_reply_and_close(struct stream *s, short status, struct buffer *msg)
  * phase) and look for the "/" beginning the PATH. If not found, return NULL.
  * It is returned otherwise.
  */
-char *http_get_path(struct http_txn *txn)
+char *http_txn_get_path(const struct http_txn *txn)
 {
-       char *ptr, *end;
-
-       ptr = ci_head(txn->req.chn) + txn->req.sl.rq.u;
-       end = ptr + txn->req.sl.rq.u_l;
-
-       if (ptr >= end)
-               return NULL;
-
-       /* RFC7230, par. 2.7 :
-        * Request-URI = "*" | absuri | abspath | authority
-        */
-
-       if (*ptr == '*')
-               return NULL;
-
-       if (isalpha((unsigned char)*ptr)) {
-               /* this is a scheme as described by RFC3986, par. 3.1 */
-               ptr++;
-               while (ptr < end &&
-                      (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
-                       ptr++;
-               /* skip '://' */
-               if (ptr == end || *ptr++ != ':')
-                       return NULL;
-               if (ptr == end || *ptr++ != '/')
-                       return NULL;
-               if (ptr == end || *ptr++ != '/')
-                       return NULL;
-       }
-       /* skip [user[:passwd]@]host[:[port]] */
-
-       while (ptr < end && *ptr != '/')
-               ptr++;
-
-       if (ptr == end)
-               return NULL;
-
-       /* OK, we got the '/' ! */
-       return ptr;
-}
+       struct ist ret;
 
-/* Parse the URI from the given string and look for the "/" beginning the PATH.
- * If not found, return NULL. It is returned otherwise.
- */
-static char *
-http_get_path_from_string(char *str)
-{
-       char *ptr = str;
-
-       /* RFC2616, par. 5.1.2 :
-        * Request-URI = "*" | absuri | abspath | authority
-        */
-
-       if (*ptr == '*')
-               return NULL;
-
-       if (isalpha((unsigned char)*ptr)) {
-               /* this is a scheme as described by RFC3986, par. 3.1 */
-               ptr++;
-               while (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.')
-                       ptr++;
-               /* skip '://' */
-               if (*ptr == '\0' || *ptr++ != ':')
-                       return NULL;
-               if (*ptr == '\0' || *ptr++ != '/')
-                       return NULL;
-               if (*ptr == '\0' || *ptr++ != '/')
-                       return NULL;
-       }
-       /* skip [user[:passwd]@]host[:[port]] */
+       ret = http_get_path(ist2(ci_head(txn->req.chn) + txn->req.sl.rq.u, txn->req.sl.rq.u_l));
 
-       while (*ptr != '\0' && *ptr != ' ' && *ptr != '/')
-               ptr++;
-
-       if (*ptr == '\0' || *ptr == ' ')
-               return NULL;
-
-       /* OK, we got the '/' ! */
-       return ptr;
+       return ret.ptr;
 }
 
 /* Returns a 302 for a redirectable request that reaches a server working in
@@ -1032,7 +958,7 @@ void http_perform_server_redirect(struct stream *s, struct stream_interface *si)
        txn = s->txn;
        c_rew(&s->req, rewind = http_hdr_rewind(&txn->req));
 
-       path = http_get_path(txn);
+       path = http_txn_get_path(txn);
        len = b_dist(&s->req.buf, path, c_ptr(&s->req, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
 
        c_adv(&s->req, rewind);
@@ -3159,7 +3085,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
                        hostlen = ctx.vlen;
                }
 
-               path = http_get_path(txn);
+               path = http_txn_get_path(txn);
                /* build message using path */
                if (path) {
                        pathlen = req->sl.rq.u_l + (ci_head(req->chn) + req->sl.rq.u) - path;
@@ -3226,7 +3152,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
                const char *path;
                int pathlen;
 
-               path = http_get_path(txn);
+               path = http_txn_get_path(txn);
                /* build message using path */
                if (path) {
                        pathlen = req->sl.rq.u_l + (ci_head(req->chn) + req->sl.rq.u) - path;
@@ -3718,7 +3644,7 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
                        return 0;
                }
 
-               path = http_get_path(txn);
+               path = http_txn_get_path(txn);
                if (url2sa(ci_head(req) + msg->sl.rq.u,
                           path ? path - (ci_head(req) + msg->sl.rq.u) : msg->sl.rq.u_l,
                           &conn->addr.to, NULL) == -1)
@@ -10323,7 +10249,7 @@ smp_fetch_path(const struct arg *args, struct sample *smp, const char *kw, void
 
        txn = smp->strm->txn;
        end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
-       ptr = http_get_path(txn);
+       ptr = http_txn_get_path(txn);
        if (!ptr)
                return 0;
 
@@ -10370,7 +10296,7 @@ smp_fetch_base(const struct arg *args, struct sample *smp, const char *kw, void
 
        /* now retrieve the path */
        end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
-       beg = http_get_path(txn);
+       beg = http_txn_get_path(txn);
        if (!beg)
                beg = end;
 
@@ -10417,7 +10343,7 @@ smp_fetch_base32(const struct arg *args, struct sample *smp, const char *kw, voi
 
        /* now retrieve the path */
        end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
-       beg = http_get_path(txn);
+       beg = http_txn_get_path(txn);
        if (!beg)
                beg = end;
 
@@ -10758,9 +10684,9 @@ smp_fetch_capture_req_method(const struct arg *args, struct sample *smp, const c
 static int
 smp_fetch_capture_req_uri(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct buffer *temp;
        struct http_txn *txn = smp->strm->txn;
-       char *ptr;
+       struct ist path;
+       const char *ptr;
 
        if (!txn || !txn->uri)
                return 0;
@@ -10775,15 +10701,12 @@ smp_fetch_capture_req_uri(const struct arg *args, struct sample *smp, const char
 
        ptr++;  /* skip the space */
 
-       temp = get_trash_chunk();
-       ptr = temp->area = http_get_path_from_string(ptr);
-       if (!ptr)
+       path = http_get_path(ist(ptr));
+       if (!path.ptr)
                return 0;
-       while (*ptr != ' ' && *ptr != '\0')  /* find space after URI */
-               ptr++;
 
-       smp->data.u.str = *temp;
-       smp->data.u.str.data = ptr - temp->area;
+       smp->data.u.str.area = path.ptr;
+       smp->data.u.str.data = path.len;
        smp->data.type = SMP_T_STR;
        smp->flags = SMP_F_CONST;
 
@@ -11467,7 +11390,7 @@ smp_fetch_url32(const struct arg *args, struct sample *smp, const char *kw, void
 
        /* now retrieve the path */
        end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
-       beg = http_get_path(txn);
+       beg = http_txn_get_path(txn);
        if (!beg)
                beg = end;
 
@@ -11895,7 +11818,7 @@ int http_replace_req_line(int action, const char *replace, int len,
                break;
 
        case 1: // path
-               cur_ptr = http_get_path(txn);
+               cur_ptr = http_txn_get_path(txn);
                if (!cur_ptr)
                        cur_ptr = ci_head(&s->req) + txn->req.sl.rq.u;