diff --git a/include/haproxy/http.h b/include/haproxy/http.h index 150ebdb7f..a213f5bfd 100644 --- a/include/haproxy/http.h +++ b/include/haproxy/http.h @@ -36,6 +36,7 @@ extern const uint8_t http_char_classes[256]; 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_parse_scheme(struct http_uri_parser *parser); struct ist http_parse_authority(struct http_uri_parser *parser, int no_userinfo); struct ist http_parse_path(struct http_uri_parser *parser); diff --git a/src/http.c b/src/http.c index 75c899d77..0d6e92d91 100644 --- a/src/http.c +++ b/src/http.c @@ -468,6 +468,29 @@ const char *http_get_reason(unsigned int status) } } +/* Returns non-zero if the scheme 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. *