]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
IPTV: add 'Remove HTTP arguments' for automatic network
authorJaroslav Kysela <perex@perex.cz>
Tue, 13 Oct 2015 17:13:19 +0000 (19:13 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 13 Oct 2015 17:22:41 +0000 (19:22 +0200)
The default value is 'ticket' for tvheadend linking.

src/htsbuf.h
src/http.c
src/http.h
src/input/mpegts/iptv/iptv.c
src/input/mpegts/iptv/iptv_auto.c
src/input/mpegts/iptv/iptv_private.h
src/satip/rtsp.c

index 50c8d3ac8da439546067735bed6a1a22ccf394c2..0513955421b1afdce80a66b69310ccb043e01e65 100644 (file)
@@ -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);
index d132f13729197a37e3a487a88a1ac7807aaa63c9..370f1903e25bdd6820156adb4064e8e4026b033c 100644 (file)
@@ -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);
   }
 }
 
index e56546e5f6de166469c12ebf18116bb47255791d..0ccfa84e7bdf449cce2acf389d8d42996e294fc8 100644 (file)
@@ -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
index dfe78999a6a46c2edc533802eceb7d6efbae2187..95445d1ee12c3bc384c78dc8f1eb9a9bc5d8e623 100644 (file)
@@ -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);
index 6afa0c3708c84161a698a4f5071bebcf4f61ab03..929050fecbcf5d0767c5b87f62c14d0ee84bc0d4 100644 (file)
  */
 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;
index a7e16fab90fb466cec8b860295c8fdf020b5842d..ee8ad231fb05cba81a59d3e6892e08724e747f5a 100644 (file)
@@ -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;
index dd951724a4d668cf977448999df6a0d420bb73c7..1d284bbdb55346c8b53ffaf9392be9ae4e3065a1 100644 (file)
@@ -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;
 }