Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
http: this fixes streaming when tvheadend is behind a https reverse p…
…roxy *and* a non-default webroot (e.g. /tvheadend)
  • Loading branch information
pgaubatz authored and perexg committed Nov 23, 2014
1 parent 085fd89 commit 664d243
Showing 1 changed file with 34 additions and 22 deletions.
56 changes: 34 additions & 22 deletions src/webui/webui.c
Expand Up @@ -364,6 +364,22 @@ http_stream_run(http_connection_t *hc, profile_chain_t *prch,
}


static char *
http_get_hostpath(http_connection_t *hc)
{
char buf[255];
const char *host = http_arg_get(&hc->hc_args, "Host");
const char *forwarded_host = http_arg_get(&hc->hc_args, "X-Forwarded-Host");
const char *proto = http_arg_get(&hc->hc_args, "X-Forwarded-Proto");

snprintf(buf, sizeof(buf), "%s://%s%s",
proto ? proto : "http",
forwarded_host ? forwarded_host : host,
tvheadend_webroot ? tvheadend_webroot : "");

return strdup(buf);
}

/**
* Output a playlist containing a single channel
*/
Expand All @@ -372,7 +388,7 @@ http_channel_playlist(http_connection_t *hc, channel_t *channel)
{
htsbuf_queue_t *hq;
char buf[255];
const char *host;
const char *hostpath = http_get_hostpath(hc);
char *profile;

if (http_access_verify_channel(hc, ACCESS_STREAMING, channel, 1))
Expand All @@ -381,13 +397,12 @@ http_channel_playlist(http_connection_t *hc, channel_t *channel)
profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile"));

hq = &hc->hc_reply;
host = http_arg_get(&hc->hc_args, "Host");

snprintf(buf, sizeof(buf), "/stream/channelid/%d", channel_get_id(channel));

htsbuf_qprintf(hq, "#EXTM3U\n");
htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", channel_get_name(channel));
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
htsbuf_qprintf(hq, "%s%s?ticket=%s", hostpath, buf,
access_ticket_create(buf, hc->hc_access));

htsbuf_qprintf(hq, "&profile=%s\n", profile);
Expand All @@ -408,15 +423,14 @@ http_tag_playlist(http_connection_t *hc, channel_tag_t *tag)
htsbuf_queue_t *hq;
char buf[255];
channel_tag_mapping_t *ctm;
const char *host;
const char *hostpath = http_get_hostpath(hc);
char *profile;

if(hc->hc_access == NULL ||
access_verify2(hc->hc_access, ACCESS_STREAMING))
return HTTP_STATUS_UNAUTHORIZED;

hq = &hc->hc_reply;
host = http_arg_get(&hc->hc_args, "Host");

profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile"));

Expand All @@ -426,7 +440,7 @@ http_tag_playlist(http_connection_t *hc, channel_tag_t *tag)
continue;
snprintf(buf, sizeof(buf), "/stream/channelid/%d", channel_get_id(ctm->ctm_channel));
htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", channel_get_name(ctm->ctm_channel));
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
htsbuf_qprintf(hq, "%s%s?ticket=%s", hostpath, buf,
access_ticket_create(buf, hc->hc_access));
htsbuf_qprintf(hq, "&profile=%s\n", profile);
}
Expand All @@ -447,15 +461,14 @@ http_tag_list_playlist(http_connection_t *hc)
htsbuf_queue_t *hq;
char buf[255];
channel_tag_t *ct;
const char *host;
const char *hostpath = http_get_hostpath(hc);
char *profile;

if(hc->hc_access == NULL ||
access_verify2(hc->hc_access, ACCESS_STREAMING))
return HTTP_STATUS_UNAUTHORIZED;

hq = &hc->hc_reply;
host = http_arg_get(&hc->hc_args, "Host");

profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile"));

Expand All @@ -466,7 +479,7 @@ http_tag_list_playlist(http_connection_t *hc)

snprintf(buf, sizeof(buf), "/playlist/tagid/%d", idnode_get_short_uuid(&ct->ct_id));
htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", ct->ct_name);
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
htsbuf_qprintf(hq, "%s%s?ticket=%s", hostpath, buf,
access_ticket_create(buf, hc->hc_access));
htsbuf_qprintf(hq, "&profile=%s\n", profile);
}
Expand Down Expand Up @@ -498,7 +511,7 @@ http_channel_list_playlist(http_connection_t *hc)
char buf[255];
channel_t *ch;
channel_t **chlist;
const char *host;
const char *hostpath = http_get_hostpath(hc);
int idx = 0, count = 0;
char *profile;

Expand All @@ -507,7 +520,6 @@ http_channel_list_playlist(http_connection_t *hc)
return HTTP_STATUS_UNAUTHORIZED;

hq = &hc->hc_reply;
host = http_arg_get(&hc->hc_args, "Host");

