rtmp: handle both IPv4 and IPv6 uris (#166)

This commit is contained in:
Alfred E. Heggestad 2018-11-01 11:09:02 +01:00 committed by Richard Aas
parent 41e771a972
commit 05a23595cc
3 changed files with 21 additions and 6 deletions

View file

@ -23,6 +23,8 @@ typedef int (uri_apply_h)(const struct pl *name, const struct pl *val,
struct re_printf; struct re_printf;
int uri_encode(struct re_printf *pf, const struct uri *uri); int uri_encode(struct re_printf *pf, const struct uri *uri);
int uri_decode(struct uri *uri, const struct pl *pl); 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, int uri_param_get(const struct pl *pl, const struct pl *pname,
struct pl *pvalue); struct pl *pvalue);
int uri_params_apply(const struct pl *pl, uri_apply_h *ah, void *arg); int uri_params_apply(const struct pl *pl, uri_apply_h *ah, void *arg);

View file

@ -15,6 +15,7 @@
#include <re_sys.h> #include <re_sys.h>
#include <re_odict.h> #include <re_odict.h>
#include <re_dns.h> #include <re_dns.h>
#include <re_uri.h>
#include <re_rtmp.h> #include <re_rtmp.h>
#include "rtmp.h" #include "rtmp.h"
@ -773,12 +774,14 @@ static void query_handler(int err, const struct dnshdr *hdr, struct list *ansl,
* Example URIs: * Example URIs:
* *
* rtmp://a.rtmp.youtube.com/live2/my-stream * 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, int rtmp_connect(struct rtmp_conn **connp, struct dnsc *dnsc, const char *uri,
rtmp_estab_h *estabh, rtmp_command_h *cmdh, rtmp_estab_h *estabh, rtmp_command_h *cmdh,
rtmp_close_h *closeh, void *arg) rtmp_close_h *closeh, void *arg)
{ {
struct rtmp_conn *conn; struct rtmp_conn *conn;
struct pl pl_hostport;
struct pl pl_host; struct pl pl_host;
struct pl pl_port; struct pl pl_port;
struct pl pl_app; struct pl pl_app;
@ -788,8 +791,11 @@ int rtmp_connect(struct rtmp_conn **connp, struct dnsc *dnsc, const char *uri,
if (!connp || !uri) if (!connp || !uri)
return EINVAL; return EINVAL;
if (re_regex(uri, strlen(uri), "rtmp://[^:/]+[:]*[0-9]*/[^/]+/[^]+", if (re_regex(uri, strlen(uri), "rtmp://[^/]+/[^/]+/[^]+",
&pl_host, NULL, &pl_port, &pl_app, &pl_stream)) &pl_hostport, &pl_app, &pl_stream))
return EINVAL;
if (uri_decode_hostport(&pl_hostport, &pl_host, &pl_port))
return EINVAL; return EINVAL;
conn = rtmp_conn_alloc(true, estabh, cmdh, closeh, arg); conn = rtmp_conn_alloc(true, estabh, cmdh, closeh, arg);

View file

@ -74,11 +74,18 @@ int uri_encode(struct re_printf *pf, const struct uri *uri)
/** /**
* Decode host-port portion of a URI (if present) * 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 * @return 0 if success, otherwise errorcode
*/ */
static int decode_hostport(const struct pl *hostport, struct pl *host, int uri_decode_hostport(const struct pl *hostport, struct pl *host,
struct pl *port) struct pl *port)
{ {
if (!hostport || !host || !port)
return EINVAL;
/* Try IPv6 first */ /* Try IPv6 first */
if (!re_regex(hostport->p, hostport->l, "\\[[0-9a-f:]+\\][:]*[0-9]*", if (!re_regex(hostport->p, hostport->l, "\\[[0-9a-f:]+\\][:]*[0-9]*",
host, NULL, port)) host, NULL, port))
@ -114,7 +121,7 @@ int uri_decode(struct uri *uri, const struct pl *pl)
&uri->scheme, &uri->user, NULL, &uri->password, &uri->scheme, &uri->user, NULL, &uri->password,
&hostport, &uri->params, &uri->headers)) { &hostport, &uri->params, &uri->headers)) {
if (0 == decode_hostport(&hostport, &uri->host, &port)) if (0 == uri_decode_hostport(&hostport, &uri->host, &port))
goto out; goto out;
} }
@ -122,7 +129,7 @@ int uri_decode(struct uri *uri, const struct pl *pl)
err = re_regex(pl->p, pl->l, "[^:]+:[^;? ]+[^?]*[^]*", err = re_regex(pl->p, pl->l, "[^:]+:[^;? ]+[^?]*[^]*",
&uri->scheme, &hostport, &uri->params, &uri->headers); &uri->scheme, &hostport, &uri->params, &uri->headers);
if (0 == err) { if (0 == err) {
err = decode_hostport(&hostport, &uri->host, &port); err = uri_decode_hostport(&hostport, &uri->host, &port);
if (0 == err) if (0 == err)
goto out; goto out;
} }