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;
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)
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);
}
fd = tvh_open(fname, O_RDONLY, 0);
- free(fname);
if(fd < 0)
return HTTP_STATUS_NOT_FOUND;
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)
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;
}
/**