profile = profile_validate_name(http_arg_get(&hc->hc_req_args, "profile"));

Expand Down Expand Up @@ -535,7 +547,7 @@ http_channel_list_playlist(http_connection_t *hc)
snprintf(buf, sizeof(buf), "/stream/channelid/%d", channel_get_id(ch));

htsbuf_qprintf(hq, "#EXTINF:-1,%s\n", channel_get_name(ch));
htsbuf_qprintf(hq, "http://%s%s?ticket=%s", host, buf,
htsbuf_qprintf(hq, "%s%s?ticket=%s", hostpath, buf,
access_ticket_create(buf, hc->hc_access));
htsbuf_qprintf(hq, "&profile=%s\n", profile);
}
Expand All @@ -559,14 +571,14 @@ http_dvr_list_playlist(http_connection_t *hc)
htsbuf_queue_t *hq;
char buf[255];
dvr_entry_t *de;
const char *host, *uuid;
const char *uuid;
const char *hostpath = http_get_hostpath(hc);
off_t fsize;
time_t durration;
struct tm tm;
int bandwidth;

hq = &hc->hc_reply;
host = http_arg_get(&hc->hc_args, "Host");

htsbuf_qprintf(hq, "#EXTM3U\n");
LIST_FOREACH(de, &dvrentries, de_global_link) {
Expand All @@ -591,7 +603,7 @@ http_dvr_list_playlist(http_connection_t *hc)
htsbuf_qprintf(hq, "#EXT-X-PROGRAM-DATE-TIME:%s\n", buf);

snprintf(buf, sizeof(buf), "/dvrfile/%s", uuid);
htsbuf_qprintf(hq, "http://%s%s?ticket=%s\n", host, buf,
htsbuf_qprintf(hq, "%s%s?ticket=%s\n", hostpath, buf,
access_ticket_create(buf, hc->hc_access));
}

Expand All @@ -613,7 +625,7 @@ http_dvr_playlist(http_connection_t *hc, dvr_entry_t *de)
off_t fsize = 0;
int bandwidth = 0;
struct tm tm;
const char *host = http_arg_get(&hc->hc_args, "Host");
const char *hostpath = http_get_hostpath(hc);

if(http_access_verify(hc, ACCESS_RECORDER))
return HTTP_STATUS_UNAUTHORIZED;
Expand All @@ -636,7 +648,7 @@ http_dvr_playlist(http_connection_t *hc, dvr_entry_t *de)

snprintf(buf, sizeof(buf), "/dvrfile/%s", uuid);
ticket_id = access_ticket_create(buf, hc->hc_access);
htsbuf_qprintf(hq, "http://%s%s?ticket=%s\n", host, buf, ticket_id);
htsbuf_qprintf(hq, "%s%s?ticket=%s\n", hostpath, buf, ticket_id);

http_output_content(hc, "application/x-mpegURL");
} else {
Expand Down Expand Up @@ -958,7 +970,7 @@ page_xspf(http_connection_t *hc, const char *remain, void *opaque)
{
size_t maxlen;
char *buf;
const char *host = http_arg_get(&hc->hc_args, "Host");
const char *hostpath = http_get_hostpath(hc);
const char *title, *profile, *image;
size_t len;

Expand All @@ -976,10 +988,10 @@ page_xspf(http_connection_t *hc, const char *remain, void *opaque)
<trackList>\r\n\
<track>\r\n\
<title>%s</title>\r\n\
<location>http://%s/%s%s%s</location>\r\n%s%s%s\
<location>%s/%s%s%s</location>\r\n%s%s%s\
</track>\r\n\
</trackList>\r\n\
</playlist>\r\n", title, host, remain, profile ? "?profile=" : "", profile ?: "",
</playlist>\r\n", title, hostpath, remain, profile ? "?profile=" : "", profile ?: "",
image ? " <image>" : "", image ?: "", image ? "</image>\r\n" : "");

len = strlen(buf);
Expand All @@ -998,7 +1010,7 @@ page_m3u(http_connection_t *hc, const char *remain, void *opaque)
{
size_t maxlen;
char *buf;
const char *host = http_arg_get(&hc->hc_args, "Host");
const char *hostpath = http_get_hostpath(hc);
const char *title, *profile;
size_t len;

Expand All @@ -1012,7 +1024,7 @@ page_m3u(http_connection_t *hc, const char *remain, void *opaque)
snprintf(buf, maxlen, "\
#EXTM3U\r\n\
#EXTINF:-1,%s\r\n\
http://%s/%s%s%s\r\n", title, host, remain, profile ? "?profile=" : "", profile ?: "");
%s/%s%s%s\r\n", title, hostpath, remain, profile ? "?profile=" : "", profile ?: "");

len = strlen(buf);
http_send_header(hc, 200, "audio/x-mpegurl", len, 0, NULL, 10, 0, NULL);
Expand Down

0 comments on commit 664d243

Please sign in to comment.