Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
IPTV: add 'Remove HTTP arguments' for automatic network
The default value is 'ticket' for tvheadend linking.
  • Loading branch information
perexg committed Oct 13, 2015
1 parent 68b9892 commit 527b1fd
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/htsbuf.h
Expand Up @@ -60,6 +60,8 @@ void htsbuf_append_prealloc(htsbuf_queue_t *hq, const void *buf, size_t len);

void htsbuf_data_free(htsbuf_queue_t *hq, htsbuf_data_t *hd);

static inline int htsbuf_empty(htsbuf_queue_t *hq) { return hq->hq_size == 0; }

size_t htsbuf_read(htsbuf_queue_t *hq, void *buf, size_t len);

size_t htsbuf_peek(htsbuf_queue_t *hq, void *buf, size_t len);
Expand Down
8 changes: 4 additions & 4 deletions src/http.c
Expand Up @@ -640,7 +640,7 @@ http_cmd_get(http_connection_t *hc)
}

if(args != NULL)
http_parse_get_args(hc, args);
http_parse_args(&hc->hc_req_args, args);

return http_exec(hc, hp, remain);
}
Expand Down Expand Up @@ -694,7 +694,7 @@ http_cmd_post(http_connection_t *hc, htsbuf_queue_t *spill)
}

if(!strcmp(argv[0], "application/x-www-form-urlencoded"))
http_parse_get_args(hc, hc->hc_post_data);
http_parse_args(&hc->hc_req_args, hc->hc_post_data);
}

