MINOR: http: add a new function http_validate_scheme() to validate a scheme
While http_parse_scheme() extracts a scheme from a URI by extracting
exactly the valid characters and stopping on delimiters, this new
function performs the same on a fixed-size string.
(cherry picked from commit d3d8d03d98c6624c8b15b81f7b80dd22fc3f9fd2)
[wt: context adj]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/include/haproxy/http.h b/include/haproxy/http.h
index 991eece..d0f3fd2 100644
--- a/include/haproxy/http.h
+++ b/include/haproxy/http.h
@@ -36,6 +36,7 @@
enum http_meth_t find_http_meth(const char *str, const int len);
int http_get_status_idx(unsigned int status);
const char *http_get_reason(unsigned int status);
+int http_validate_scheme(const struct ist schm);
struct ist http_get_scheme(const struct ist uri);
struct ist http_get_authority(const struct ist uri, int no_userinfo);
struct ist http_get_path(const struct ist uri);
diff --git a/src/http.c b/src/http.c
index aff27f1..0b00e47 100644
--- a/src/http.c
+++ b/src/http.c
@@ -468,6 +468,29 @@
}
}
+/* Returns non-zero if the scheme <schm> is syntactically correct according to
+ * RFC3986#3.1, otherwise zero. It expects only the scheme and nothing else
+ * (particularly not the following "://").
+ * Scheme = alpha *(alpha|digit|'+'|'-'|'.')
+ */
+int http_validate_scheme(const struct ist schm)
+{
+ size_t i;
+
+ for (i = 0; i < schm.len; i++) {
+ if (likely((schm.ptr[i] >= 'a' && schm.ptr[i] <= 'z') ||
+ (schm.ptr[i] >= 'A' && schm.ptr[i] <= 'Z')))
+ continue;
+ if (unlikely(!i)) // first char must be alpha
+ return 0;
+ if ((schm.ptr[i] >= '0' && schm.ptr[i] <= '9') ||
+ schm.ptr[i] == '+' || schm.ptr[i] == '-' || schm.ptr[i] == '.')
+ continue;
+ return 0;
+ }
+ return !!i;
+}
+
/* 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.
*/