Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
IPTV: more improvements, leak fixes, better url parser for autonetwork
  • Loading branch information
perexg committed Oct 14, 2015
1 parent 403a432 commit 316edf1
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 64 deletions.
25 changes: 21 additions & 4 deletions src/input/mpegts/iptv/iptv.c
Expand Up @@ -464,8 +464,7 @@ void
iptv_input_mux_started ( iptv_mux_t *im )
{
/* Allocate input buffer */
sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
im->mm_iptv_rtp_seq = -1;
sbuf_reset_and_alloc(&im->mm_iptv_buffer, IPTV_BUF_SIZE);

if (iptv_input_fd_started(im))
return;
Expand All @@ -481,7 +480,8 @@ static void
iptv_network_delete ( mpegts_network_t *mn, int delconf )
{
iptv_network_t *in = (iptv_network_t*)mn;
char *s = in->in_url;
char *url = in->in_url;
char *sane_url = in->in_url_sane;

if (in->mn_id.in_class == &iptv_auto_network_class)
iptv_auto_network_done(in);
Expand All @@ -495,7 +495,8 @@ iptv_network_delete ( mpegts_network_t *mn, int delconf )
free(in->in_remove_args);
mpegts_network_delete(mn, delconf);

free(s);
free(sane_url);
free(url);
}

/* **************************************************************************
Expand Down Expand Up @@ -556,6 +557,19 @@ const idclass_t iptv_network_class = {
}
};

static int
iptv_auto_network_class_url_set( void *in, const void *v )
{
iptv_network_t *mn = in;
return iptv_url_set(&mn->in_url, &mn->in_url_sane, v, 1, 0);
}

static void
iptv_auto_network_class_notify_url( void *in, const char *lang )
{
iptv_auto_network_trigger(in);
}

const idclass_t iptv_auto_network_class = {
.ic_super = &iptv_network_class,
.ic_class = "iptv_auto_network",
Expand All @@ -566,6 +580,9 @@ const idclass_t iptv_auto_network_class = {
.id = "url",
.name = N_("URL"),
.off = offsetof(iptv_network_t, in_url),
.set = iptv_auto_network_class_url_set,
.notify = iptv_auto_network_class_notify_url,
.opts = PO_MULTILINE
},
{
.type = PT_S64,
Expand Down
26 changes: 19 additions & 7 deletions src/input/mpegts/iptv/iptv_auto.c
Expand Up @@ -369,9 +369,12 @@ iptv_auto_network_fetch(void *aux)

memset(&u, 0, sizeof(u));

if (in->in_url == NULL)
goto done;

if (strncmp(in->in_url, "file://", 7) == 0) {
iptv_auto_network_file(in, in->in_url + 7);
goto arm;
goto done;
}

gtimer_disarm(&in->in_auto_timer);
Expand All @@ -382,12 +385,12 @@ iptv_auto_network_fetch(void *aux)

if (urlparse(in->in_url, &u) < 0) {
tvherror("iptv", "wrong url for network '%s'", in->mn_network_name);
goto arm;
goto done;
}
hc = http_client_connect(in, HTTP_VERSION_1_1, u.scheme, u.host, u.port, NULL);
if (hc == NULL) {
tvherror("iptv", "unable to open http client for network '%s'", in->mn_network_name);
goto arm;
goto done;
}
hc->hc_handle_location = 1;
hc->hc_data_limit = 1024*1024;
Expand All @@ -397,26 +400,35 @@ iptv_auto_network_fetch(void *aux)
if (http_client_simple(hc, &u) < 0) {
http_client_close(hc);
tvherror("iptv", "unable to send http command for network '%s'", in->mn_network_name);
goto arm;
goto done;
}

in->in_http_client = hc;

arm:
urlreset(&u);
gtimer_arm(&in->in_auto_timer, iptv_auto_network_fetch, in,
MAX(1, in->in_refetch_period) * 60);
done:
urlreset(&u);
}

/*
*
*/
void
iptv_auto_network_init( iptv_network_t *in )
iptv_auto_network_trigger( iptv_network_t *in )
{
gtimer_arm(&in->in_auto_timer, iptv_auto_network_fetch, in, 0);
}

/*
*
*/
void
iptv_auto_network_init( iptv_network_t *in )
{
iptv_auto_network_trigger(in);
}

/*
*
*/
Expand Down
7 changes: 5 additions & 2 deletions src/input/mpegts/iptv/iptv_http.c
Expand Up @@ -67,10 +67,11 @@ iptv_http_header ( http_client_t *hc )
s = http_arg_get(&hc->hc_args, "Content-Type");
if (s) {
n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';');
printf("mime: '%s'\n", s);
if (n > 0 &&
(strcasecmp(s, "audio/mpegurl") == 0 ||
strcasecmp(s, "audio/x-mpegurl") == 0)) {
strcasecmp(s, "audio/x-mpegurl") == 0 ||
strcasecmp(s, "application/apple.vnd.mpegurl") == 0 ||
strcasecmp(s, "application/vnd.apple.mpegurl") == 0)) {
if (im->im_m3u_header > 10) {
im->im_m3u_header = 0;
return 0;
Expand Down Expand Up @@ -133,6 +134,7 @@ iptv_http_complete
im->im_m3u_header = 0;
sbuf_append(&im->mm_iptv_buffer, "", 1);
url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data);
sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE);
if (url == NULL) {
tvherror("iptv", "m3u contents parsing failed");
return 0;
Expand Down Expand Up @@ -178,6 +180,7 @@ iptv_http_start
return SM_CODE_TUNING_FAILED;
}
im->im_data = hc;
sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_BUF_SIZE);

