diff -r 14722c5f8856 -r 74babc0082b7 src/server/util/io.c --- a/src/server/util/io.c Wed May 22 15:05:06 2013 +0200 +++ b/src/server/util/io.c Sun May 26 12:12:07 2013 +0200 @@ -80,14 +80,14 @@ st->st = net_io_funcs; st->fd = fd; st->max_read = 0; - st->rd = 0; - st->chunkedenc = 0; + st->read = 0; + st->chunked_enc = 0; st->buffered = 0; return (IOStream*)st; } ssize_t net_stream_write(NetIOStream *st, void *buf, size_t nbytes) { - if(st->chunkedenc) { + if(st->chunked_enc) { // TODO: on some plattforms iov_len is smaller than size_t struct iovec io[2]; char chunk_len[16]; @@ -103,7 +103,7 @@ } ssize_t net_stream_writev(NetIOStream *st, struct iovec *iovec, int iovcnt) { - if(st->chunkedenc) { + if(st->chunked_enc) { struct iovec *io = calloc(iovcnt + 1, sizeof(struct iovec)); char chunk_len[16]; io[0].iov_base = chunk_len; @@ -121,11 +121,11 @@ } ssize_t net_stream_read(NetIOStream *st, void *buf, size_t nbytes) { - if(st->max_read != 0 && st->rd >= st->max_read) { + if(st->max_read != 0 && st->read >= st->max_read) { return 0; } ssize_t r = read(st->fd, buf, nbytes); - st->rd += r; + st->read += r; return r; } @@ -179,14 +179,75 @@ } ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { - IOStream *out = fd; - if(out->sendfile) { + NetIOStream *out = fd; + if(out->st.sendfile && sfd->fd && sfd->fd->fd != -1) { ssize_t r = ((IOStream*)fd)->sendfile(fd, sfd); if(r < 0) { return IO_ERROR; } } else { - fprintf(stderr, "stream does not support sendfile\n"); + // stream/file does not support sendfile + // do regular copy + char *buf = malloc(4096); + if(!buf) { + // TODO: out of memory error + return IO_ERROR; + } + char *header = (char*)sfd->header; + int hlen = sfd->hlen; + char *trailer = (char*)sfd->trailer; + int tlen = sfd->tlen; + if(header == NULL) { + hlen = 0; + } + if(trailer == NULL) { + tlen = 0; + } + + ssize_t r; + while(hlen > 0) { + r = out->st.write(fd, header, hlen); + header += r; + hlen -= r; + if(r <= 0) { + free(buf); + return IO_ERROR; + } + } + + if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) { + free(buf); + return IO_ERROR; + } + + size_t length = sfd->len; + while(length > 0) { + if((r = system_fread(sfd->fd, buf, 4096)) <= 0) { + break; + } + char *write_buf = buf; + while(r > 0) { + ssize_t w = out->st.write(fd, write_buf, r); + r -= w; + length -= w; + write_buf += w; + } + } + free(buf); + if(length > 0) { + return IO_ERROR; + } + + while(tlen > 0) { + r = out->st.write(fd, trailer, tlen); + trailer += r; + tlen -= r; + if(r <= 0) { + return IO_ERROR; + } + } + + return sfd->hlen + sfd->len + sfd->tlen; } return IO_ERROR; }