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";
*/
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;
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");
} 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
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,
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;
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);
+ http_send_header(hc, range ? HTTP_STATUS_PARTIAL_CONTENT : HTTP_STATUS_OK,
+ content, content_len, NULL, NULL, 10,
+ range ? range_buf : NULL);
+
+ 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);
-
- if(range)
- return 206;
- else
- return 0;
+ return 0;
}