WEBUI: Add possibility to cancel HTTP and HTSP streaming connections
This commit is contained in:
parent
6f4661ddcf
commit
20f603e359
6 changed files with 96 additions and 14 deletions
|
@ -90,12 +90,43 @@ api_status_connections
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
api_connections_cancel
|
||||
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
|
||||
{
|
||||
htsmsg_field_t *f;
|
||||
htsmsg_t *ids;
|
||||
uint32_t id;
|
||||
|
||||
if (!(f = htsmsg_field_find(args, "id")))
|
||||
return EINVAL;
|
||||
if (!(ids = htsmsg_field_get_list(f)))
|
||||
if (htsmsg_field_get_u32(f, &id))
|
||||
return EINVAL;
|
||||
|
||||
if (ids) {
|
||||
HTSMSG_FOREACH(f, ids) {
|
||||
if (htsmsg_field_get_u32(f, &id)) continue;
|
||||
if (!id) continue;
|
||||
pthread_mutex_lock(&global_lock);
|
||||
tcp_connection_cancel(id);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
}
|
||||
} else {
|
||||
pthread_mutex_lock(&global_lock);
|
||||
tcp_connection_cancel(id);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void api_status_init ( void )
|
||||
{
|
||||
static api_hook_t ah[] = {
|
||||
{ "status/connections", ACCESS_ADMIN, api_status_connections, NULL },
|
||||
{ "status/subscriptions", ACCESS_ADMIN, api_status_subscriptions, NULL },
|
||||
{ "status/inputs", ACCESS_ADMIN, api_status_inputs, NULL },
|
||||
{ "connections/cancel", ACCESS_ADMIN, api_connections_cancel, NULL },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
|
|
@ -2567,6 +2567,10 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source,
|
|||
static void
|
||||
htsp_server_cancel ( void *opaque )
|
||||
{
|
||||
htsp_connection_t *htsp = opaque;
|
||||
|
||||
if (htsp)
|
||||
shutdown(htsp->htsp_fd, SHUT_RDWR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
14
src/http.c
14
src/http.c
|
@ -976,16 +976,14 @@ http_serve(int fd, void **opaque, struct sockaddr_storage *peer,
|
|||
*opaque = NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
http_server_status ( void *opaque, htsmsg_t *m )
|
||||
http_cancel( void *opaque )
|
||||
{
|
||||
// http_connection_t *hc = opaque;
|
||||
htsmsg_add_str(m, "type", "HTTP");
|
||||
if (hc->hc_username)
|
||||
htsmsg_add_str(m, "user", hc->hc_username);
|
||||
http_connection_t *hc = opaque;
|
||||
|
||||
if (hc)
|
||||
shutdown(hc->hc_fd, SHUT_RDWR);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Fire up HTTP server
|
||||
|
@ -996,7 +994,7 @@ http_server_init(const char *bindaddr)
|
|||
static tcp_server_ops_t ops = {
|
||||
.start = http_serve,
|
||||
.stop = NULL,
|
||||
.cancel = NULL
|
||||
.cancel = http_cancel
|
||||
};
|
||||
http_server = tcp_server_create(bindaddr, tvheadend_webui_port, &ops, NULL);
|
||||
}
|
||||
|
|
24
src/tcp.c
24
src/tcp.c
|
@ -459,13 +459,13 @@ try_again:
|
|||
*
|
||||
*/
|
||||
void
|
||||
tcp_connection_land(void *id)
|
||||
tcp_connection_land(void *tcp_id)
|
||||
{
|
||||
tcp_server_launch_t *tsl = id;
|
||||
tcp_server_launch_t *tsl = tcp_id;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
if (id == NULL)
|
||||
if (tsl == NULL)
|
||||
return;
|
||||
|
||||
LIST_REMOVE(tsl, link);
|
||||
|
@ -475,6 +475,24 @@ tcp_connection_land(void *id)
|
|||
tsl->representative = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
tcp_connection_cancel(uint32_t id)
|
||||
{
|
||||
tcp_server_launch_t *tsl;
|
||||
|
||||
lock_assert(&global_lock);
|
||||
|
||||
LIST_FOREACH(tsl, &tcp_server_active, alink)
|
||||
if (tsl->id == id) {
|
||||
if (tsl->ops.cancel)
|
||||
tsl->ops.cancel(tsl->opaque);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -83,7 +83,8 @@ struct access;
|
|||
|
||||
void *tcp_connection_launch(int fd, void (*status) (void *opaque, htsmsg_t *m),
|
||||
struct access *aa);
|
||||
void tcp_connection_land(void *id);
|
||||
void tcp_connection_land(void *tcp_id);
|
||||
void tcp_connection_cancel(uint32_t id);
|
||||
|
||||
htsmsg_t *tcp_server_connections ( void );
|
||||
|
||||
|
|
|
@ -449,6 +449,33 @@ tvheadend.status_conns = function(panel, index) {
|
|||
if (grid)
|
||||
return;
|
||||
|
||||
var actions = new Ext.ux.grid.RowActions({
|
||||
header: '',
|
||||
width: 10,
|
||||
actions: [
|
||||
{
|
||||
iconCls: 'cancel',
|
||||
qtip: 'Cancel this connection',
|
||||
cb: function(grid, rec, act, row) {
|
||||
var id = grid.getStore().getAt(row).data.id;
|
||||
Ext.MessageBox.confirm('Cancel Connection',
|
||||
'Cancel the selected connection?',
|
||||
function(button) {
|
||||
if (button === 'no')
|
||||
return;
|
||||
Ext.Ajax.request({
|
||||
url: 'api/connections/cancel',
|
||||
params: { id: id },
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
],
|
||||
destroy: function() {
|
||||
}
|
||||
});
|
||||
|
||||
store = new Ext.data.JsonStore({
|
||||
root: 'entries',
|
||||
totalProperty: 'totalCount',
|
||||
|
@ -475,7 +502,9 @@ tvheadend.status_conns = function(panel, index) {
|
|||
return dt.format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
var cm = new Ext.grid.ColumnModel([{
|
||||
var cm = new Ext.grid.ColumnModel([
|
||||
actions,
|
||||
{
|
||||
width: 50,
|
||||
id: 'type',
|
||||
header: "Type",
|
||||
|
@ -508,7 +537,8 @@ tvheadend.status_conns = function(panel, index) {
|
|||
flex: 1,
|
||||
viewConfig: {
|
||||
forceFit: true
|
||||
}
|
||||
},
|
||||
plugins: [actions],
|
||||
});
|
||||
|
||||
dpanel.add(grid);
|
||||
|
|
Loading…
Add table
Reference in a new issue