]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
IPTV: allow custom HTTP headers for muxes, fixes #3182
authorJaroslav Kysela <perex@perex.cz>
Thu, 29 Oct 2015 16:13:25 +0000 (17:13 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 29 Oct 2015 16:13:25 +0000 (17:13 +0100)
src/http.h
src/httpc.c
src/input/mpegts/iptv/iptv_http.c
src/input/mpegts/iptv/iptv_mux.c
src/input/mpegts/iptv/iptv_private.h

index 2c4134bfb9f4fdb3cc81e732d4d5952f3d8c20a7..d21c0edc8ea026606413d13b1f54d7720c6f7fe8 100644 (file)
@@ -342,6 +342,8 @@ struct http_client {
   gtimer_t     hc_close_timer;
 
   /* callbacks */
+  void    (*hc_hdr_create)   (http_client_t *hc, http_arg_list_t *h,
+                              const url_t *url, int keepalive);
   int     (*hc_hdr_received) (http_client_t *hc);
   int     (*hc_data_received)(http_client_t *hc, void *buf, size_t len);
   int     (*hc_data_complete)(http_client_t *hc);
@@ -364,6 +366,10 @@ int http_client_send( http_client_t *hc, http_cmd_t cmd,
                       http_arg_list_t *header, void *body, size_t body_size );
 void http_client_basic_auth( http_client_t *hc, http_arg_list_t *h,
                              const char *user, const char *pass );
+void http_client_basic_args ( http_client_t *hc, http_arg_list_t *h,
+                              const url_t *url, int keepalive );
+void http_client_add_args ( http_client_t *hc, http_arg_list_t *h,
+                            const char *args );
 int http_client_simple_reconnect ( http_client_t *hc, const url_t *u, http_ver_t ver );
 int http_client_simple( http_client_t *hc, const url_t *url);
 int http_client_clear_state( http_client_t *hc );
index 72fcd931b43d0520a217b3f07c328e0f48d4fde8..4db8fa2c20e60092d9f1837f180ae8b93e4a0232 100644 (file)
@@ -1117,7 +1117,7 @@ http_client_basic_auth( http_client_t *hc, http_arg_list_t *h,
 /*
  * Redirected
  */
-static void
+void
 http_client_basic_args ( http_client_t *hc, http_arg_list_t *h, const url_t *url, int keepalive )
 {
   char buf[256];
@@ -1141,8 +1141,47 @@ http_client_basic_args ( http_client_t *hc, http_arg_list_t *h, const url_t *url
   http_client_basic_auth(hc, h, url->user, url->pass);
 }
 
+static char *
+strstrip(char *s)
+{
+  size_t l;
+  if (s != NULL) {
+    while (*s && *s <= ' ') s++;
+    l = *s ? 0 : strlen(s) - 1;
+    while (*s && s[l] <= ' ') s[l--] = '\0';
+  }
+  return s;
+}
+
+void
+http_client_add_args ( http_client_t *hc, http_arg_list_t *h, const char *args )
+{
+  char *p, *k, *v;
+
+  if (args == NULL)
+    return;
+  p = strdupa(args);
+  while (*p) {
+    while (*p && *p <= ' ') p++;
+    if (*p == '\0') break;
+    k = p;
+    while (*p && *p != '\r' && *p != '\n' && *p != ':' && *p != '=') p++;
+    v = NULL;
+    if (*p == '=' || *p == ':') { *p = '\0'; p++; v = p; }
+    while (*p && *p != '\r' && *p != '\n') p++;
+    if (*p) { *p = '\0'; p++; }
+    k = strstrip(k);
+    v = strstrip(v);
+    if (v && *v && *k &&
+        strcasecmp(k, "Connection") != 0 &&
+        strcasecmp(k, "Host") != 0)
+      http_arg_set(h, k, v);
+  }
+}
+
 int
-http_client_simple_reconnect ( http_client_t *hc, const url_t *u, http_ver_t ver )
+http_client_simple_reconnect ( http_client_t *hc, const url_t *u,
+                               http_ver_t ver )
 {
   http_arg_list_t h;
   tvhpoll_t *efd;
@@ -1172,7 +1211,7 @@ http_client_simple_reconnect ( http_client_t *hc, const url_t *u, http_ver_t ver
 
   http_client_flush(hc, 0);
 
-  http_client_basic_args(hc, &h, u, hc->hc_keepalive);
+  hc->hc_hdr_create(hc, &h, u, 0);
   hc->hc_reconnected = 1;
   hc->hc_shutdown    = 0;
   hc->hc_pevents     = 0;
@@ -1227,7 +1266,7 @@ http_client_simple( http_client_t *hc, const url_t *url )
 {
   http_arg_list_t h;
 
-  http_client_basic_args(hc, &h, url, 0);
+  hc->hc_hdr_create(hc, &h, url, 0);
   return http_client_send(hc, HTTP_CMD_GET, url->path, url->query,
                           &h, NULL, 0);
 }
@@ -1415,6 +1454,8 @@ http_client_connect
   TAILQ_INIT(&hc->hc_args);
   TAILQ_INIT(&hc->hc_wqueue);
 
+  hc->hc_hdr_create = http_client_basic_args;
+
   if (http_client_reconnect(hc, ver, scheme, host, port) < 0) {
     free(hc);
     return NULL;
index 8149161e49fec463de733554e8540b74ac97ff54..49f98bd5485bfe040ad430c08cdbff0e16f3fd0b 100644 (file)
@@ -161,6 +161,19 @@ iptv_http_complete
   return 0;
 }
 
+/*
+ * Custom headers
+ */
+static void
+iptv_http_create_header
+  ( http_client_t *hc, http_arg_list_t *h, const url_t *url, int keepalive )
+{
+  iptv_mux_t *im = hc->hc_aux;
+
+  http_client_basic_args(hc, h, url, keepalive);
+  http_client_add_args(hc, h, im->mm_iptv_hdr);
+}
+
 /*
  * Setup HTTP(S) connection
  */
@@ -174,6 +187,7 @@ iptv_http_start
   if (!(hc = http_client_connect(im, HTTP_VERSION_1_1, u->scheme,
                                  u->host, u->port, NULL)))
     return SM_CODE_TUNING_FAILED;
+  hc->hc_hdr_create      = iptv_http_create_header;
   hc->hc_hdr_received    = iptv_http_header;
   hc->hc_data_received   = iptv_http_data;
   hc->hc_data_complete   = iptv_http_complete;
index a7c01a6710925d1da38c69a4f26b6e16ced5cdd9..b6781596bf97d1bbd651911e613a23d98bd617d9 100644 (file)
@@ -217,6 +217,13 @@ const idclass_t iptv_mux_class =
       .off      = offsetof(iptv_mux_t, mm_iptv_env),
       .opts     = PO_ADVANCED | PO_MULTILINE
     },
+    {
+      .type     = PT_STR,
+      .id       = "iptv_hdr",
+      .name     = N_("Custom HTTP headers"),
+      .off      = offsetof(iptv_mux_t, mm_iptv_hdr),
+      .opts     = PO_ADVANCED | PO_MULTILINE
+    },
     {}
   }
 };
@@ -252,6 +259,7 @@ iptv_mux_delete ( mpegts_mux_t *mm, int delconf )
   free(im->mm_iptv_interface);
   free(im->mm_iptv_svcname);
   free(im->mm_iptv_env);
+  free(im->mm_iptv_hdr);
   free(im->mm_iptv_icon);
   free(im->mm_iptv_epgid);
   mpegts_mux_delete(mm, delconf);
index 12c8c452cac8e93a611ea1d5f4782ea25b34b8e6..77253473d788426e9b67da325415fa7006f39cca 100644 (file)
@@ -130,6 +130,7 @@ struct iptv_mux
   int                   mm_iptv_kill;
   int                   mm_iptv_kill_timeout;
   char                 *mm_iptv_env;
+  char                 *mm_iptv_hdr;
 
   uint32_t              mm_iptv_rtp_seq;