if (tvhtrace_enabled())
Expand Down Expand Up @@ -1008,7 +1008,7 @@ http_deescape(char *s)
* Parse arguments of a HTTP GET url, not perfect, but works for us
*/
void
http_parse_get_args(http_connection_t *hc, char *args)
http_parse_args(http_arg_list_t *list, char *args)
{
char *k, *v;

Expand All @@ -1028,7 +1028,7 @@ http_parse_get_args(http_connection_t *hc, char *args)
http_deescape(k);
http_deescape(v);
// printf("%s = %s\n", k, v);
http_arg_set(&hc->hc_req_args, k, v);
http_arg_set(list, k, v);
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/http.h
Expand Up @@ -180,6 +180,8 @@ char *http_arg_get_remove(struct http_arg_list *list, const char *name);

void http_arg_set(struct http_arg_list *list, const char *key, const char *val);

static inline int http_args_empty(const struct http_arg_list *list) { return TAILQ_EMPTY(list); }

int http_tokenize(char *buf, char **vec, int vecsize, int delimiter);

void http_error(http_connection_t *hc, int error);
Expand Down Expand Up @@ -236,7 +238,7 @@ int http_access_verify_channel(http_connection_t *hc, int mask,

void http_deescape(char *s);

void http_parse_get_args(http_connection_t *hc, char *args);
void http_parse_args(http_arg_list_t *list, char *args);

/*
* HTTP/RTSP Client
Expand Down
17 changes: 15 additions & 2 deletions src/input/mpegts/iptv/iptv.c
Expand Up @@ -483,7 +483,8 @@ iptv_input_mux_started ( iptv_mux_t *im )
static void
iptv_network_class_delete ( idnode_t *in )
{
mpegts_network_t *mn = (mpegts_network_t*)in;
iptv_network_t *mn = (iptv_network_t*)in;
char *s = mn->in_url;

if (in->in_class == &iptv_auto_network_class)
iptv_auto_network_done((iptv_network_t *)in);
Expand All @@ -493,7 +494,10 @@ iptv_network_class_delete ( idnode_t *in )
idnode_uuid_as_sstr(in));

/* delete */
mpegts_network_delete(mn, 1);
free(mn->in_remove_args);
mpegts_network_delete((mpegts_network_t *)mn, 1);

free(s);
}

extern const idclass_t mpegts_network_class;
Expand Down Expand Up @@ -568,6 +572,13 @@ const idclass_t iptv_auto_network_class = {
.name = N_("SSL verify peer"),
.off = offsetof(iptv_network_t, in_ssl_peer_verify),
},
{
.type = PT_STR,
.id = "remove_args",
.name = N_("Remove HTTP arguments"),
.off = offsetof(iptv_network_t, in_remove_args),
.def.s = "ticket"
},
{}
}
};
Expand Down Expand Up @@ -614,6 +625,8 @@ iptv_network_create0
/* Init Network */
in->in_priority = 1;
in->in_streaming_priority = 1;
if (idc == &iptv_auto_network_class)
in->in_remove_args = strdup("ticket");
if (!mpegts_network_create0((mpegts_network_t *)in, idc,
uuid, NULL, conf)) {
free(in);
Expand Down
68 changes: 64 additions & 4 deletions src/input/mpegts/iptv/iptv_auto.c
Expand Up @@ -29,20 +29,70 @@
*/
static void
iptv_auto_network_process_m3u_item(iptv_network_t *in,
const http_arg_list_t *remove_args,
const char *url, const char *name,
int *total, int *count)
{
htsmsg_t *conf;
mpegts_mux_t *mm;
iptv_mux_t *im;
url_t u;
int change;
http_arg_list_t args;
http_arg_t *ra1, *ra2, *ra2_next;
htsbuf_queue_t q;
size_t l = 0;
char url2[512];

if (url == NULL ||
(strncmp(url, "file://", 7) &&
strncmp(url, "http://", 7) &&
strncmp(url, "https://", 8)))
return;

memset(&u, 0, sizeof(u));
if (urlparse(url, &u))
return;
if (u.host == NULL || u.host[0] == '\0')
return;

/* remove requested arguments */
if (!http_args_empty(remove_args)) {
http_arg_init(&args);
http_parse_args(&args, u.query);
TAILQ_FOREACH(ra1, remove_args, link)
for (ra2 = TAILQ_FIRST(&args); ra2; ra2 = ra2_next) {
ra2_next = TAILQ_NEXT(ra2, link);
if (strcmp(ra1->key, ra2->key) == 0)
TAILQ_REMOVE(&args, ra2, link);
}
free(u.query);
u.query = NULL;
if (!http_args_empty(&args)) {
htsbuf_queue_init(&q, 0);
TAILQ_FOREACH(ra1, &args, link) {
if (!htsbuf_empty(&q))
htsbuf_append(&q, "&", 1);
htsbuf_append_and_escape_url(&q, ra1->key);
htsbuf_append(&q, "=", 1);
htsbuf_append_and_escape_url(&q, ra1->val);
}
free(u.query);
u.query = htsbuf_to_string(&q);
htsbuf_queue_flush(&q);
}
tvh_strlcatf(url2, sizeof(url2), l, "%s://", u.scheme);
if (u.user && u.user[0] && u.pass && u.pass[0])
tvh_strlcatf(url2, sizeof(url2), l, "%s:%s@", u.user, u.pass);
tvh_strlcatf(url2, sizeof(url2), l, "%s", u.host);
if (u.port > 0)
tvh_strlcatf(url2, sizeof(url2), l, ":%d", u.port);
tvh_strlcatf(url2, sizeof(url2), l, "%s", u.path);
if (u.query)
tvh_strlcatf(url2, sizeof(url2), l, "?%s", u.query);
url = url2;
}

LIST_FOREACH(mm, &in->mn_muxes, mm_network_link) {
im = (iptv_mux_t *)mm;
if (strcmp(im->mm_iptv_url ?: "", url) == 0) {
Expand Down Expand Up @@ -78,7 +128,8 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
*
*/
static int
iptv_auto_network_process_m3u(iptv_network_t *in, char *data)
iptv_auto_network_process_m3u(iptv_network_t *in, char *data,
http_arg_list_t *remove_args)
{
char *url, *name = NULL;
int total = 0, count = 0;
Expand All @@ -105,7 +156,7 @@ iptv_auto_network_process_m3u(iptv_network_t *in, char *data)
while (*data && *data != '\n') data++;
if (*data) { *data = '\0'; data++; }
if (*url)
iptv_auto_network_process_m3u_item(in, url, name, &total, &count);
iptv_auto_network_process_m3u_item(in, remove_args, url, name, &total, &count);
}

if (total == 0)
Expand All @@ -122,20 +173,29 @@ static int
iptv_auto_network_process(iptv_network_t *in, char *data, size_t len)
{
mpegts_mux_t *mm;
int r = -1, count;
int r = -1, count, n, i;
http_arg_list_t remove_args;
char *argv[10];

/* note that we know that data are terminated with '\0' */

if (data == NULL || len == 0)
return -1;

http_arg_init(&remove_args);
if (in->in_remove_args && in->in_remove_args) {
n = http_tokenize(in->in_remove_args, argv, ARRAY_SIZE(argv), -1);
for (i = 0; i < n; i++)
http_arg_set(&remove_args, argv[i], "1");
}

LIST_FOREACH(mm, &in->mn_muxes, mm_network_link)
((iptv_mux_t *)mm)->im_delete_flag = 1;

while (*data && *data <= ' ') data++;

if (!strncmp(data, "#EXTM3U", 7))
r = iptv_auto_network_process_m3u(in, data);
r = iptv_auto_network_process_m3u(in, data, &remove_args);

if (r == 0) {
count = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/input/mpegts/iptv/iptv_private.h
Expand Up @@ -81,9 +81,10 @@ struct iptv_network
uint32_t in_max_bandwidth;
uint32_t in_max_timeout;

char *in_url;
char *in_url;
uint32_t in_refetch_period;
int in_ssl_peer_verify;
char *in_remove_args;
gtimer_t in_auto_timer;
gtimer_t in_fetch_timer;
struct http_client *in_http_client;
Expand Down
2 changes: 1 addition & 1 deletion src/satip/rtsp.c
Expand Up @@ -274,7 +274,7 @@ rtsp_parse_args(http_connection_t *hc, char *u)
return -1;
u++;
}
http_parse_get_args(hc, u);
http_parse_args(&hc->hc_req_args, u);
return stream;
}

Expand Down

0 comments on commit 527b1fd

Please sign in to comment.