src/server/util/io.c

changeset 65
14722c5f8856
parent 64
c7f5b062e622
child 66
74babc0082b7
--- a/src/server/util/io.c	Wed May 22 13:27:31 2013 +0200
+++ b/src/server/util/io.c	Wed May 22 15:05:06 2013 +0200
@@ -48,10 +48,10 @@
 };
 
 IOStream net_io_funcs = {
-    net_stream_write,
-    net_stream_writev,
-    net_stream_read,
-    net_stream_sendfile
+    (io_write_f)net_stream_write,
+    (io_writev_f)net_stream_writev,
+    (io_read_f)net_stream_read,
+    (io_sendfile_f)net_stream_sendfile
 };
 
 
@@ -81,34 +81,60 @@
     st->fd = fd;
     st->max_read = 0;
     st->rd = 0;
+    st->chunkedenc = 0;
+    st->buffered = 0;
     return (IOStream*)st;
 }
 
-ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes) {
-    return write(((NetIOStream*)st)->fd, buf, nbytes);
-}
-
-ssize_t net_stream_writev(IOStream *st, struct iovec *iovec, int iovcnt) {
-    return writev(((NetIOStream*)st)->fd, iovec, iovcnt);
+ssize_t net_stream_write(NetIOStream *st, void *buf, size_t nbytes) {
+    if(st->chunkedenc) {
+        // TODO: on some plattforms iov_len is smaller than size_t
+        struct iovec io[2];
+        char chunk_len[16];
+        io[0].iov_base = chunk_len;
+        io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", nbytes);
+        io[1].iov_base = buf;
+        io[1].iov_len = nbytes;
+        ssize_t r = writev(st->fd, io, 2);
+        return r - io[0].iov_len;
+    } else {
+        return write(st->fd, buf, nbytes);
+    }
 }
 
-ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes) {
-    NetIOStream *n = (NetIOStream*)st;
-    if(n->max_read != 0 && n->rd >= n->max_read) {
+ssize_t net_stream_writev(NetIOStream *st, struct iovec *iovec, int iovcnt) {
+    if(st->chunkedenc) {
+        struct iovec *io = calloc(iovcnt + 1, sizeof(struct iovec));
+        char chunk_len[16];
+        io[0].iov_base = chunk_len;
+        size_t len = 0;
+        for(int i=0;i<iovcnt;i++) {
+            len += iovec[i].iov_len;
+        }
+        io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", len);
+        memcpy(io + 1, iovec, iovcnt * sizeof(struct iovec));
+        ssize_t r = writev(st->fd, io, iovcnt + 1);
+        return r - io[0].iov_len;
+    } else {
+        return writev(st->fd, iovec, iovcnt);
+    }
+}
+
+ssize_t net_stream_read(NetIOStream *st, void *buf, size_t nbytes) {
+    if(st->max_read != 0 && st->rd >= st->max_read) {
         return 0;
     }
-    ssize_t r = read(n->fd, buf, nbytes);
-    n->rd += r;
+    ssize_t r = read(st->fd, buf, nbytes);
+    st->rd += r;
     return r;
 }
 
-ssize_t net_stream_sendfile(IOStream *st, sendfiledata *sfd) {
-    NetIOStream *io = (NetIOStream*)st;
+ssize_t net_stream_sendfile(NetIOStream *st, sendfiledata *sfd) {
     // TODO: header and trailer
     ssize_t ret = 0;
     off_t fileoffset = sfd->offset;
     if(sfd->fd->fd != -1) {
-        ret = sendfile(io->fd, sfd->fd->fd, &fileoffset, sfd->len);
+        ret = sendfile(st->fd, sfd->fd->fd, &fileoffset, sfd->len);
     } else {
         // TODO: regular copy
         fprintf(stderr, "sendfile not implemented for SYS_FILE\n");

mercurial