REORG: http: move http_get_path() to http.c

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.
diff --git a/include/common/http.h b/include/common/http.h
index d283e29..4184a47 100644
--- a/include/common/http.h
+++ b/include/common/http.h
@@ -114,6 +114,7 @@
 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 */
 
diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h
index b537d45..9eba144 100644
--- a/include/proto/proto_http.h
+++ b/include/proto/proto_http.h
@@ -100,7 +100,7 @@
 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);
diff --git a/src/cache.c b/src/cache.c
index f58c3cc..3abb46c 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -650,7 +650,7 @@
 
 	/* 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);
diff --git a/src/hlua.c b/src/hlua.c
index f07df47..6f001d5 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -3945,7 +3945,7 @@
 	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;
diff --git a/src/http.c b/src/http.c
index ad620a9..66a91db 100644
--- a/src/http.c
+++ b/src/http.c
@@ -183,3 +183,53 @@
 	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);
+}
diff --git a/src/proto_http.c b/src/proto_http.c
index b153b14..047e270 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -914,87 +914,13 @@
  * 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 @@
 	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 @@
 			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 @@
 		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 @@
 			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 @@
 
 	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 @@
 
 	/* 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 @@
 
 	/* 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 @@
 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 @@
 
 	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 @@
 
 	/* 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 @@
 		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;