MINOR: http: implement http_get_scheme

This method can be used to retrieve the scheme part of an uri, with the
suffix '://'. It will be useful to implement scheme-based normalization.

(cherry picked from commit ef08811240fb117b6a8072c346f7136e7dd65220)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/http.c b/src/http.c
index 689069c..aff27f1 100644
--- a/src/http.c
+++ b/src/http.c
@@ -468,6 +468,56 @@
 	}
 }
 
+/* Parse the uri and looks for the scheme. If not found, an empty ist is
+ * returned. Otherwise, the ist pointing to the scheme is returned.
+ */
+struct ist http_get_scheme(const struct ist uri)
+{
+	const char *ptr, *start, *end;
+
+	if (!uri.len)
+		goto not_found;
+
+	ptr = uri.ptr;
+	start = ptr;
+	end = ptr + uri.len;
+
+	/* RFC7230, par. 2.7 :
+	 * Request-URI = "*" | absuri | abspath | authority
+	 */
+
+	if (*ptr == '*' || *ptr == '/')
+		goto not_found;
+
+	if (isalpha((unsigned char)*ptr)) {
+		/* this is a scheme as described by RFC3986, par. 3.1, or only
+		 * an authority (in case of a CONNECT method).
+		 */
+		ptr++;
+		/* retrieve the scheme up to the suffix '://'. If the suffix is
+		 * not found, this means there is no scheme and it is an
+		 * authority-only uri.
+		 */
+		while (ptr < end &&
+		       (isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
+			ptr++;
+		if (ptr == end || *ptr++ != ':')
+			goto not_found;
+		if (ptr == end || *ptr++ != '/')
+			goto not_found;
+		if (ptr == end || *ptr++ != '/')
+			goto not_found;
+	}
+	else {
+		goto not_found;
+	}
+
+	return ist2(start, ptr - start);
+
+ not_found:
+	return IST_NULL;
+}
+
 /* Parse the uri and looks for the authority, between the scheme and the
  * path. if no_userinfo is not zero, the part before the '@' (including it) is
  * skipped. If not found, an empty ist is returned. Otherwise, the ist pointing