Fix a couple of bugs related to sending files > 2GB

Ticket #391
This commit is contained in:
Andreas Öman 2011-03-02 23:32:45 +01:00
parent 98975cf4b3
commit 2ea7764431
3 changed files with 25 additions and 13 deletions

View file

@ -123,7 +123,8 @@ static const char *
http_rc2str(int code)
{
switch(code) {
case HTTP_STATUS_OK: return "Ok";
case HTTP_STATUS_OK: return "OK";
case HTTP_STATUS_PARTIAL_CONTENT: return "Partial Content";
case HTTP_STATUS_NOT_FOUND: return "Not found";
case HTTP_STATUS_UNAUTHORIZED: return "Unauthorized";
case HTTP_STATUS_BAD_REQUEST: return "Bad request";
@ -149,7 +150,8 @@ 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,
int64_t contentlen,
const char *encoding, const char *location,
int maxage, const char *range)
{
struct tm tm0, *tm;
@ -204,7 +206,7 @@ http_send_header(http_connection_t *hc, int rc, const char *content,
htsbuf_qprintf(&hdrs, "Content-Type: %s\r\n", content);
if(contentlen > 0)
htsbuf_qprintf(&hdrs, "Content-Length: %d\r\n", contentlen);
htsbuf_qprintf(&hdrs, "Content-Length: %"PRId64"\r\n", contentlen);
if(range) {
htsbuf_qprintf(&hdrs, "Accept-Ranges: %s\r\n", "bytes");

View file

@ -30,6 +30,7 @@ typedef struct http_arg {
} http_arg_t;
#define HTTP_STATUS_OK 200
#define HTTP_STATUS_PARTIAL_CONTENT 206
#define HTTP_STATUS_FOUND 302
#define HTTP_STATUS_BAD_REQUEST 400
#define HTTP_STATUS_UNAUTHORIZED 401
@ -111,7 +112,7 @@ void http_output_content(http_connection_t *hc, const char *content);
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,
int64_t contentlen, const char *encoding,
const char *location, int maxage, const char *range);
typedef int (http_callback_t)(http_connection_t *hc,

View file

@ -525,7 +525,8 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
dvr_entry_t *de;
char *fname;
char range_buf[255];
off_t content_len, file_start, file_end;
off_t content_len, file_start, file_end, chunk;
ssize_t r;
if(remain == NULL)
return 404;
@ -577,19 +578,27 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
content_len = file_end - file_start+1;
sprintf(range_buf, "bytes %"PRId64"-%"PRId64"/%"PRId64"", file_start, file_end, st.st_size);
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);
http_send_header(hc, range ? HTTP_STATUS_PARTIAL_CONTENT : HTTP_STATUS_OK,
content, content_len, NULL, NULL, 10,
range ? range_buf : NULL);
if(range)
return 206;
else
return 0;
if(!hc->hc_no_output) {
while(content_len > 0) {
chunk = MIN(1024 * 1024 * 1024, content_len);
r = sendfile(hc->hc_fd, fd, NULL, chunk);
if(r == -1)
return -1;
content_len -= r;
}
}
close(fd);
return 0;
}