Rewrite HTTP server so it can defer replies
This commit is contained in:
parent
186e1b8c6a
commit
2d700d2901
10 changed files with 530 additions and 540 deletions
143
ajaxui/ajaxui.c
143
ajaxui/ajaxui.c
|
@ -268,16 +268,15 @@ ajax_a_jsfunc(tcp_queue_t *tq, const char *innerhtml, const char *func,
|
|||
* Titlebar AJAX page
|
||||
*/
|
||||
static int
|
||||
ajax_page_titlebar(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_page_titlebar(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
|
||||
if(remain == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
ajax_menu_bar_from_array(&tq, "top", ajax_tabnames, AJAX_TABS, atoi(remain));
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
ajax_menu_bar_from_array(&hr->hr_tq, "top",
|
||||
ajax_tabnames, AJAX_TABS, atoi(remain));
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -287,20 +286,18 @@ ajax_page_titlebar(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* About
|
||||
*/
|
||||
static int
|
||||
ajax_about_tab(http_connection_t *hc)
|
||||
ajax_about_tab(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
tcp_qprintf(tq, "<center>");
|
||||
tcp_qprintf(tq, "<div style=\"padding: auto; width: 400px\">");
|
||||
|
||||
tcp_qprintf(&tq, "<center>");
|
||||
tcp_qprintf(&tq, "<div style=\"padding: auto; width: 400px\">");
|
||||
ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, "About");
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, "About");
|
||||
tcp_qprintf(tq, "<div style=\"text-align: center\">");
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"text-align: center\">");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<p>HTS / Tvheadend</p>"
|
||||
"<p>(c) 2006-2008 Andreas \303\226man</p>"
|
||||
"<p>Latest release and information is available at:</p>"
|
||||
|
@ -317,12 +314,12 @@ ajax_about_tab(http_connection_t *hc)
|
|||
"<p><a href=\"http://www.ffmpeg.org/\">FFmpeg</a></p>"
|
||||
);
|
||||
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
tcp_qprintf(&tq, "</center>");
|
||||
tcp_qprintf(tq, "</div>");
|
||||
ajax_box_end(tq, AJAX_BOX_SIDEBOX);
|
||||
tcp_qprintf(tq, "</div>");
|
||||
tcp_qprintf(tq, "</center>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -334,7 +331,8 @@ ajax_about_tab(http_connection_t *hc)
|
|||
* Find the 'tab' id and continue with tab specific code
|
||||
*/
|
||||
static int
|
||||
ajax_page_tab(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_page_tab(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
int tab;
|
||||
|
||||
|
@ -345,13 +343,13 @@ ajax_page_tab(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
switch(tab) {
|
||||
case AJAX_TAB_CHANNELS:
|
||||
return ajax_channelgroup_tab(hc);
|
||||
return ajax_channelgroup_tab(hc, hr);
|
||||
|
||||
case AJAX_TAB_CONFIGURATION:
|
||||
return ajax_config_tab(hc);
|
||||
return ajax_config_tab(hc, hr);
|
||||
|
||||
case AJAX_TAB_ABOUT:
|
||||
return ajax_about_tab(hc);
|
||||
return ajax_about_tab(hc, hr);
|
||||
|
||||
default:
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
@ -365,13 +363,12 @@ ajax_page_tab(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* Root page
|
||||
*/
|
||||
static int
|
||||
ajax_page_root(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_page_root(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\r\n"
|
||||
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
|
||||
/*
|
||||
|
@ -388,110 +385,50 @@ ajax_page_root(http_connection_t *hc, const char *remain, void *opaque)
|
|||
"content=\"text/html; charset=utf-8\">\r\n");
|
||||
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<link href=\"/ajax/ajaxui.css\" rel=\"stylesheet\" "
|
||||
"type=\"text/css\">\r\n");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script src=\"/ajax/prototype.js\" type=\"text/javascript\">"
|
||||
"</script>\r\n");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script src=\"/ajax/effects.js\" type=\"text/javascript\">"
|
||||
"</script>\r\n");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script src=\"/ajax/dragdrop.js\" type=\"text/javascript\">"
|
||||
"</script>\r\n");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script src=\"/ajax/controls.js\" type=\"text/javascript\">"
|
||||
"</script>\r\n");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script src=\"/ajax/tvheadend.js\" type=\"text/javascript\">"
|
||||
"</script>\r\n");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"</head>");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<body>");
|
||||
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_FILLED, "topmenu", NULL, NULL);
|
||||
ajax_box_end(&tq, AJAX_BOX_FILLED);
|
||||
ajax_box_begin(tq, AJAX_BOX_FILLED, "topmenu", NULL, NULL);
|
||||
ajax_box_end(tq, AJAX_BOX_FILLED);
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"topdeck\"></div>");
|
||||
tcp_qprintf(tq, "<div id=\"topdeck\"></div>");
|
||||
|
||||
ajax_js(&tq, "switchtab('top', '0')");
|
||||
ajax_js(tq, "switchtab('top', '0')");
|
||||
|
||||
tcp_qprintf(&tq, "</body></html>");
|
||||
tcp_qprintf(tq, "</body></html>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void blah(void) {
|
||||
tcp_qprintf(&tq,
|
||||
"<ul id=\"list\">"
|
||||
"<li id=\"item_1\">I'm number 1 <a href=\"/\">a link</a></li>"
|
||||
"<li id=\"item_2\">");
|
||||
ajax_box_top(&tq, NULL, NULL);
|
||||
tcp_qprintf(&tq,
|
||||
"I'm number 2");
|
||||
|
||||
ajax_box_bottom(&tq);
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
"</li>"
|
||||
"<li id=\"item_3\">I'm number 3</li>"
|
||||
"<li id=\"item_4\">I'm number 4</li>"
|
||||
"</ul>"
|
||||
"\r\n"
|
||||
"<p id=\"list-info\"></p>\r\n");
|
||||
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
"<script type=\"text/javascript\">\r\n"
|
||||
"//<![CDATA[\r\n"
|
||||
"Sortable.create(\"list\", {onUpdate:function(){new Ajax.Updater('list-info', '/ajax/order', {asynchronous:true, evalScripts:true, onComplete:function(request){new Effect.Highlight(\"list\",{});}, parameters:Sortable.serialize(\"list\")})}})\r\n"
|
||||
"//]]>\r\n"
|
||||
"</script>\r\n");
|
||||
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
"<div id=\"updateDiv\"></div>\r\n"
|
||||
"<form id=\"testform\">\n"
|
||||
"<input name=\"name\" type=\"text\"><br>\r\n"
|
||||
"<textarea name=\"comment\" cols=\"20\" rows=\"3\">"
|
||||
"</textarea><br>\r\n"
|
||||
"<input name=\"sendbutton\" type=\"button\" value=\"Send\""
|
||||
" onClick=\"new Ajax.Updater('updateDiv', '/ajax/formupdate', "
|
||||
"{asynchronous:true, "
|
||||
" parameters:Form.serialize($('testform'))})\">\r\n"
|
||||
"</form>\r\n");
|
||||
|
||||
|
||||
for(i = 0; i < 40; i++) {
|
||||
tcp_qprintf(&tq,
|
||||
"<div style=\"float: left\" class=\"sidebox\">\r\n"
|
||||
" <div class=\"boxhead\"><h2>Discovery</h2></div>\r\n"
|
||||
" <div class=\"boxbody\">"
|
||||
" <p>Idag e det bra saker pa TV</p>"
|
||||
" <p>Imorgon vet vi inte</p>"
|
||||
"</div></div>");
|
||||
}
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
"</body></html>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,13 +54,13 @@ void ajax_menu_bar_from_array(tcp_queue_t *tq, const char *name,
|
|||
void ajax_a_jsfunc(tcp_queue_t *tq, const char *innerhtml, const char *func,
|
||||
const char *trailer);
|
||||
|
||||
int ajax_channelgroup_tab(http_connection_t *hc);
|
||||
int ajax_config_tab(http_connection_t *hc);
|
||||
int ajax_channelgroup_tab(http_connection_t *hc, http_reply_t *hr);
|
||||
int ajax_config_tab(http_connection_t *hc, http_reply_t *hr);
|
||||
|
||||
int ajax_config_channels_tab(http_connection_t *hc);
|
||||
int ajax_config_channels_tab(http_connection_t *hc, http_reply_t *hr);
|
||||
void ajax_config_channels_init(void);
|
||||
|
||||
int ajax_config_dvb_tab(http_connection_t *hc);
|
||||
int ajax_config_dvb_tab(http_connection_t *hc, http_reply_t *hr);
|
||||
void ajax_config_dvb_init(void);
|
||||
void ajax_config_transport_init(void);
|
||||
|
||||
|
|
|
@ -58,17 +58,16 @@ ajax_channelgroupmenu_content(tcp_queue_t *tq, int current)
|
|||
* Channelgroup menu bar
|
||||
*/
|
||||
static int
|
||||
ajax_channelgroup_menu(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_channelgroup_menu(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
if(remain == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
ajax_channelgroupmenu_content(&tq, atoi(remain));
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
ajax_channelgroupmenu_content(tq, atoi(remain));
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -82,9 +81,10 @@ ajax_channelgroup_menu(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* Group is given by 'tag' as an ASCII string in remain
|
||||
*/
|
||||
int
|
||||
ajax_channel_tab(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_channel_tab(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
// tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_channel_t *ch;
|
||||
th_channel_group_t *tcg;
|
||||
|
||||
|
@ -94,8 +94,6 @@ ajax_channel_tab(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if((tcg = channel_group_by_tag(atoi(remain))) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
TAILQ_FOREACH(ch, &tcg->tcg_channels, ch_group_link) {
|
||||
if(LIST_FIRST(&ch->ch_transports) == NULL)
|
||||
continue;
|
||||
|
@ -108,7 +106,7 @@ ajax_channel_tab(http_connection_t *hc, const char *remain, void *opaque)
|
|||
#endif
|
||||
}
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -121,23 +119,21 @@ ajax_channel_tab(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* This is the top level menu for this c-file
|
||||
*/
|
||||
int
|
||||
ajax_channelgroup_tab(http_connection_t *hc)
|
||||
ajax_channelgroup_tab(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
ajax_box_begin(tq, AJAX_BOX_FILLED, "channelgroupmenu", NULL, NULL);
|
||||
ajax_box_end(tq, AJAX_BOX_FILLED);
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_FILLED, "channelgroupmenu", NULL, NULL);
|
||||
ajax_box_end(&tq, AJAX_BOX_FILLED);
|
||||
tcp_qprintf(tq, "<div id=\"channelgroupdeck\"></div>");
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"channelgroupdeck\"></div>");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script type=\"text/javascript\">"
|
||||
"switchtab('channelgroup', '0')"
|
||||
"</script>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,18 +43,18 @@ const char *ajax_config_tabnames[] = {
|
|||
* Titlebar AJAX page
|
||||
*/
|
||||
static int
|
||||
ajax_config_menu(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_config_menu(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
if(remain == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
ajax_menu_bar_from_array(&tq, "config",
|
||||
ajax_menu_bar_from_array(tq, "config",
|
||||
ajax_config_tabnames, AJAX_CONFIG_TABS,
|
||||
atoi(remain));
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,8 @@ ajax_config_menu(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* Switch to different tabs
|
||||
*/
|
||||
static int
|
||||
ajax_config_dispatch(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_config_dispatch(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
int tab;
|
||||
|
||||
|
@ -75,9 +76,9 @@ ajax_config_dispatch(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
switch(tab) {
|
||||
case AJAX_CONFIG_TAB_CHANNELS:
|
||||
return ajax_config_channels_tab(hc);
|
||||
return ajax_config_channels_tab(hc, hr);
|
||||
case AJAX_CONFIG_TAB_DVB:
|
||||
return ajax_config_dvb_tab(hc);
|
||||
return ajax_config_dvb_tab(hc, hr);
|
||||
|
||||
default:
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
@ -94,23 +95,21 @@ ajax_config_dispatch(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* This is the top level menu for this c-file
|
||||
*/
|
||||
int
|
||||
ajax_config_tab(http_connection_t *hc)
|
||||
ajax_config_tab(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
ajax_box_begin(tq, AJAX_BOX_FILLED, "configmenu", NULL, NULL);
|
||||
ajax_box_end(tq, AJAX_BOX_FILLED);
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_FILLED, "configmenu", NULL, NULL);
|
||||
ajax_box_end(&tq, AJAX_BOX_FILLED);
|
||||
tcp_qprintf(tq, "<div id=\"configdeck\"></div>");
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"configdeck\"></div>");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<script type=\"text/javascript\">"
|
||||
"switchtab('config', '0')"
|
||||
"</script>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,15 +71,13 @@ ajax_chgroup_build(tcp_queue_t *tq, th_channel_group_t *tcg)
|
|||
* Update order of channel groups
|
||||
*/
|
||||
static int
|
||||
ajax_chgroup_updateorder(http_connection_t *hc, const char *remain,
|
||||
void *opaque)
|
||||
ajax_chgroup_updateorder(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_channel_group_t *tcg;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
http_arg_t *ra;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
TAILQ_FOREACH(ra, &hc->hc_req_args, link) {
|
||||
if(strcmp(ra->key, "channelgrouplist[]") ||
|
||||
(tcg = channel_group_by_tag(atoi(ra->val))) == NULL)
|
||||
|
@ -91,9 +89,9 @@ ajax_chgroup_updateorder(http_connection_t *hc, const char *remain,
|
|||
|
||||
channel_group_settings_write();
|
||||
|
||||
tcp_qprintf(&tq, "<span id=\"updatedok\">Updated on server</span>");
|
||||
ajax_js(&tq, "Effect.Fade('updatedok')");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
tcp_qprintf(tq, "<span id=\"updatedok\">Updated on server</span>");
|
||||
ajax_js(tq, "Effect.Fade('updatedok')");
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -103,14 +101,13 @@ ajax_chgroup_updateorder(http_connection_t *hc, const char *remain,
|
|||
* Add a new channel group
|
||||
*/
|
||||
static int
|
||||
ajax_chgroup_add(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_chgroup_add(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_channel_group_t *tcg;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
const char *name;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
if((name = http_arg_get(&hc->hc_req_args, "name")) != NULL) {
|
||||
|
||||
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link)
|
||||
|
@ -120,13 +117,13 @@ ajax_chgroup_add(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if(tcg == NULL) {
|
||||
tcg = channel_group_find(name, 1);
|
||||
|
||||
ajax_chgroup_build(&tq, tcg);
|
||||
ajax_chgroup_build(tq, tcg);
|
||||
|
||||
/* We must recreate the Sortable object */
|
||||
|
||||
ajax_js(&tq, "Sortable.destroy(\"channelgrouplist\")");
|
||||
ajax_js(tq, "Sortable.destroy(\"channelgrouplist\")");
|
||||
|
||||
ajax_js(&tq, "Sortable.create(\"channelgrouplist\", "
|
||||
ajax_js(tq, "Sortable.create(\"channelgrouplist\", "
|
||||
"{onUpdate:function(){updatelistonserver("
|
||||
"'channelgrouplist', "
|
||||
"'/ajax/chgroup_updateorder', "
|
||||
|
@ -134,7 +131,7 @@ ajax_chgroup_add(http_connection_t *hc, const char *remain, void *opaque)
|
|||
")}});");
|
||||
}
|
||||
}
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -144,10 +141,11 @@ ajax_chgroup_add(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* Delete a channel group
|
||||
*/
|
||||
static int
|
||||
ajax_chgroup_del(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_chgroup_del(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_channel_group_t *tcg;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
const char *id;
|
||||
|
||||
if((id = http_arg_get(&hc->hc_req_args, "id")) == NULL)
|
||||
|
@ -156,12 +154,10 @@ ajax_chgroup_del(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if((tcg = channel_group_by_tag(atoi(id))) == NULL)
|
||||
return HTTP_STATUS_BAD_REQUEST;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
tcp_qprintf(&tq, "$('chgrp_%d').remove();", tcg->tcg_tag);
|
||||
http_output_queue(hc, &tq, "text/javascript; charset=UTF-8", 0);
|
||||
tcp_qprintf(tq, "$('chgrp_%d').remove();", tcg->tcg_tag);
|
||||
http_output(hc, hr, "text/javascript; charset=UTF-8", NULL, 0);
|
||||
|
||||
channel_group_destroy(tcg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -171,32 +167,30 @@ ajax_chgroup_del(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* Channel group & channel configuration
|
||||
*/
|
||||
int
|
||||
ajax_config_channels_tab(http_connection_t *hc)
|
||||
ajax_config_channels_tab(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_channel_group_t *tcg;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"float: left; width: 40%\">");
|
||||
tcp_qprintf(tq, "<div style=\"float: left; width: 40%\">");
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, "channelgroups",
|
||||
ajax_box_begin(tq, AJAX_BOX_SIDEBOX, "channelgroups",
|
||||
NULL, "Channel groups");
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"height:15px; text-align:center\" "
|
||||
tcp_qprintf(tq, "<div style=\"height:15px; text-align:center\" "
|
||||
"id=\"list-info\"></div>");
|
||||
|
||||
tcp_qprintf(&tq, "<ul id=\"channelgrouplist\" class=\"draglist\">");
|
||||
tcp_qprintf(tq, "<ul id=\"channelgrouplist\" class=\"draglist\">");
|
||||
|
||||
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
|
||||
if(tcg->tcg_hidden)
|
||||
continue;
|
||||
ajax_chgroup_build(&tq, tcg);
|
||||
ajax_chgroup_build(tq, tcg);
|
||||
}
|
||||
|
||||
tcp_qprintf(&tq, "</ul>");
|
||||
tcp_qprintf(tq, "</ul>");
|
||||
|
||||
ajax_js(&tq, "Sortable.create(\"channelgrouplist\", "
|
||||
ajax_js(tq, "Sortable.create(\"channelgrouplist\", "
|
||||
"{onUpdate:function(){updatelistonserver("
|
||||
"'channelgrouplist', "
|
||||
"'/ajax/chgroup_updateorder', "
|
||||
|
@ -206,9 +200,9 @@ ajax_config_channels_tab(http_connection_t *hc)
|
|||
/**
|
||||
* Add new group
|
||||
*/
|
||||
ajax_box_begin(&tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
|
||||
ajax_box_begin(tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"height: 20px\">"
|
||||
"<div style=\"float: left\">"
|
||||
"<input class=\"textinput\" type=\"text\" id=\"newchgrp\">"
|
||||
|
@ -220,21 +214,18 @@ ajax_config_channels_tab(http_connection_t *hc)
|
|||
"Add</a></div>"
|
||||
"</div>");
|
||||
|
||||
ajax_box_end(&tq, AJAX_BOX_BORDER);
|
||||
ajax_box_end(tq, AJAX_BOX_BORDER);
|
||||
|
||||
ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
ajax_box_end(tq, AJAX_BOX_SIDEBOX);
|
||||
tcp_qprintf(tq, "</div>");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div id=\"groupeditortab\" "
|
||||
"style=\"height: 600px; overflow: auto; "
|
||||
"float: left; width: 60%\">");
|
||||
|
||||
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
tcp_qprintf(tq, "</div>");
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -242,46 +233,45 @@ ajax_config_channels_tab(http_connection_t *hc)
|
|||
* Display all channels within the group
|
||||
*/
|
||||
static int
|
||||
ajax_chgroup_editor(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_chgroup_editor(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_channel_t *ch;
|
||||
th_channel_group_t *tcg;
|
||||
|
||||
if(remain == NULL || (tcg = channel_group_by_tag(atoi(remain))) == NULL)
|
||||
return HTTP_STATUS_BAD_REQUEST;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, tcg->tcg_name);
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, tcg->tcg_name);
|
||||
|
||||
tcp_qprintf(&tq, "<ul id=\"channellist\" class=\"draglist\">");
|
||||
tcp_qprintf(tq, "<ul id=\"channellist\" class=\"draglist\">");
|
||||
|
||||
TAILQ_FOREACH(ch, &tcg->tcg_channels, ch_group_link) {
|
||||
tcp_qprintf(&tq, "<li id=\"ch_%d\">", ch->ch_tag);
|
||||
tcp_qprintf(tq, "<li id=\"ch_%d\">", ch->ch_tag);
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
|
||||
ajax_box_begin(tq, AJAX_BOX_BORDER, NULL, NULL, NULL);
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"overflow: auto; width: 100%\">");
|
||||
tcp_qprintf(tq, "<div style=\"overflow: auto; width: 100%\">");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"float: left; width: 100%\">"
|
||||
"<a href=\"javascript:void(0)\" >"
|
||||
"%s</a>"
|
||||
"</div>",
|
||||
ch->ch_name);
|
||||
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
ajax_box_end(&tq, AJAX_BOX_BORDER);
|
||||
tcp_qprintf(&tq, "</li>");
|
||||
tcp_qprintf(tq, "</div>");
|
||||
ajax_box_end(tq, AJAX_BOX_BORDER);
|
||||
tcp_qprintf(tq, "</li>");
|
||||
}
|
||||
|
||||
tcp_qprintf(&tq, "</ul>");
|
||||
tcp_qprintf(tq, "</ul>");
|
||||
|
||||
ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
|
||||
ajax_box_end(tq, AJAX_BOX_SIDEBOX);
|
||||
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,38 +68,37 @@ tdmi_displayname(th_dvb_mux_instance_t *tdmi, char *buf, size_t len)
|
|||
* Adapter summary
|
||||
*/
|
||||
static int
|
||||
ajax_adaptersummary(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_adaptersummary(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_dvb_adapter_t *tda;
|
||||
char dispname[20];
|
||||
|
||||
if(remain == NULL || (tda = dvb_adapter_find_by_identifier(remain)) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
snprintf(dispname, sizeof(dispname), "%s", tda->tda_displayname);
|
||||
strcpy(dispname + sizeof(dispname) - 4, "...");
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, dispname);
|
||||
ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, dispname);
|
||||
|
||||
tcp_qprintf(&tq, "<div class=\"infoprefix\">Status:</div>"
|
||||
tcp_qprintf(tq, "<div class=\"infoprefix\">Status:</div>"
|
||||
"<div>%s</div>",
|
||||
val2str(tda->tda_state, adapterstatus) ?: "invalid");
|
||||
tcp_qprintf(&tq, "<div class=\"infoprefix\">Type:</div>"
|
||||
tcp_qprintf(tq, "<div class=\"infoprefix\">Type:</div>"
|
||||
"<div>%s</div>",
|
||||
dvb_adaptertype_to_str(tda->tda_fe_info->type));
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"text-align: center\">"
|
||||
tcp_qprintf(tq, "<div style=\"text-align: center\">"
|
||||
"<a href=\"javascript:void(0);\" "
|
||||
"onClick=\"new Ajax.Updater('dvbadaptereditor', "
|
||||
"'/ajax/dvbadaptereditor/%s', "
|
||||
"{method: 'get', evalScripts: true})\""
|
||||
"\">Edit</a></div>", tda->tda_identifier);
|
||||
ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
|
||||
ajax_box_end(tq, AJAX_BOX_SIDEBOX);
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -108,29 +107,27 @@ ajax_adaptersummary(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* DVB configuration
|
||||
*/
|
||||
int
|
||||
ajax_config_dvb_tab(http_connection_t *hc)
|
||||
ajax_config_dvb_tab(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_dvb_adapter_t *tda;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"overflow: auto; width: 100%\">");
|
||||
tcp_qprintf(tq, "<div style=\"overflow: auto; width: 100%\">");
|
||||
|
||||
LIST_FOREACH(tda, &dvb_adapters, tda_global_link) {
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"summary_%s\" "
|
||||
tcp_qprintf(tq, "<div id=\"summary_%s\" "
|
||||
"style=\"float:left; width: 250px\"></div>",
|
||||
tda->tda_identifier);
|
||||
|
||||
ajax_js(&tq, "new Ajax.Updater('summary_%s', "
|
||||
ajax_js(tq, "new Ajax.Updater('summary_%s', "
|
||||
"'/ajax/dvbadaptersummary/%s', {method: 'get'})",
|
||||
tda->tda_identifier, tda->tda_identifier);
|
||||
|
||||
}
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
tcp_qprintf(&tq, "<div id=\"dvbadaptereditor\"></div>");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
tcp_qprintf(tq, "</div>");
|
||||
tcp_qprintf(tq, "<div id=\"dvbadaptereditor\"></div>");
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -159,28 +156,27 @@ dvb_make_add_link(tcp_queue_t *tq, th_dvb_adapter_t *tda, const char *result)
|
|||
* DVB adapter editor pane
|
||||
*/
|
||||
static int
|
||||
ajax_adaptereditor(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_adaptereditor(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_dvb_adapter_t *tda;
|
||||
float a, b, c;
|
||||
|
||||
if(remain == NULL || (tda = dvb_adapter_find_by_identifier(remain)) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
ajax_box_begin(tq, AJAX_BOX_FILLED, NULL, NULL, NULL);
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_FILLED, NULL, NULL, NULL);
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"text-align: center; font-weight: bold\">%s</div>",
|
||||
tda->tda_displayname);
|
||||
|
||||
ajax_box_end(&tq, AJAX_BOX_FILLED);
|
||||
ajax_box_end(tq, AJAX_BOX_FILLED);
|
||||
|
||||
/* Type */
|
||||
|
||||
tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Model:</div>"
|
||||
tcp_qprintf(tq, "<div class=\"infoprefixwide\">Model:</div>"
|
||||
"<div>%s (%s)</div>",
|
||||
tda->tda_fe_info->name,
|
||||
dvb_adaptertype_to_str(tda->tda_fe_info->type));
|
||||
|
@ -200,13 +196,13 @@ ajax_adaptereditor(http_connection_t *hc, const char *remain, void *opaque)
|
|||
break;
|
||||
}
|
||||
|
||||
tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Freq. Range:</div>"
|
||||
tcp_qprintf(tq, "<div class=\"infoprefixwide\">Freq. Range:</div>"
|
||||
"<div>%.2f - %.2f kHz, in steps of %.2f kHz</div>",
|
||||
a, b, c);
|
||||
|
||||
|
||||
if(tda->tda_fe_info->symbol_rate_min) {
|
||||
tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Symbolrate:</div>"
|
||||
tcp_qprintf(tq, "<div class=\"infoprefixwide\">Symbolrate:</div>"
|
||||
"<div>%d - %d BAUD</div>",
|
||||
tda->tda_fe_info->symbol_rate_min,
|
||||
tda->tda_fe_info->symbol_rate_max);
|
||||
|
@ -216,34 +212,34 @@ ajax_adaptereditor(http_connection_t *hc, const char *remain, void *opaque)
|
|||
/* Capabilities */
|
||||
|
||||
|
||||
// tcp_qprintf(&tq, "<div class=\"infoprefixwide\">Capabilities:</div>");
|
||||
// tcp_qprintf(tq, "<div class=\"infoprefixwide\">Capabilities:</div>");
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"float: left; width:45%\">");
|
||||
tcp_qprintf(tq, "<div style=\"float: left; width:45%\">");
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, "Multiplexes");
|
||||
ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, "Multiplexes");
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"dvbmuxlist%s\"></div>",
|
||||
tcp_qprintf(tq, "<div id=\"dvbmuxlist%s\"></div>",
|
||||
tda->tda_identifier);
|
||||
|
||||
ajax_js(&tq,
|
||||
ajax_js(tq,
|
||||
"new Ajax.Updater('dvbmuxlist%s', "
|
||||
"'/ajax/dvbadaptermuxlist/%s', {method: 'get'}) ",
|
||||
tda->tda_identifier, tda->tda_identifier);
|
||||
|
||||
tcp_qprintf(&tq, "<hr><div id=\"addmux\">");
|
||||
dvb_make_add_link(&tq, tda, NULL);
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
tcp_qprintf(tq, "<hr><div id=\"addmux\">");
|
||||
dvb_make_add_link(tq, tda, NULL);
|
||||
tcp_qprintf(tq, "</div>");
|
||||
|
||||
ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
ajax_box_end(tq, AJAX_BOX_SIDEBOX);
|
||||
tcp_qprintf(tq, "</div>");
|
||||
|
||||
/* Div for displaying services */
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"servicepane\" "
|
||||
tcp_qprintf(tq, "<div id=\"servicepane\" "
|
||||
"style=\"float: left; width:55%\">");
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
tcp_qprintf(tq, "</div>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -252,9 +248,10 @@ ajax_adaptereditor(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* DVB adapter add mux
|
||||
*/
|
||||
static int
|
||||
ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_adapteraddmux(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_dvb_adapter_t *tda;
|
||||
int caps;
|
||||
int fetype;
|
||||
|
@ -266,13 +263,11 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
caps = tda->tda_fe_info->caps;
|
||||
fetype = tda->tda_fe_info->type;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
tcp_qprintf(&tq, "<div style=\"text-align: center; font-weight: bold\">"
|
||||
tcp_qprintf(tq, "<div style=\"text-align: center; font-weight: bold\">"
|
||||
"Add new %s mux</div>",
|
||||
dvb_adaptertype_to_str(tda->tda_fe_info->type));
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Frequency (%s):</div>"
|
||||
"<div>"
|
||||
"<input class=\"textinput\" type=\"text\" id=\"freq\">"
|
||||
|
@ -287,7 +282,7 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
if(fetype == FE_QAM || fetype == FE_QPSK) {
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Symbolrate:</div>"
|
||||
"<div>"
|
||||
"<input class=\"textinput\" type=\"text\" id=\"symrate\">"
|
||||
|
@ -300,15 +295,15 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
/* Bandwidth */
|
||||
|
||||
if(fetype == FE_OFDM) {
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Bandwidth:</div>"
|
||||
"<div><select id=\"bw\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_BANDWIDTH_AUTO, "AUTO");
|
||||
add_option(&tq, 1 , "8MHz");
|
||||
add_option(&tq, 1 , "7MHz");
|
||||
add_option(&tq, 1 , "6MHz");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_BANDWIDTH_AUTO, "AUTO");
|
||||
add_option(tq, 1 , "8MHz");
|
||||
add_option(tq, 1 , "7MHz");
|
||||
add_option(tq, 1 , "6MHz");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", bw: $F('bw')");
|
||||
|
@ -318,19 +313,19 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
/* Constellation */
|
||||
|
||||
if(fetype == FE_QAM || fetype == FE_OFDM) {
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Constellation:</div>"
|
||||
"<div><select id=\"const\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_QAM_AUTO, "AUTO");
|
||||
add_option(&tq, caps & FE_CAN_QPSK, "QPSK");
|
||||
add_option(&tq, caps & FE_CAN_QAM_16, "QAM16");
|
||||
add_option(&tq, caps & FE_CAN_QAM_32, "QAM32");
|
||||
add_option(&tq, caps & FE_CAN_QAM_64, "QAM64");
|
||||
add_option(&tq, caps & FE_CAN_QAM_128, "QAM128");
|
||||
add_option(&tq, caps & FE_CAN_QAM_256, "QAM256");
|
||||
add_option(tq, caps & FE_CAN_QAM_AUTO, "AUTO");
|
||||
add_option(tq, caps & FE_CAN_QPSK, "QPSK");
|
||||
add_option(tq, caps & FE_CAN_QAM_16, "QAM16");
|
||||
add_option(tq, caps & FE_CAN_QAM_32, "QAM32");
|
||||
add_option(tq, caps & FE_CAN_QAM_64, "QAM64");
|
||||
add_option(tq, caps & FE_CAN_QAM_128, "QAM128");
|
||||
add_option(tq, caps & FE_CAN_QAM_256, "QAM256");
|
||||
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", const: $F('const')");
|
||||
|
@ -340,33 +335,33 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
/* FEC */
|
||||
|
||||
if(fetype == FE_QAM || fetype == FE_QPSK) {
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">FEC:</div>"
|
||||
"<div><select id=\"fec\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_FEC_AUTO, "AUTO");
|
||||
add_option(&tq, caps & FE_CAN_FEC_1_2, "1/2");
|
||||
add_option(&tq, caps & FE_CAN_FEC_2_3, "2/3");
|
||||
add_option(&tq, caps & FE_CAN_FEC_3_4, "3/4");
|
||||
add_option(&tq, caps & FE_CAN_FEC_4_5, "4/5");
|
||||
add_option(&tq, caps & FE_CAN_FEC_5_6, "5/6");
|
||||
add_option(&tq, caps & FE_CAN_FEC_6_7, "6/7");
|
||||
add_option(&tq, caps & FE_CAN_FEC_7_8, "7/8");
|
||||
add_option(&tq, caps & FE_CAN_FEC_8_9, "8/9");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_FEC_AUTO, "AUTO");
|
||||
add_option(tq, caps & FE_CAN_FEC_1_2, "1/2");
|
||||
add_option(tq, caps & FE_CAN_FEC_2_3, "2/3");
|
||||
add_option(tq, caps & FE_CAN_FEC_3_4, "3/4");
|
||||
add_option(tq, caps & FE_CAN_FEC_4_5, "4/5");
|
||||
add_option(tq, caps & FE_CAN_FEC_5_6, "5/6");
|
||||
add_option(tq, caps & FE_CAN_FEC_6_7, "6/7");
|
||||
add_option(tq, caps & FE_CAN_FEC_7_8, "7/8");
|
||||
add_option(tq, caps & FE_CAN_FEC_8_9, "8/9");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", fec: $F('fec')");
|
||||
}
|
||||
|
||||
if(fetype == FE_QPSK) {
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Polarisation:</div>"
|
||||
"<div><select id=\"pol\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, 1, "Vertical");
|
||||
add_option(&tq, 1, "Horizontal");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, 1, "Vertical");
|
||||
add_option(tq, 1, "Horizontal");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", pol: $F('pol')");
|
||||
|
@ -376,44 +371,44 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
|
||||
if(fetype == FE_OFDM) {
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Transmission mode:</div>"
|
||||
"<div><select id=\"tmode\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_TRANSMISSION_MODE_AUTO, "AUTO");
|
||||
add_option(&tq, 1 , "2k");
|
||||
add_option(&tq, 1 , "8k");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_TRANSMISSION_MODE_AUTO, "AUTO");
|
||||
add_option(tq, 1 , "2k");
|
||||
add_option(tq, 1 , "8k");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", tmode: $F('tmode')");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Guard interval:</div>"
|
||||
"<div><select id=\"guard\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_GUARD_INTERVAL_AUTO, "AUTO");
|
||||
add_option(&tq, 1 , "1/32");
|
||||
add_option(&tq, 1 , "1/16");
|
||||
add_option(&tq, 1 , "1/8");
|
||||
add_option(&tq, 1 , "1/4");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_GUARD_INTERVAL_AUTO, "AUTO");
|
||||
add_option(tq, 1 , "1/32");
|
||||
add_option(tq, 1 , "1/16");
|
||||
add_option(tq, 1 , "1/8");
|
||||
add_option(tq, 1 , "1/4");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", guard: $F('guard')");
|
||||
|
||||
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Hierarchy:</div>"
|
||||
"<div><select id=\"hier\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_HIERARCHY_AUTO, "AUTO");
|
||||
add_option(&tq, 1 , "1");
|
||||
add_option(&tq, 1 , "2");
|
||||
add_option(&tq, 1 , "4");
|
||||
add_option(&tq, 1 , "NONE");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_HIERARCHY_AUTO, "AUTO");
|
||||
add_option(tq, 1 , "1");
|
||||
add_option(tq, 1 , "2");
|
||||
add_option(tq, 1 , "4");
|
||||
add_option(tq, 1 , "NONE");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
|
@ -421,45 +416,45 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">FEC Hi:</div>"
|
||||
"<div><select id=\"fechi\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_FEC_AUTO, "AUTO");
|
||||
add_option(&tq, caps & FE_CAN_FEC_1_2, "1/2");
|
||||
add_option(&tq, caps & FE_CAN_FEC_2_3, "2/3");
|
||||
add_option(&tq, caps & FE_CAN_FEC_3_4, "3/4");
|
||||
add_option(&tq, caps & FE_CAN_FEC_4_5, "4/5");
|
||||
add_option(&tq, caps & FE_CAN_FEC_5_6, "5/6");
|
||||
add_option(&tq, caps & FE_CAN_FEC_6_7, "6/7");
|
||||
add_option(&tq, caps & FE_CAN_FEC_7_8, "7/8");
|
||||
add_option(&tq, caps & FE_CAN_FEC_8_9, "8/9");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_FEC_AUTO, "AUTO");
|
||||
add_option(tq, caps & FE_CAN_FEC_1_2, "1/2");
|
||||
add_option(tq, caps & FE_CAN_FEC_2_3, "2/3");
|
||||
add_option(tq, caps & FE_CAN_FEC_3_4, "3/4");
|
||||
add_option(tq, caps & FE_CAN_FEC_4_5, "4/5");
|
||||
add_option(tq, caps & FE_CAN_FEC_5_6, "5/6");
|
||||
add_option(tq, caps & FE_CAN_FEC_6_7, "6/7");
|
||||
add_option(tq, caps & FE_CAN_FEC_7_8, "7/8");
|
||||
add_option(tq, caps & FE_CAN_FEC_8_9, "8/9");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", fechi: $F('fechi')");
|
||||
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">FEC Low:</div>"
|
||||
"<div><select id=\"feclo\" class=\"textinput\">");
|
||||
|
||||
add_option(&tq, caps & FE_CAN_FEC_AUTO, "AUTO");
|
||||
add_option(&tq, caps & FE_CAN_FEC_1_2, "1/2");
|
||||
add_option(&tq, caps & FE_CAN_FEC_2_3, "2/3");
|
||||
add_option(&tq, caps & FE_CAN_FEC_3_4, "3/4");
|
||||
add_option(&tq, caps & FE_CAN_FEC_4_5, "4/5");
|
||||
add_option(&tq, caps & FE_CAN_FEC_5_6, "5/6");
|
||||
add_option(&tq, caps & FE_CAN_FEC_6_7, "6/7");
|
||||
add_option(&tq, caps & FE_CAN_FEC_7_8, "7/8");
|
||||
add_option(&tq, caps & FE_CAN_FEC_8_9, "8/9");
|
||||
tcp_qprintf(&tq, "</select></div>");
|
||||
add_option(tq, caps & FE_CAN_FEC_AUTO, "AUTO");
|
||||
add_option(tq, caps & FE_CAN_FEC_1_2, "1/2");
|
||||
add_option(tq, caps & FE_CAN_FEC_2_3, "2/3");
|
||||
add_option(tq, caps & FE_CAN_FEC_3_4, "3/4");
|
||||
add_option(tq, caps & FE_CAN_FEC_4_5, "4/5");
|
||||
add_option(tq, caps & FE_CAN_FEC_5_6, "5/6");
|
||||
add_option(tq, caps & FE_CAN_FEC_6_7, "6/7");
|
||||
add_option(tq, caps & FE_CAN_FEC_7_8, "7/8");
|
||||
add_option(tq, caps & FE_CAN_FEC_8_9, "8/9");
|
||||
tcp_qprintf(tq, "</select></div>");
|
||||
|
||||
snprintf(params + strlen(params), sizeof(params) - strlen(params),
|
||||
", feclo: $F('feclo')");
|
||||
}
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"text-align: center\">"
|
||||
"<input type=\"button\" value=\"Create\" "
|
||||
"onClick=\"new Ajax.Updater('addmux', "
|
||||
|
@ -468,7 +463,7 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
"\">"
|
||||
"</div>", tda->tda_identifier, params);
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -476,13 +471,12 @@ ajax_adapteraddmux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
*
|
||||
*/
|
||||
static int
|
||||
ajax_adaptercreatemux_fail(http_connection_t *hc, th_dvb_adapter_t *tda,
|
||||
const char *errmsg)
|
||||
ajax_adaptercreatemux_fail(http_connection_t *hc, http_reply_t *hr,
|
||||
th_dvb_adapter_t *tda, const char *errmsg)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_init_queue(&tq, -1);
|
||||
dvb_make_add_link(&tq, tda, errmsg);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
dvb_make_add_link(tq, tda, errmsg);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -490,9 +484,10 @@ ajax_adaptercreatemux_fail(http_connection_t *hc, th_dvb_adapter_t *tda,
|
|||
* DVB adapter create mux (come here on POST after addmux query)
|
||||
*/
|
||||
static int
|
||||
ajax_adaptercreatemux(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_adaptercreatemux(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq;
|
||||
th_dvb_adapter_t *tda;
|
||||
const char *v;
|
||||
|
||||
|
@ -514,17 +509,17 @@ ajax_adaptercreatemux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
http_arg_get(&hc->hc_req_args, "port"), 1);
|
||||
|
||||
if(v != NULL)
|
||||
return ajax_adaptercreatemux_fail(hc, tda, v);
|
||||
return ajax_adaptercreatemux_fail(hc, hr, tda, v);
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
dvb_make_add_link(&tq, tda, "Successfully created");
|
||||
tq = &hr->hr_tq;
|
||||
dvb_make_add_link(tq, tda, "Successfully created");
|
||||
|
||||
ajax_js(&tq,
|
||||
ajax_js(tq,
|
||||
"new Ajax.Updater('dvbmuxlist%s', "
|
||||
"'/ajax/dvbadaptermuxlist/%s', {method: 'get'}) ",
|
||||
tda->tda_identifier, tda->tda_identifier);
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -533,10 +528,11 @@ ajax_adaptercreatemux(http_connection_t *hc, const char *remain, void *opaque)
|
|||
* Return a list of all muxes on the given adapter
|
||||
*/
|
||||
static int
|
||||
ajax_adaptermuxlist(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_adaptermuxlist(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
th_dvb_adapter_t *tda;
|
||||
char buf[50], buf2[500], buf3[20];
|
||||
const char *txt;
|
||||
|
@ -555,32 +551,30 @@ ajax_adaptermuxlist(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
fetype = tda->tda_fe_info->type;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
/* List of muxes */
|
||||
|
||||
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
|
||||
nmuxes++;
|
||||
|
||||
ajax_table_header(hc, &tq,
|
||||
ajax_table_header(hc, tq,
|
||||
(const char *[])
|
||||
{"Freq", "Status", "State", "Name", "Services", NULL},
|
||||
(int[]){3,3,2,4,2},
|
||||
nmuxes > displines,
|
||||
csize);
|
||||
|
||||
tcp_qprintf(&tq, "<hr>");
|
||||
tcp_qprintf(tq, "<hr>");
|
||||
|
||||
v = displines;
|
||||
if(nmuxes < displines)
|
||||
v = nmuxes;
|
||||
|
||||
tcp_qprintf(&tq, "<div id=\"dvbmuxlist%s\" "
|
||||
tcp_qprintf(tq, "<div id=\"dvbmuxlist%s\" "
|
||||
"style=\"height: %dpx; overflow: auto\" class=\"normallist\">",
|
||||
tda->tda_identifier, v * 14);
|
||||
|
||||
if(nmuxes == 0) {
|
||||
tcp_qprintf(&tq, "<div style=\"text-align: center\">"
|
||||
tcp_qprintf(tq, "<div style=\"text-align: center\">"
|
||||
"No muxes configured</div>");
|
||||
} else LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) {
|
||||
|
||||
|
@ -620,12 +614,12 @@ ajax_adaptermuxlist(http_connection_t *hc, const char *remain, void *opaque)
|
|||
cells[4] = buf3;
|
||||
cells[5] = NULL;
|
||||
|
||||
ajax_table_row(&tq, cells, csize, &o);
|
||||
ajax_table_row(tq, cells, csize, &o);
|
||||
|
||||
}
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
tcp_qprintf(tq, "</div>");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -642,10 +636,11 @@ dvbsvccmp(th_transport_t *a, th_transport_t *b)
|
|||
* Display detailes about a mux
|
||||
*/
|
||||
static int
|
||||
ajax_dvbmuxeditor(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_dvbmuxeditor(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_dvb_mux_instance_t *tdmi;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
char buf[1000];
|
||||
th_transport_t *t;
|
||||
struct th_transport_list head;
|
||||
|
@ -654,8 +649,6 @@ ajax_dvbmuxeditor(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if(remain == NULL || (tdmi = dvb_mux_find_by_identifier(remain)) == NULL)
|
||||
return HTTP_STATUS_NOT_FOUND;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
tdmi_displayname(tdmi, buf, sizeof(buf));
|
||||
|
||||
LIST_INIT(&head);
|
||||
|
@ -667,11 +660,11 @@ ajax_dvbmuxeditor(http_connection_t *hc, const char *remain, void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
ajax_box_begin(&tq, AJAX_BOX_SIDEBOX, NULL, NULL, buf);
|
||||
ajax_transport_build_list(hc, &tq, &head, n);
|
||||
ajax_box_end(&tq, AJAX_BOX_SIDEBOX);
|
||||
ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, buf);
|
||||
ajax_transport_build_list(hc, tq, &head, n);
|
||||
ajax_box_end(tq, AJAX_BOX_SIDEBOX);
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -282,12 +282,12 @@ ajax_transport_build_list(http_connection_t *hc, tcp_queue_t *tq,
|
|||
* Rename of unmapped channel
|
||||
*/
|
||||
static int
|
||||
ajax_transport_rename_channel(http_connection_t *hc,
|
||||
ajax_transport_rename_channel(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_transport_t *t;
|
||||
const char *newname, *v;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
char buf[1000];
|
||||
|
||||
if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL)
|
||||
|
@ -299,8 +299,6 @@ ajax_transport_rename_channel(http_connection_t *hc,
|
|||
free((void *)t->tht_channelname);
|
||||
t->tht_channelname = strdup(newname);
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
v = newname;
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
|
@ -308,9 +306,9 @@ ajax_transport_rename_channel(http_connection_t *hc,
|
|||
"'/ajax/transport_rename_channel/%s', '%s')",
|
||||
t->tht_identifier, t->tht_identifier, v);
|
||||
|
||||
ajax_a_jsfunc(&tq, v, buf, "");
|
||||
ajax_a_jsfunc(tq, v, buf, "");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
http_output_html(hc, hr);
|
||||
t->tht_config_change(t);
|
||||
return 0;
|
||||
}
|
||||
|
@ -361,10 +359,11 @@ dvb_unmap_channel(th_transport_t *t, tcp_queue_t *tq)
|
|||
*
|
||||
*/
|
||||
int
|
||||
ajax_transport_op(http_connection_t *hc, const char *remain, void *opaque)
|
||||
ajax_transport_op(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
th_transport_t *t;
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
const char *op;
|
||||
|
||||
if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL)
|
||||
|
@ -373,20 +372,18 @@ ajax_transport_op(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if((op = http_arg_get(&hc->hc_req_args, "action")) == NULL)
|
||||
return HTTP_STATUS_BAD_REQUEST;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
if(!strcmp(op, "toggle")) {
|
||||
if(t->tht_channel)
|
||||
dvb_unmap_channel(t, &tq);
|
||||
dvb_unmap_channel(t, tq);
|
||||
else
|
||||
dvb_map_channel(t, &tq);
|
||||
dvb_map_channel(t, tq);
|
||||
} else if(!strcmp(op, "map") && t->tht_channel == NULL) {
|
||||
dvb_map_channel(t, &tq);
|
||||
dvb_map_channel(t, tq);
|
||||
} else if(!strcmp(op, "unmap") && t->tht_channel != NULL) {
|
||||
dvb_unmap_channel(t, &tq);
|
||||
dvb_unmap_channel(t, tq);
|
||||
}
|
||||
|
||||
http_output_queue(hc, &tq, "text/javascript; charset=UTF-8", 0);
|
||||
http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0);
|
||||
|
||||
t->tht_config_change(t);
|
||||
return 0;
|
||||
|
|
367
http.c
367
http.c
|
@ -149,218 +149,269 @@ static const char *cachemonths[12] = {
|
|||
};
|
||||
|
||||
/**
|
||||
* If current version mandates it, send a HTTP reply header back
|
||||
*
|
||||
*/
|
||||
static void
|
||||
http_output_reply_header(http_connection_t *hc, int rc, int maxage)
|
||||
http_destroy_reply(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
if(hr->hr_destroy != NULL)
|
||||
hr->hr_destroy(hr, hr->hr_opaque);
|
||||
|
||||
TAILQ_REMOVE(&hc->hc_replies, hr, hr_link);
|
||||
free(hr->hr_location);
|
||||
tcp_flush_queue(&hr->hr_tq);
|
||||
free(hr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit a HTTP reply
|
||||
*
|
||||
* Return non-zero if we should disconnect (no more keep-alive)
|
||||
*/
|
||||
static int
|
||||
http_send_reply(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
struct tm tm0, *tm;
|
||||
time_t t;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
int r;
|
||||
|
||||
if(hc->hc_version < HTTP_VERSION_1_0)
|
||||
return;
|
||||
|
||||
http_printf(hc, "%s %d %s\r\n", val2str(hc->hc_version, HTTP_versiontab),
|
||||
rc, http_rc2str(rc));
|
||||
if(hr->hr_version > HTTP_VERSION_1_0) {
|
||||
http_printf(hc, "%s %d %s\r\n", val2str(hr->hr_version, HTTP_versiontab),
|
||||
hr->hr_rc, http_rc2str(hr->hr_rc));
|
||||
|
||||
if(maxage == 0) {
|
||||
http_printf(hc, "Cache-Control: no-cache\r\n");
|
||||
} else {
|
||||
t = dispatch_clock;
|
||||
http_printf(hc, "Server: HTS/tvheadend\r\n");
|
||||
|
||||
if(hr->hr_maxage == 0) {
|
||||
http_printf(hc, "Cache-Control: no-cache\r\n");
|
||||
} else {
|
||||
t = dispatch_clock;
|
||||
|
||||
tm = gmtime_r(&t, &tm0);
|
||||
http_printf(hc,
|
||||
"Last-Modified: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
|
||||
cachedays[tm->tm_wday], tm->tm_year + 1900,
|
||||
cachemonths[tm->tm_mon], tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
t += hr->hr_maxage;
|
||||
|
||||
tm = gmtime_r(&t, &tm0);
|
||||
http_printf(hc,
|
||||
"Expires: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
|
||||
cachedays[tm->tm_wday], tm->tm_year + 1900,
|
||||
cachemonths[tm->tm_mon], tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
http_printf(hc, "Cache-Control: max-age=%d\r\n", hr->hr_maxage);
|
||||
}
|
||||
|
||||
http_printf(hc, "Connection: %s\r\n",
|
||||
hr->hr_keep_alive ? "Keep-Alive" : "Close");
|
||||
|
||||
if(hr->hr_rc == HTTP_STATUS_UNAUTHORIZED)
|
||||
http_printf(hc, "WWW-Authenticate: Basic realm=\"tvheadend\"\r\n");
|
||||
|
||||
if(hr->hr_encoding != NULL)
|
||||
http_printf(hc, "Content-Encoding: %s\r\n", hr->hr_encoding);
|
||||
|
||||
if(hr->hr_location != NULL)
|
||||
http_printf(hc, "Location: %s\r\n", hr->hr_location);
|
||||
|
||||
tm = gmtime_r(&t, &tm0);
|
||||
http_printf(hc,
|
||||
"Last-Modified: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
|
||||
cachedays[tm->tm_wday], tm->tm_year + 1900,
|
||||
cachemonths[tm->tm_mon], tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
t += maxage;
|
||||
|
||||
tm = gmtime_r(&t, &tm0);
|
||||
http_printf(hc,
|
||||
"Expires: %s, %02d %s %d %02d:%02d:%02d GMT\r\n",
|
||||
cachedays[tm->tm_wday], tm->tm_year + 1900,
|
||||
cachemonths[tm->tm_mon], tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
http_printf(hc, "Cache-Control: max-age=%d\r\n", maxage);
|
||||
"Content-Type: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n",
|
||||
hr->hr_content, tq->tq_depth);
|
||||
}
|
||||
tcp_output_queue(&hc->hc_tcp_session, NULL, tq);
|
||||
|
||||
http_printf(hc, "Server: HTS/tvheadend\r\n");
|
||||
http_printf(hc, "Connection: %s\r\n",
|
||||
hc->hc_keep_alive ? "Keep-Alive" : "Close");
|
||||
r = !hr->hr_keep_alive;
|
||||
|
||||
http_destroy_reply(hc, hr);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send HTTP replies
|
||||
*
|
||||
* Return non-zero if we should disconnect
|
||||
*/
|
||||
static int
|
||||
http_xmit_queue(http_connection_t *hc)
|
||||
{
|
||||
http_reply_t *hr;
|
||||
|
||||
while((hr = TAILQ_FIRST(&hc->hc_replies)) != NULL) {
|
||||
if(hr->hr_destroy != NULL)
|
||||
break; /* Pending reply, cannot send this yet */
|
||||
if(http_send_reply(hc, hr))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send HTTP error back
|
||||
*/
|
||||
void
|
||||
http_error(http_connection_t *hc, int error)
|
||||
http_error(http_connection_t *hc, http_reply_t *hr, int error)
|
||||
{
|
||||
char ret[300];
|
||||
const char *errtxt = http_rc2str(error);
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
http_output_reply_header(hc, error, 0);
|
||||
tcp_flush_queue(tq);
|
||||
|
||||
snprintf(ret, sizeof(ret),
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
|
||||
"<HTML><HEAD>\r\n"
|
||||
"<TITLE>%d %s</TITLE>\r\n"
|
||||
"</HEAD><BODY>\r\n"
|
||||
"<H1>%d %s</H1>\r\n"
|
||||
"</BODY></HTML>\r\n",
|
||||
error, errtxt,
|
||||
error, errtxt);
|
||||
tcp_qprintf(tq,
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
|
||||
"<HTML><HEAD>\r\n"
|
||||
"<TITLE>%d %s</TITLE>\r\n"
|
||||
"</HEAD><BODY>\r\n"
|
||||
"<H1>%d %s</H1>\r\n"
|
||||
"</BODY></HTML>\r\n",
|
||||
error, errtxt, error, errtxt);
|
||||
|
||||
if(hc->hc_version >= HTTP_VERSION_1_0) {
|
||||
if(error == HTTP_STATUS_UNAUTHORIZED)
|
||||
http_printf(hc, "WWW-Authenticate: Basic realm=\"tvheadend\"\r\n");
|
||||
|
||||
http_printf(hc, "Content-Type: text/html\r\n");
|
||||
http_printf(hc, "Content-Length: %d\r\n", strlen(ret));
|
||||
http_printf(hc, "\r\n");
|
||||
}
|
||||
http_printf(hc, "%s", ret);
|
||||
hr->hr_destroy = NULL;
|
||||
hr->hr_rc = error;
|
||||
hr->hr_content = "text/html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an HTTP OK and post data from a tcp queue
|
||||
* Send an HTTP OK
|
||||
*/
|
||||
void
|
||||
http_output_queue(http_connection_t *hc, tcp_queue_t *tq, const char *content,
|
||||
int maxage)
|
||||
http_output(http_connection_t *hc, http_reply_t *hr, const char *content,
|
||||
const char *encoding, int maxage)
|
||||
{
|
||||
http_output_reply_header(hc, 200, maxage);
|
||||
|
||||
if(hc->hc_version >= HTTP_VERSION_1_0) {
|
||||
http_printf(hc,
|
||||
"Content-Type: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n",
|
||||
content, tq->tq_depth);
|
||||
}
|
||||
|
||||
tcp_output_queue(&hc->hc_tcp_session, NULL, tq);
|
||||
hr->hr_encoding = encoding;
|
||||
hr->hr_content = content;
|
||||
hr->hr_maxage = maxage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an HTTP OK and post data from a tcp queue
|
||||
* Send an HTTP OK, simple version for text/html
|
||||
*/
|
||||
static void
|
||||
http_output_queue_encoding(http_connection_t *hc, tcp_queue_t *tq,
|
||||
const char *content, int maxage,
|
||||
const char *encoding)
|
||||
void
|
||||
http_output_html(http_connection_t *hc, http_reply_t *hr)
|
||||
{
|
||||
http_output_reply_header(hc, 200, maxage);
|
||||
|
||||
if(hc->hc_version >= HTTP_VERSION_1_0) {
|
||||
http_printf(hc,
|
||||
"Content-Encoding: %s\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n",
|
||||
encoding, content, tq->tq_depth);
|
||||
}
|
||||
|
||||
tcp_output_queue(&hc->hc_tcp_session, NULL, tq);
|
||||
hr->hr_content = "text/html; charset=UTF-8";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send an HTTP REDIRECT
|
||||
*/
|
||||
int
|
||||
http_redirect(http_connection_t *hc, const char *location)
|
||||
void
|
||||
http_redirect(http_connection_t *hc, http_reply_t *hr, const char *location)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
http_output_reply_header(hc, 303, 0);
|
||||
tcp_qprintf(tq,
|
||||
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
|
||||
"<HTML><HEAD>\r\n"
|
||||
"<TITLE>Redirect</TITLE>\r\n"
|
||||
"</HEAD><BODY>\r\n"
|
||||
"Please follow <a href=\"%s\">%s</a>\r\n"
|
||||
"</BODY></HTML>\r\n",
|
||||
location, location);
|
||||
|
||||
if(hc->hc_version < HTTP_VERSION_1_0)
|
||||
return -1;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
tcp_qprintf(&tq, "Please follow <a href=\"%s\"\"></a>", location);
|
||||
|
||||
http_printf(hc,
|
||||
"Location: %s\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n", location, tq.tq_depth);
|
||||
tcp_output_queue(&hc->hc_tcp_session, NULL, &tq);
|
||||
return 0;
|
||||
hr->hr_location = strdup(location);
|
||||
hr->hr_rc = 303;
|
||||
hr->hr_content = "text/html";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute url callback
|
||||
*
|
||||
* Returns 1 if we should disconnect
|
||||
*
|
||||
*/
|
||||
static int
|
||||
http_exec(http_connection_t *hc, http_path_t *hp, char *remain, int err)
|
||||
{
|
||||
http_reply_t *hr = calloc(1, sizeof(http_reply_t));
|
||||
|
||||
/* Insert reply in order */
|
||||
TAILQ_INSERT_TAIL(&hc->hc_replies, hr, hr_link);
|
||||
|
||||
tcp_init_queue(&hr->hr_tq, -1);
|
||||
hr->hr_version = hc->hc_version;
|
||||
hr->hr_keep_alive = hc->hc_keep_alive;
|
||||
|
||||
if(!err)
|
||||
err = hp->hp_callback(hc, hr, remain, hp->hp_opaque);
|
||||
|
||||
if(err)
|
||||
http_error(hc, hr, err);
|
||||
|
||||
if(hr->hr_destroy != NULL)
|
||||
return 0; /* New entry is delayed, do not transmit anything */
|
||||
|
||||
return http_xmit_queue(hc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* HTTP GET
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
http_cmd_get(http_connection_t *hc)
|
||||
{
|
||||
http_path_t *hp;
|
||||
char *remain;
|
||||
char *args;
|
||||
int err;
|
||||
|
||||
hp = http_resolve(hc, &remain, &args);
|
||||
if(hp == NULL) {
|
||||
http_error(hc, HTTP_STATUS_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
if(hp == NULL)
|
||||
return http_exec(hc, NULL, NULL, HTTP_STATUS_NOT_FOUND);
|
||||
|
||||
if(args != NULL)
|
||||
http_parse_get_args(hc, args);
|
||||
|
||||
err = hp->hp_callback(hc, remain, hp->hp_opaque);
|
||||
if(err)
|
||||
http_error(hc, err);
|
||||
return http_exec(hc, hp, remain, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a HTTP POST is fully received, and if so, continue processing
|
||||
*
|
||||
* Return non-zero if we should disconnect
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
http_post_check(http_connection_t *hc)
|
||||
{
|
||||
http_path_t *hp;
|
||||
char *remain, *args, *v, *argv[2];
|
||||
int err, n;
|
||||
int n;
|
||||
|
||||
if(hc->hc_post_ptr != hc->hc_post_len)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
hc->hc_state = HTTP_CON_WAIT_REQUEST;
|
||||
|
||||
/* Parse content-type */
|
||||
v = http_arg_get(&hc->hc_args, "Content-Type");
|
||||
if(v == NULL) {
|
||||
http_error(hc, HTTP_STATUS_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
if(v == NULL)
|
||||
return http_exec(hc, NULL, NULL, HTTP_STATUS_BAD_REQUEST);
|
||||
|
||||
n = http_tokenize(v, argv, 2, ';');
|
||||
if(n == 0) {
|
||||
http_error(hc, HTTP_STATUS_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
if(n == 0)
|
||||
return http_exec(hc, NULL, NULL, HTTP_STATUS_BAD_REQUEST);
|
||||
|
||||
if(!strcmp(argv[0], "application/x-www-form-urlencoded"))
|
||||
http_parse_get_args(hc, hc->hc_post_data);
|
||||
|
||||
hp = http_resolve(hc, &remain, &args);
|
||||
if(hp == NULL) {
|
||||
http_error(hc, HTTP_STATUS_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
if(hp == NULL)
|
||||
return http_exec(hc, NULL, NULL, HTTP_STATUS_NOT_FOUND);
|
||||
|
||||
err = hp->hp_callback(hc, remain, hp->hp_opaque);
|
||||
if(err)
|
||||
http_error(hc, err);
|
||||
return http_exec(hc, hp, remain, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -368,27 +419,23 @@ http_post_check(http_connection_t *hc)
|
|||
|
||||
|
||||
/**
|
||||
* HTTP POST
|
||||
* Initial processing of HTTP POST
|
||||
*
|
||||
* Return non-zero if we should disconnect
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
http_cmd_post(http_connection_t *hc)
|
||||
{
|
||||
char *v;
|
||||
|
||||
/* Set keep-alive status */
|
||||
v = http_arg_get(&hc->hc_args, "Content-Length");
|
||||
if(v == NULL) {
|
||||
/* No content length in POST, make us disconnect */
|
||||
hc->hc_keep_alive = 0;
|
||||
return;
|
||||
}
|
||||
if(v == NULL)
|
||||
return 1; /* No content length in POST, make us disconnect */
|
||||
|
||||
hc->hc_post_len = atoi(v);
|
||||
if(hc->hc_post_len > 16 * 1024 * 1024) {
|
||||
/* Bail out if POST data > 16 Mb */
|
||||
hc->hc_keep_alive = 0;
|
||||
return;
|
||||
}
|
||||
if(hc->hc_post_len > 16 * 1024 * 1024)
|
||||
return 1; /* Bail out if POST data > 16 Mb */
|
||||
|
||||
hc->hc_state = HTTP_CON_POST_DATA;
|
||||
|
||||
|
@ -404,8 +451,7 @@ http_cmd_post(http_connection_t *hc)
|
|||
|
||||
hc->hc_post_ptr = tcp_line_drain(&hc->hc_tcp_session, hc->hc_post_data,
|
||||
hc->hc_post_len);
|
||||
|
||||
http_post_check(hc);
|
||||
return http_post_check(hc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -426,25 +472,23 @@ http_consume_post_data(http_connection_t *hc)
|
|||
}
|
||||
|
||||
hc->hc_post_ptr += r;
|
||||
http_post_check(hc);
|
||||
if(http_post_check(hc))
|
||||
tcp_disconnect(tcp, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a HTTP request
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
http_process_request(http_connection_t *hc)
|
||||
{
|
||||
switch(hc->hc_cmd) {
|
||||
default:
|
||||
http_error(hc, HTTP_STATUS_BAD_REQUEST);
|
||||
break;
|
||||
return http_exec(hc, NULL, NULL, HTTP_STATUS_BAD_REQUEST);
|
||||
case HTTP_CMD_GET:
|
||||
http_cmd_get(hc);
|
||||
break;
|
||||
return http_cmd_get(hc);
|
||||
case HTTP_CMD_POST:
|
||||
http_cmd_post(hc);
|
||||
break;
|
||||
return http_cmd_post(hc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,22 +562,22 @@ process_request(http_connection_t *hc)
|
|||
switch(hc->hc_version) {
|
||||
case RTSP_VERSION_1_0:
|
||||
rtsp_process_request(hc);
|
||||
break;
|
||||
return 0;
|
||||
|
||||
case HTTP_VERSION_0_9:
|
||||
case HTTP_VERSION_1_0:
|
||||
case HTTP_VERSION_1_1:
|
||||
http_process_request(hc);
|
||||
break;
|
||||
return http_process_request(hc) ? -1 : 0;
|
||||
}
|
||||
|
||||
return hc->hc_keep_alive == 0 ? -1 : 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* HTTP connection state machine & parser
|
||||
*
|
||||
* If we return non zero we will disconnect
|
||||
*/
|
||||
static int
|
||||
http_con_parse(void *aux, char *buf)
|
||||
|
@ -615,6 +659,11 @@ http_con_parse(void *aux, char *buf)
|
|||
static void
|
||||
http_disconnect(http_connection_t *hc)
|
||||
{
|
||||
http_reply_t *hr;
|
||||
|
||||
while((hr = TAILQ_FIRST(&hc->hc_replies)) != NULL)
|
||||
http_destroy_reply(hc, hr);
|
||||
|
||||
free(hc->hc_post_data);
|
||||
free(hc->hc_username);
|
||||
free(hc->hc_password);
|
||||
|
@ -636,6 +685,7 @@ http_tcp_callback(tcpevent_t event, void *tcpsession)
|
|||
|
||||
switch(event) {
|
||||
case TCP_CONNECT:
|
||||
TAILQ_INIT(&hc->hc_replies);
|
||||
TAILQ_INIT(&hc->hc_args);
|
||||
TAILQ_INIT(&hc->hc_req_args);
|
||||
break;
|
||||
|
@ -865,14 +915,13 @@ typedef struct http_resource {
|
|||
} http_resource_t;
|
||||
|
||||
static int
|
||||
deliver_resource(http_connection_t *hc, const char *remain, void *opaque)
|
||||
deliver_resource(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque)
|
||||
{
|
||||
http_resource_t *hres = opaque;
|
||||
tcp_queue_t tq;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
tcp_qput(&tq, hres->data, hres->len);
|
||||
http_output_queue_encoding(hc, &tq, hres->content, 15, hres->encoding);
|
||||
tcp_qput(&hr->hr_tq, hres->data, hres->len);
|
||||
http_output(hc, hr, hres->content, hres->encoding, 15);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
41
http.h
41
http.h
|
@ -42,11 +42,37 @@ typedef struct http_arg {
|
|||
} http_arg_t;
|
||||
|
||||
|
||||
TAILQ_HEAD(http_reply_queue, http_reply);
|
||||
|
||||
typedef struct http_reply {
|
||||
TAILQ_ENTRY(http_reply) hr_link;
|
||||
|
||||
void *hr_opaque;
|
||||
|
||||
void (*hr_destroy)(struct http_reply *hr, void *opaque);
|
||||
|
||||
int hr_version; /* HTTP version */
|
||||
int hr_keep_alive;
|
||||
|
||||
char *hr_location;
|
||||
|
||||
int hr_rc; /* Return code */
|
||||
int hr_maxage;
|
||||
const char *hr_encoding;
|
||||
const char *hr_content;
|
||||
|
||||
tcp_queue_t hr_tq;
|
||||
|
||||
} http_reply_t;
|
||||
|
||||
|
||||
typedef struct http_connection {
|
||||
tcp_session_t hc_tcp_session; /* Must be first */
|
||||
char *hc_url;
|
||||
int hc_keep_alive;
|
||||
|
||||
struct http_reply_queue hc_replies;
|
||||
|
||||
struct http_arg_list hc_args;
|
||||
|
||||
struct http_arg_list hc_req_args; /* Argumets from GET or POST request */
|
||||
|
@ -103,15 +129,18 @@ void http_arg_set(struct http_arg_list *list, char *key, char *val);
|
|||
|
||||
int http_tokenize(char *buf, char **vec, int vecsize, int delimiter);
|
||||
|
||||
void http_error(http_connection_t *hc, int error);
|
||||
void http_error(http_connection_t *hc, http_reply_t *hr, int error);
|
||||
|
||||
void http_output_queue(http_connection_t *hc, tcp_queue_t *tq,
|
||||
const char *content, int maxage);
|
||||
void http_output(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *content, const char *encoding, int maxage);
|
||||
|
||||
int http_redirect(http_connection_t *hc, const char *location);
|
||||
void http_output_html(http_connection_t *hc, http_reply_t *hr);
|
||||
|
||||
typedef int (http_callback_t)(http_connection_t *hc, const char *remain,
|
||||
void *opaque);
|
||||
void http_redirect(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *location);
|
||||
|
||||
typedef int (http_callback_t)(http_connection_t *hc, http_reply_t *hr,
|
||||
const char *remain, void *opaque);
|
||||
|
||||
typedef struct http_path {
|
||||
LIST_ENTRY(http_path) hp_link;
|
||||
|
|
2
tcp.c
2
tcp.c
|
@ -351,7 +351,7 @@ tcp_output_queue(tcp_session_t *ses, tcp_queue_t *dst, tcp_queue_t *src)
|
|||
dst->tq_depth += s;
|
||||
}
|
||||
|
||||
if(!ses->tcp_blocked)
|
||||
if(ses != NULL && !ses->tcp_blocked)
|
||||
tcp_transmit(ses);
|
||||
|
||||
src->tq_depth = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue