]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Added support for byte ranges in the http server. This enables seeking when streaming...
authorsb1066 <sb1066@gmail.com>
Fri, 9 Jul 2010 20:09:52 +0000 (20:09 +0000)
committersb1066 <sb1066@gmail.com>
Fri, 9 Jul 2010 20:09:52 +0000 (20:09 +0000)
src/http.c
src/http.h
src/webui/webui.c

index e684b228958fca72c4f79fab451df63e5d75c549..cb813b9c2c5e68007c5f22a3354fea925cfa2dc7 100644 (file)
@@ -155,7 +155,7 @@ static const char *cachemonths[12] = {
 void
 http_send_header(http_connection_t *hc, int rc, const char *content, 
                 int contentlen, const char *encoding, const char *location, 
-                int maxage)
+                int maxage, const char *range)
 {
   struct tm tm0, *tm;
   htsbuf_queue_t hdrs;
@@ -211,6 +211,11 @@ http_send_header(http_connection_t *hc, int rc, const char *content,
   if(contentlen > 0)
     htsbuf_qprintf(&hdrs, "Content-Length: %d\r\n", contentlen);
 
+  if(range) {
+    htsbuf_qprintf(&hdrs, "Accept-Ranges: %s\r\n", "bytes");
+    htsbuf_qprintf(&hdrs, "Content-Range: %s\r\n", range);
+  }
+  
   htsbuf_qprintf(&hdrs, "\r\n");
 
   tcp_write_queue(hc->hc_fd, &hdrs);
@@ -226,7 +231,7 @@ http_send_reply(http_connection_t *hc, int rc, const char *content,
                const char *encoding, const char *location, int maxage)
 {
   http_send_header(hc, rc, content, hc->hc_reply.hq_size,
-                  encoding, location, maxage);
+                  encoding, location, maxage, 0);
   
   if(hc->hc_no_output)
     return;
@@ -841,7 +846,7 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq)
         int pcrpid = ss->ss_pcr_pid;
         int pmtpid = 0x0fff;
 
-        http_output_content(hc, "audio/mp2t");
+        http_output_content(hc, "video/mp2t");
         
         //Send PAT
         memset(pat_ts, 0xff, 188);
index 9bf8b0630e9838a5e71eb4fc6975af5032ed4853..8cc497c3ba4134a068d5faf308c9b4bbc9c03cc8 100644 (file)
@@ -117,7 +117,7 @@ void http_redirect(http_connection_t *hc, const char *location);
 
 void http_send_header(http_connection_t *hc, int rc, const char *content, 
                      int contentlen, const char *encoding,
-                     const char *location, int maxage);
+                     const char *location, int maxage, const char *range);
 
 typedef int (http_callback_t)(http_connection_t *hc, 
                              const char *remain, void *opaque);
index 4458a489af98645bee6c927db65d31b0ee63fb1e..6f90ac977d85cb51b2596a48ca366214b6ce43a4 100644 (file)
@@ -114,7 +114,7 @@ page_static_file(http_connection_t *hc, const char *remain, void *opaque)
     return 404;
   }
 
-  http_send_header(hc, 200, content, st.st_size, NULL, NULL, 10);
+  http_send_header(hc, 200, content, st.st_size, NULL, NULL, 10, 0);
   sendfile(hc->hc_fd, fd, NULL, st.st_size);
   close(fd);
   return 0;
@@ -174,7 +174,7 @@ page_static_bundle(http_connection_t *hc, const char *remain, void *opaque)
     if(!strcmp(fbe->filename, remain)) {
 
       http_send_header(hc, 200, content, fbe->size, 
-                      fbe->original_size == -1 ? NULL : "gzip", NULL, 10);
+                      fbe->original_size == -1 ? NULL : "gzip", NULL, 10, 0);
       /* ignore return value */
       n = write(hc->hc_fd, fbe->data, fbe->size);
       return 0;
@@ -195,7 +195,9 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
   const char *content = NULL, *postfix, *range;
   dvr_entry_t *de;
   char *fname;
-
+  char range_buf[255];
+  off_t content_len, file_start, file_end;
+  
   if(remain == NULL)
     return 404;
 
@@ -232,18 +234,28 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
     return 404;
   }
 
+  file_start = 0;
+  file_end = st.st_size-1;
   
   range = http_arg_get(&hc->hc_args, "Range");
-#if 0
-  if(range != NULL) {
-    printf("Range req: %s\n", range);
-  }
-#endif
+  if(range != NULL)
+    sscanf(range, "bytes=%"PRId64"-%"PRId64"", &file_start, &file_end);
 
-  http_send_header(hc, 200, content, st.st_size, NULL, NULL, 10);
-  sendfile(hc->hc_fd, fd, NULL, st.st_size);
+  content_len = file_end - file_start+1;
+  
+  sprintf(range_buf, "bytes %"PRId64"-%"PRId64"/%"PRId64"", file_start, file_end, st.st_size);
+
+  if(file_start > 0)
+    lseek(fd, file_start, SEEK_SET);
+
+  http_send_header(hc, 200, content, content_len, NULL, NULL, 10, range_buf);
+  sendfile(hc->hc_fd, fd, NULL, content_len);
   close(fd);
-  return 0;
+
+  if(range)
+    return 206;
+  else
+    return 0;
 }