From 60c220515f4099bcf2dd527179e614ad094a7809 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 10 Aug 2021 15:35:36 +0200 Subject: [PATCH] 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 (cherry picked from commit a12054991079cfb6c0f8b7484a8b8209be785cd2) [wt: context adj] Signed-off-by: Willy Tarreau --- include/haproxy/http.h | 1 + src/http.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/haproxy/http.h b/include/haproxy/http.h index fb47abd..7dea530 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_get_authority(const struct ist uri, int no_userinfo); struct ist http_get_path(const struct ist uri); int http_header_match2(const char *hdr, const char *end, diff --git a/src/http.c b/src/http.c index 22a5a14..6f78164 100644 --- a/src/http.c +++ b/src/http.c @@ -458,6 +458,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 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 -- 1.7.10.4