]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
WEBUI: Add possibility to cancel HTTP and HTSP streaming connections
authorJaroslav Kysela <perex@perex.cz>
Mon, 6 Oct 2014 15:35:24 +0000 (17:35 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 6 Oct 2014 15:35:24 +0000 (17:35 +0200)
src/api/api_status.c
src/htsp_server.c
src/http.c
src/tcp.c
src/tcp.h
src/webui/static/app/status.js

index 6d19e8434afed305df5c89db08458434f5b78e39..0057109fa07bcc0a3ca68882a43d8ecac20269ce 100644 (file)
@@ -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 },
   };
 
index a7ab5dbe087c0773368713a07c88a1ae9ace150f..df92935511924a4a8e85333ecf44941440fd71c7 100644 (file)
@@ -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);
 }
 
 /**
index 692de1ec9d0cc6c282c6b5613236cbb02e6c36ff..19ecc4cf61c5aa7ee2ad229aae9516779fb0bc5a 100644 (file)
@@ -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);
 }
index 47c0d16d55f17e6189bb8b8ee2f2ae853debb07c..8c0576b4af9bbca821b073e584eff587d46e5f14 100644 (file)
--- a/src/tcp.c
+++ b/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;
+    }
+}
+
 /*
  *
  */
index d08adc356f017e1c5f63e1038e6758eda456c77d..43dd7d44d684e2ce3fa8e043a32a68f0b958e991 100644 (file)
--- a/src/tcp.h
+++ b/src/tcp.h
@@ -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 );
 
index 2d39e151cd118744aa71ea2510da3098d8e59f2e..868f4f8f4767804949de957a8cc458dca91858b8 100644 (file)
@@ -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);