From be7381f1d15c12e6d2a5790145d8cb81f7d7d044 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 29 Oct 2015 17:13:25 +0100 Subject: [PATCH] IPTV: allow custom HTTP headers for muxes, fixes #3182 --- src/http.h | 6 ++++ src/httpc.c | 49 +++++++++++++++++++++++++--- src/input/mpegts/iptv/iptv_http.c | 14 ++++++++ src/input/mpegts/iptv/iptv_mux.c | 8 +++++ src/input/mpegts/iptv/iptv_private.h | 1 + 5 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/http.h b/src/http.h index 2c4134bfb..d21c0edc8 100644 --- a/src/http.h +++ b/src/http.h @@ -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 ); diff --git a/src/httpc.c b/src/httpc.c index 72fcd931b..4db8fa2c2 100644 --- a/src/httpc.c +++ b/src/httpc.c @@ -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; diff --git a/src/input/mpegts/iptv/iptv_http.c b/src/input/mpegts/iptv/iptv_http.c index 8149161e4..49f98bd54 100644 --- a/src/input/mpegts/iptv/iptv_http.c +++ b/src/input/mpegts/iptv/iptv_http.c @@ -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; diff --git a/src/input/mpegts/iptv/iptv_mux.c b/src/input/mpegts/iptv/iptv_mux.c index a7c01a671..b6781596b 100644 --- a/src/input/mpegts/iptv/iptv_mux.c +++ b/src/input/mpegts/iptv/iptv_mux.c @@ -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); diff --git a/src/input/mpegts/iptv/iptv_private.h b/src/input/mpegts/iptv/iptv_private.h index 12c8c452c..77253473d 100644 --- a/src/input/mpegts/iptv/iptv_private.h +++ b/src/input/mpegts/iptv/iptv_private.h @@ -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; -- 2.47.3