summaryrefslogtreecommitdiffstats
path: root/src/plugins/http/http.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/http/http.h')
-rw-r--r--src/plugins/http/http.h108
1 files changed, 87 insertions, 21 deletions
diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h
index 13118bfde06..04c53d15ecb 100644
--- a/src/plugins/http/http.h
+++ b/src/plugins/http/http.h
@@ -522,18 +522,19 @@ http_validate_query_syntax (u8 *query, int *is_encoded)
* Decode percent-encoded data.
*
* @param src Data to decode.
+ * @param len Length of data to decode.
*
* @return New vector with decoded data.
*
* The caller is always responsible to free the returned vector.
*/
always_inline u8 *
-http_percent_decode (u8 *src)
+http_percent_decode (u8 *src, u32 len)
{
- int i;
+ u32 i;
u8 *decoded_uri = 0;
- for (i = 0; i < vec_len (src); i++)
+ for (i = 0; i < len; i++)
{
if (src[i] == '%')
{
@@ -995,6 +996,31 @@ typedef struct
u8 host_is_ip6;
} http_url_t;
+always_inline int
+_parse_port (u8 **pos, u8 *end, u16 *port)
+{
+ u32 value = 0;
+ u8 *p = *pos;
+
+ if (!isdigit (*p))
+ return -1;
+ value = *p - '0';
+ p++;
+
+ while (p != end)
+ {
+ if (!isdigit (*p))
+ break;
+ value = value * 10 + *p - '0';
+ if (value > CLIB_U16_MAX)
+ return -1;
+ p++;
+ }
+ *pos = p;
+ *port = clib_host_to_net_u16 ((u16) value);
+ return 0;
+}
+
/**
* An "absolute-form" URL parsing.
*
@@ -1102,27 +1128,12 @@ http_parse_absolute_form (u8 *url, http_url_t *parsed)
/* parse port, if any */
if (token_start != end && *token_start == ':')
{
- u32 port = 0;
token_end = ++token_start;
- while (token_end != end && *token_end != '/')
+ if (_parse_port (&token_end, end, &parsed->port))
{
- if (isdigit (*token_end))
- {
- port = port * 10 + *token_end - '0';
- if (port > 65535)
- {
- clib_warning ("invalid port number");
- return -1;
- }
- }
- else
- {
- clib_warning ("expected digit '%u'", *token_end);
- return -1;
- }
- token_end++;
+ clib_warning ("invalid port");
+ return -1;
}
- parsed->port = clib_host_to_net_u16 ((u16) port);
token_start = token_end;
}
@@ -1140,6 +1151,61 @@ http_parse_absolute_form (u8 *url, http_url_t *parsed)
return 0;
}
+/**
+ * Parse target host and port of UDP tunnel over HTTP.
+ *
+ * @param path Path in format "{target_host}/{target_port}/".
+ * @param path_len Length of given path.
+ * @param parsed Parsed target in case of success..
+ *
+ * @return @c 0 on success.
+ *
+ * @note Only IPv4 literals and IPv6 literals supported.
+ */
+always_inline int
+http_parse_masque_host_port (u8 *path, u32 path_len, http_uri_t *parsed)
+{
+ u8 *p, *end, *decoded_host;
+ u32 host_len;
+ unformat_input_t input;
+
+ p = path;
+ end = path + path_len;
+ clib_memset (parsed, 0, sizeof (*parsed));
+
+ while (p != end && *p != '/')
+ p++;
+
+ host_len = p - path;
+ if (!host_len || (host_len == path_len) || (host_len + 1 == path_len))
+ return -1;
+ decoded_host = http_percent_decode (path, host_len);
+ unformat_init_vector (&input, decoded_host);
+ if (unformat (&input, "%U", unformat_ip4_address, &parsed->ip.ip4))
+ parsed->is_ip4 = 1;
+ else if (unformat (&input, "%U", unformat_ip6_address, &parsed->ip.ip6))
+ parsed->is_ip4 = 0;
+ else
+ {
+ unformat_free (&input);
+ clib_warning ("unsupported target_host format");
+ return -1;
+ }
+ unformat_free (&input);
+
+ p++;
+ if (_parse_port (&p, end, &parsed->port))
+ {
+ clib_warning ("invalid port");
+ return -1;
+ }
+
+ if (p == end || *p != '/')
+ return -1;
+
+ return 0;
+}
+
#endif /* SRC_PLUGINS_HTTP_HTTP_H_ */
/*