webui: when wget or curl is used, stream directly for /play handler

This commit is contained in:
Jaroslav Kysela 2014-06-23 18:15:00 +02:00
parent fc15e04d78
commit 7cb8fc2f23
3 changed files with 65 additions and 16 deletions

View file

@ -94,8 +94,9 @@ static http_path_t *
http_resolve(http_connection_t *hc, char **remainp, char **argsp)
{
http_path_t *hp;
int n = 0;
int n = 0, cut = 0;
char *v, *path = tvh_strdupa(hc->hc_url);
char *npath;
/* Canocalize path (or at least remove excess slashes) */
v = path;
@ -109,19 +110,35 @@ http_resolve(http_connection_t *hc, char **remainp, char **argsp)
v++;
}
LIST_FOREACH(hp, &http_paths, hp_link) {
if(!strncmp(path, hp->hp_path, hp->hp_len)) {
if(path[hp->hp_len] == 0 ||
path[hp->hp_len] == '/' ||
path[hp->hp_len] == '?')
break;
}
}
if(hp == NULL)
return NULL;
while (1) {
v = hc->hc_url + n + hp->hp_len;
LIST_FOREACH(hp, &http_paths, hp_link) {
if(!strncmp(path, hp->hp_path, hp->hp_len)) {
if(path[hp->hp_len] == 0 ||
path[hp->hp_len] == '/' ||
path[hp->hp_len] == '?')
break;
}
}
if(hp == NULL)
return NULL;
cut += hp->hp_len;
if(hp->hp_path_modify == NULL)
break;
npath = hp->hp_path_modify(hc, path, &cut);
if(npath == NULL)
break;
path = tvh_strdupa(npath);
free(npath);
}
v = hc->hc_url + n + cut;
*remainp = NULL;
*argsp = NULL;
@ -648,8 +665,8 @@ http_tokenize(char *buf, char **vec, int vecsize, int delimiter)
* Add a callback for a given "virtual path" on our HTTP server
*/
http_path_t *
http_path_add(const char *path, void *opaque, http_callback_t *callback,
uint32_t accessmask)
http_path_add_modify(const char *path, void *opaque, http_callback_t *callback,
uint32_t accessmask, http_path_modify_t *path_modify)
{
http_path_t *hp = malloc(sizeof(http_path_t));
char *tmp;
@ -664,10 +681,20 @@ http_path_add(const char *path, void *opaque, http_callback_t *callback,
hp->hp_opaque = opaque;
hp->hp_callback = callback;
hp->hp_accessmask = accessmask;
hp->hp_path_modify = path_modify;
LIST_INSERT_HEAD(&http_paths, hp, hp_link);
return hp;
}
/**
* Add a callback for a given "virtual path" on our HTTP server
*/
http_path_t *
http_path_add(const char *path, void *opaque, http_callback_t *callback,
uint32_t accessmask)
{
return http_path_add_modify(path, opaque, callback, accessmask, NULL);
}
/**
* De-escape HTTP URL

View file

@ -177,6 +177,10 @@ void http_send_header(http_connection_t *hc, int rc, const char *content,
typedef int (http_callback_t)(http_connection_t *hc,
const char *remain, void *opaque);
typedef char * (http_path_modify_t)(http_connection_t *hc,
const char * path, int *cut);
typedef struct http_path {
LIST_ENTRY(http_path) hp_link;
const char *hp_path;
@ -184,8 +188,13 @@ typedef struct http_path {
http_callback_t *hp_callback;
int hp_len;
uint32_t hp_accessmask;
http_path_modify_t *hp_path_modify;
} http_path_t;
http_path_t *http_path_add_modify(const char *path, void *opaque,
http_callback_t *callback,
uint32_t accessmask,
http_path_modify_t path_modify);
http_path_t *http_path_add(const char *path, void *opaque,
http_callback_t *callback, uint32_t accessmask);

View file

@ -984,6 +984,19 @@ http://%s/%s\r\n", title, host, remain);
return 0;
}
static char *
page_play_path_modify(http_connection_t *hc, const char *path, int *cut)
{
/*
* For curl and wget do not set the playlist, stream directly
*/
const char *agent = http_arg_get(&hc->hc_args, "User-Agent");
if (strncasecmp(agent, "curl/", 5) == 0 ||
strncasecmp(agent, "wget/", 5) == 0)
return strdup(path + 5);
return NULL;
}
static int
page_play(http_connection_t *hc, const char *remain, void *opaque)
{
@ -1204,7 +1217,7 @@ webui_init(int xspf)
http_path_add("", NULL, page_root2, ACCESS_WEB_INTERFACE);
http_path_add("/", NULL, page_root, ACCESS_WEB_INTERFACE);
http_path_add("/play", NULL, page_play, ACCESS_WEB_INTERFACE);
http_path_add_modify("/play", NULL, page_play, ACCESS_WEB_INTERFACE, page_play_path_modify);
http_path_add("/dvrfile", NULL, page_dvrfile, ACCESS_WEB_INTERFACE);
http_path_add("/favicon.ico", NULL, favicon, ACCESS_WEB_INTERFACE);
http_path_add("/playlist", NULL, page_http_playlist, ACCESS_WEB_INTERFACE);