diff --git a/include/re_uri.h b/include/re_uri.h index 20efa8b..d323e5c 100644 --- a/include/re_uri.h +++ b/include/re_uri.h @@ -23,6 +23,8 @@ typedef int (uri_apply_h)(const struct pl *name, const struct pl *val, struct re_printf; int uri_encode(struct re_printf *pf, const struct uri *uri); int uri_decode(struct uri *uri, const struct pl *pl); +int uri_decode_hostport(const struct pl *hostport, struct pl *host, + struct pl *port); int uri_param_get(const struct pl *pl, const struct pl *pname, struct pl *pvalue); int uri_params_apply(const struct pl *pl, uri_apply_h *ah, void *arg); diff --git a/src/rtmp/conn.c b/src/rtmp/conn.c index d92554f..1ea7758 100644 --- a/src/rtmp/conn.c +++ b/src/rtmp/conn.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "rtmp.h" @@ -773,12 +774,14 @@ static void query_handler(int err, const struct dnshdr *hdr, struct list *ansl, * Example URIs: * * rtmp://a.rtmp.youtube.com/live2/my-stream + * rtmp://[::1]/vod/mp4:sample.mp4 */ int rtmp_connect(struct rtmp_conn **connp, struct dnsc *dnsc, const char *uri, rtmp_estab_h *estabh, rtmp_command_h *cmdh, rtmp_close_h *closeh, void *arg) { struct rtmp_conn *conn; + struct pl pl_hostport; struct pl pl_host; struct pl pl_port; struct pl pl_app; @@ -788,8 +791,11 @@ int rtmp_connect(struct rtmp_conn **connp, struct dnsc *dnsc, const char *uri, if (!connp || !uri) return EINVAL; - if (re_regex(uri, strlen(uri), "rtmp://[^:/]+[:]*[0-9]*/[^/]+/[^]+", - &pl_host, NULL, &pl_port, &pl_app, &pl_stream)) + if (re_regex(uri, strlen(uri), "rtmp://[^/]+/[^/]+/[^]+", + &pl_hostport, &pl_app, &pl_stream)) + return EINVAL; + + if (uri_decode_hostport(&pl_hostport, &pl_host, &pl_port)) return EINVAL; conn = rtmp_conn_alloc(true, estabh, cmdh, closeh, arg); diff --git a/src/uri/uri.c b/src/uri/uri.c index 433c34e..5409463 100644 --- a/src/uri/uri.c +++ b/src/uri/uri.c @@ -74,11 +74,18 @@ int uri_encode(struct re_printf *pf, const struct uri *uri) /** * Decode host-port portion of a URI (if present) * + * @param hostport Host and port input string + * @param host Decoded host portion + * @param port Decoded port portion + * * @return 0 if success, otherwise errorcode */ -static int decode_hostport(const struct pl *hostport, struct pl *host, - struct pl *port) +int uri_decode_hostport(const struct pl *hostport, struct pl *host, + struct pl *port) { + if (!hostport || !host || !port) + return EINVAL; + /* Try IPv6 first */ if (!re_regex(hostport->p, hostport->l, "\\[[0-9a-f:]+\\][:]*[0-9]*", host, NULL, port)) @@ -114,7 +121,7 @@ int uri_decode(struct uri *uri, const struct pl *pl) &uri->scheme, &uri->user, NULL, &uri->password, &hostport, &uri->params, &uri->headers)) { - if (0 == decode_hostport(&hostport, &uri->host, &port)) + if (0 == uri_decode_hostport(&hostport, &uri->host, &port)) goto out; } @@ -122,7 +129,7 @@ int uri_decode(struct uri *uri, const struct pl *pl) err = re_regex(pl->p, pl->l, "[^:]+:[^;? ]+[^?]*[^]*", &uri->scheme, &hostport, &uri->params, &uri->headers); if (0 == err) { - err = decode_hostport(&hostport, &uri->host, &port); + err = uri_decode_hostport(&hostport, &uri->host, &port); if (0 == err) goto out; }