From: Jaroslav Kysela Date: Tue, 13 Oct 2015 17:13:19 +0000 (+0200) Subject: IPTV: add 'Remove HTTP arguments' for automatic network X-Git-Tag: v4.2.1~1924 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=527b1fdc833be336106d7cf1545432b244d3828e;p=thirdparty%2Ftvheadend.git IPTV: add 'Remove HTTP arguments' for automatic network The default value is 'ticket' for tvheadend linking. --- diff --git a/src/htsbuf.h b/src/htsbuf.h index 50c8d3ac8..051395542 100644 --- a/src/htsbuf.h +++ b/src/htsbuf.h @@ -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); diff --git a/src/http.c b/src/http.c index d132f1372..370f1903e 100644 --- a/src/http.c +++ b/src/http.c @@ -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); } @@ -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()) @@ -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; @@ -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); } } diff --git a/src/http.h b/src/http.h index e56546e5f..0ccfa84e7 100644 --- a/src/http.h +++ b/src/http.h @@ -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); @@ -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 diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index dfe78999a..95445d1ee 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -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); @@ -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; @@ -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" + }, {} } }; @@ -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); diff --git a/src/input/mpegts/iptv/iptv_auto.c b/src/input/mpegts/iptv/iptv_auto.c index 6afa0c370..929050fec 100644 --- a/src/input/mpegts/iptv/iptv_auto.c +++ b/src/input/mpegts/iptv/iptv_auto.c @@ -29,13 +29,20 @@ */ 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) && @@ -43,6 +50,49 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, 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) { @@ -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; @@ -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) @@ -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; diff --git a/src/input/mpegts/iptv/iptv_private.h b/src/input/mpegts/iptv/iptv_private.h index a7e16fab9..ee8ad231f 100644 --- a/src/input/mpegts/iptv/iptv_private.h +++ b/src/input/mpegts/iptv/iptv_private.h @@ -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; diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index dd951724a..1d284bbdb 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -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; }