]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
HTTP dvrfile streaming: add subscription handling - fixes #2540
authorJaroslav Kysela <perex@perex.cz>
Fri, 12 Dec 2014 11:06:55 +0000 (12:06 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 12 Dec 2014 12:41:47 +0000 (13:41 +0100)
src/subscriptions.c
src/subscriptions.h
src/webui/webui.c

index 1c0a08b1312bee2d3624e60d93812404949949ba..298d7f39a3f8d0db6f1f6644e550cab873fd41ab 100644 (file)
@@ -561,6 +561,7 @@ subscription_unsubscribe(th_subscription_t *s)
   free(s->ths_hostname);
   free(s->ths_username);
   free(s->ths_client);
+  free(s->ths_dvrfile);
   free(s);
 
   gtimer_arm(&subscription_reschedule_timer, 
@@ -894,6 +895,9 @@ subscription_create_msg(th_subscription_t *s)
   if(s->ths_service != NULL)
     htsmsg_add_str(m, "service", s->ths_service->s_nicename ?: "");
 
+  else if(s->ths_dvrfile != NULL)
+    htsmsg_add_str(m, "service", s->ths_dvrfile ?: "");
+
   else if (s->ths_mmi != NULL && s->ths_mmi->mmi_mux != NULL) {
     char buf[512];
     mpegts_mux_t *mm = s->ths_mmi->mmi_mux;
index ca22d3c58fe948b09215c1424d205da89f34efc9..40c638def2bf5ee6a68733ca16e6c445908f0ee7 100644 (file)
@@ -95,6 +95,7 @@ typedef struct th_subscription {
   char *ths_hostname;
   char *ths_username;
   char *ths_client;
+  char *ths_dvrfile;
 
   /**
    * This is the list of service candidates we have
index 98e4f1c93aaf6d82ea2344cbd646e1db0c4a498d..4dff23e9db6885eb1514a6840ecda5873c1688aa 100644 (file)
@@ -1097,7 +1097,7 @@ page_play(http_connection_t *hc, const char *remain, void *opaque)
 static int
 page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
 {
-  int fd, i;
+  int fd, i, ret;
   struct stat st;
   const char *content = NULL, *range;
   dvr_entry_t *de;
@@ -1107,6 +1107,8 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
   char disposition[256];
   off_t content_len, chunk;
   intmax_t file_start, file_end;
+  void *tcp_id;
+  th_subscription_t *sub;
 #if defined(PLATFORM_LINUX)
   ssize_t r;
 #elif defined(PLATFORM_FREEBSD) || defined(PLATFORM_DARWIN)
@@ -1133,7 +1135,7 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
     return HTTP_STATUS_NOT_FOUND;
   }
 
-  fname = strdup(de->de_filename);
+  fname = tvh_strdupa(de->de_filename);
   content = muxer_container_type2mime(de->de_mc, 1);
 
   pthread_mutex_unlock(&global_lock);
@@ -1153,7 +1155,6 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
   }
 
   fd = tvh_open(fname, O_RDONLY, 0);
-  free(fname);
   if(fd < 0)
     return HTTP_STATUS_NOT_FOUND;
 
@@ -1195,14 +1196,40 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
       return HTTP_STATUS_INTERNAL;
     }
 
+  pthread_mutex_lock(&global_lock);
+  tcp_id = http_stream_preop(hc);
+  tcp_get_ip_str((struct sockaddr*)hc->hc_peer, range_buf, 50);
+  sub = NULL;
+  if (tcp_id && !hc->hc_no_output && content_len > 64*1024) {
+    sub = subscription_create(NULL, 1, "HTTP",
+                              SUBSCRIPTION_NONE, NULL,
+                              range_buf, hc->hc_username,
+                              http_arg_get(&hc->hc_args, "User-Agent"));
+    if (sub == NULL) {
+      http_stream_postop(tcp_id);
+      tcp_id = NULL;
+    } else {
+      basename = malloc(strlen(fname) + 7 + 1);
+      strcpy(basename, "file://");
+      strcat(basename, fname);
+      sub->ths_dvrfile = basename;
+    }
+  }
+  pthread_mutex_unlock(&global_lock);
+  if (tcp_id == NULL) {
+    close(fd);
+    return HTTP_STATUS_NOT_ALLOWED;
+  }
+
   http_send_header(hc, range ? HTTP_STATUS_PARTIAL_CONTENT : HTTP_STATUS_OK,
        content, content_len, NULL, NULL, 10, 
        range ? range_buf : NULL,
        disposition[0] ? disposition : NULL);
 
+  ret = 0;
   if(!hc->hc_no_output) {
     while(content_len > 0) {
-      chunk = MIN(1024 * 1024 * 1024, content_len);
+      chunk = MIN(1024 * (sub ? 128 : 1024 * 1024), content_len);
 #if defined(PLATFORM_LINUX)
       r = sendfile(hc->hc_fd, fd, NULL, chunk);
 #elif defined(PLATFORM_FREEBSD)
@@ -1212,14 +1239,24 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
       sendfile(fd, hc->hc_fd, 0, NULL, &r, 0);
 #endif
       if(r < 0) {
-        close(fd);
-        return -1;
+        ret = -1;
+        break;
       }
       content_len -= r;
+      if (sub) {
+        sub->ths_bytes_in += r;
+        sub->ths_bytes_out += r;
+      }
     }
   }
   close(fd);
-  return 0;
+
+  pthread_mutex_lock(&global_lock);
+  if (sub)
+    subscription_unsubscribe(sub);
+  http_stream_postop(tcp_id);
+  pthread_mutex_unlock(&global_lock);
+  return ret;
 }
 
 /**