Replace evbuffer_read(); should not be applied to files

evbuffer_read() is really meant to read from sockets and not regular
files. It also looks like evbuffer_read() was causing issues with large
files, locking up a little below 2 GB for an unknown reason (couldn't
reproduce).
This commit is contained in:
Julien BLACHE 2010-02-02 21:03:29 +01:00
parent 3fc40bc29e
commit f0239951e1
1 changed files with 35 additions and 5 deletions

View File

@ -79,6 +79,7 @@ struct content_type_map {
struct stream_ctx { struct stream_ctx {
struct evhttp_request *req; struct evhttp_request *req;
uint8_t *buf;
struct evbuffer *evbuf; struct evbuffer *evbuf;
struct event ev; struct event ev;
int id; int id;
@ -129,7 +130,10 @@ stream_end(struct stream_ctx *st, int failed)
if (st->xcode) if (st->xcode)
transcode_cleanup(st->xcode); transcode_cleanup(st->xcode);
else else
close(st->fd); {
free(st->buf);
close(st->fd);
}
free(st); free(st);
} }
@ -249,7 +253,7 @@ stream_chunk_raw_cb(int fd, short event, void *arg)
else else
chunk_size = STREAM_CHUNK_SIZE; chunk_size = STREAM_CHUNK_SIZE;
ret = evbuffer_read(st->evbuf, st->fd, chunk_size); ret = read(st->fd, st->buf, chunk_size);
if (ret <= 0) if (ret <= 0)
{ {
if (ret == 0) if (ret == 0)
@ -263,6 +267,8 @@ stream_chunk_raw_cb(int fd, short event, void *arg)
DPRINTF(E_DBG, L_HTTPD, "Read %d bytes; streaming file id %d\n", ret, st->id); DPRINTF(E_DBG, L_HTTPD, "Read %d bytes; streaming file id %d\n", ret, st->id);
evbuffer_add(st->evbuf, st->buf, ret);
evhttp_send_reply_chunk_with_cb(st->req, st->evbuf, stream_chunk_resched_cb, st); evhttp_send_reply_chunk_with_cb(st->req, st->evbuf, stream_chunk_resched_cb, st);
st->offset += ret; st->offset += ret;
@ -403,6 +409,18 @@ httpd_stream_file(struct evhttp_request *req, int id)
/* Stream the raw file */ /* Stream the raw file */
DPRINTF(E_INFO, L_HTTPD, "Preparing to stream %s\n", mfi->path); DPRINTF(E_INFO, L_HTTPD, "Preparing to stream %s\n", mfi->path);
st->buf = (uint8_t *)malloc(STREAM_CHUNK_SIZE);
if (!st->buf)
{
DPRINTF(E_LOG, L_HTTPD, "Out of memory for raw streaming buffer\n");
evhttp_send_error(req, HTTP_SERVUNAVAIL, "Internal Server Error");
free(st);
free_mfi(mfi, 0);
return;
}
stream_cb = stream_chunk_raw_cb; stream_cb = stream_chunk_raw_cb;
st->fd = open(mfi->path, O_RDONLY); st->fd = open(mfi->path, O_RDONLY);
@ -412,6 +430,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
free(st->buf);
free(st); free(st);
free_mfi(mfi, 0); free_mfi(mfi, 0);
return; return;
@ -425,6 +444,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
evhttp_send_error(req, HTTP_NOTFOUND, "Not Found"); evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
close(st->fd); close(st->fd);
free(st->buf);
free(st); free(st);
free_mfi(mfi, 0); free_mfi(mfi, 0);
return; return;
@ -439,6 +459,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request"); evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
close(st->fd); close(st->fd);
free(st->buf);
free(st); free(st);
free_mfi(mfi, 0); free_mfi(mfi, 0);
return; return;
@ -487,7 +508,10 @@ httpd_stream_file(struct evhttp_request *req, int id)
if (transcode) if (transcode)
transcode_cleanup(st->xcode); transcode_cleanup(st->xcode);
else else
close(st->fd); {
free(st->buf);
close(st->fd);
}
free(st); free(st);
free_mfi(mfi, 0); free_mfi(mfi, 0);
return; return;
@ -504,7 +528,10 @@ httpd_stream_file(struct evhttp_request *req, int id)
if (transcode) if (transcode)
transcode_cleanup(st->xcode); transcode_cleanup(st->xcode);
else else
close(st->fd); {
free(st->buf);
close(st->fd);
}
evbuffer_free(st->evbuf); evbuffer_free(st->evbuf);
free(st); free(st);
free_mfi(mfi, 0); free_mfi(mfi, 0);
@ -525,7 +552,10 @@ httpd_stream_file(struct evhttp_request *req, int id)
if (transcode) if (transcode)
transcode_cleanup(st->xcode); transcode_cleanup(st->xcode);
else else
close(st->fd); {
free(st->buf);
close(st->fd);
}
evbuffer_free(st->evbuf); evbuffer_free(st->evbuf);
free(st); free(st);
free_mfi(mfi, 0); free_mfi(mfi, 0);