return 0;
}
Expand Down
112 changes: 61 additions & 51 deletions src/input/mpegts/iptv/iptv_mux.c
Expand Up @@ -27,65 +27,73 @@
extern const idclass_t mpegts_mux_class;
extern const idclass_t mpegts_mux_instance_class;

static int
iptv_mux_url_set ( void *p, const void *v )
static inline void
iptv_url_set0 ( char **url, char **sane_url,
const char *url1, const char *sane_url1 )
{
iptv_mux_t *im = p;
const char *str = v, *x;
free(*url);
free(*sane_url);
*url = url1 ? strdup(url1) : NULL;
*sane_url = sane_url1 ? strdup(sane_url1) : NULL;
}

int
iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe )
{
const char *x;
char *buf, port[16] = "";
size_t len;
url_t url;
url_t u;

if (strcmp(str ?: "", im->mm_iptv_url ?: "")) {
if (str == NULL || *str == '\0') {
free(im->mm_iptv_url);
free(im->mm_iptv_url_sane);
im->mm_iptv_url = NULL;
im->mm_iptv_url_sane = NULL;
return 1;
}
if (!strncmp(str, "pipe://", 7)) {
x = str + strlen(str);
while (x != str && *x <= ' ')
x--;
((char *)x)[1] = '\0';
free(im->mm_iptv_url);
free(im->mm_iptv_url_sane);
im->mm_iptv_url = strdup(str);
im->mm_iptv_url_sane = strdup(str);
return 1;
}
memset(&url, 0, sizeof(url));
if (!urlparse(str, &url)) {
free(im->mm_iptv_url);
free(im->mm_iptv_url_sane);
im->mm_iptv_url = strdup(str);
if (im->mm_iptv_url) {
len = (url.scheme ? strlen(url.scheme) + 3 : 0) +
(url.host ? strlen(url.host) + 1 : 0) +
/* port */ 16 +
(url.path ? strlen(url.path) + 1 : 0) +
(url.query ? strlen(url.query) + 2 : 0);
buf = alloca(len);
if (url.port > 0 && url.port <= 65535)
snprintf(port, sizeof(port), ":%d", url.port);
snprintf(buf, len, "%s%s%s%s%s%s%s",
url.scheme ?: "", url.scheme ? "://" : "",
url.host ?: "", port,
url.path ?: "", url.query ? "?" : "",
url.query ?: "");
im->mm_iptv_url_sane = strdup(buf);
} else {
im->mm_iptv_url_sane = NULL;
}
urlreset(&url);
return 1;
}
urlreset(&url);
if (strcmp(str ?: "", *url ?: "") == 0)
return 0;

if (str == NULL || *str == '\0') {
iptv_url_set0(url, sane_url, NULL, NULL);
return 1;
}
if (allow_file && !strncmp(str, "file://", 7)) {
iptv_url_set0(url, sane_url, str, str);
return 1;
}
if (allow_pipe && !strncmp(str, "pipe://", 7)) {
x = str + strlen(str);
while (x != str && *x <= ' ')
x--;
((char *)x)[1] = '\0';
iptv_url_set0(url, sane_url, str, str);
return 1;
}
memset(&u, 0, sizeof(u));
if (!urlparse(str, &u)) {
len = (u.scheme ? strlen(u.scheme) + 3 : 0) +
(u.host ? strlen(u.host) + 1 : 0) +
/* port */ 16 +
(u.path ? strlen(u.path) + 1 : 0) +
(u.query ? strlen(u.query) + 2 : 0);
buf = alloca(len);
if (u.port > 0 && u.port <= 65535)
snprintf(port, sizeof(port), ":%d", u.port);
snprintf(buf, len, "%s%s%s%s%s%s%s",
u.scheme ?: "", u.scheme ? "://" : "",
u.host ?: "", port,
u.path ?: "", (u.query && u.query[0]) ? "?" : "",
u.query ?: "");
iptv_url_set0(url, sane_url, str, buf);
urlreset(&u);
return 1;
}

return 0;
}

static int
iptv_mux_url_set ( void *p, const void *v )
{
iptv_mux_t *im = p;
return iptv_url_set(&im->mm_iptv_url, &im->mm_iptv_url_sane, v, 0, 1);
}

static htsmsg_t *
iptv_muxdvr_class_kill_list ( void *o, const char *lang )
{
Expand Down Expand Up @@ -276,6 +284,8 @@ iptv_mux_create0 ( iptv_network_t *in, const char *uuid, htsmsg_t *conf )
if (!im->mm_iptv_kill_timeout)
im->mm_iptv_kill_timeout = 5;

sbuf_init(&im->mm_iptv_buffer);

/* Create Instance */
(void)mpegts_mux_instance_create(mpegts_mux_instance, NULL,
(mpegts_input_t*)iptv_input,
Expand Down
4 changes: 4 additions & 0 deletions src/input/mpegts/iptv/iptv_private.h
Expand Up @@ -82,6 +82,7 @@ struct iptv_network
uint32_t in_max_timeout;

char *in_url;
char *in_url_sane;
int64_t in_channel_number;
uint32_t in_refetch_period;
int in_ssl_peer_verify;
Expand Down Expand Up @@ -152,8 +153,11 @@ extern const idclass_t iptv_auto_network_class;
extern iptv_input_t *iptv_input;
extern iptv_network_t *iptv_network;

int iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe );

void iptv_mux_load_all ( void );

void iptv_auto_network_trigger( iptv_network_t *in );
void iptv_auto_network_init( iptv_network_t *in );
void iptv_auto_network_done( iptv_network_t *in );

Expand Down

0 comments on commit 316edf1

Please sign in to comment.