79 NetIOStream *st = pool_malloc(pool, sizeof(NetIOStream)); |
79 NetIOStream *st = pool_malloc(pool, sizeof(NetIOStream)); |
80 st->st = net_io_funcs; |
80 st->st = net_io_funcs; |
81 st->fd = fd; |
81 st->fd = fd; |
82 st->max_read = 0; |
82 st->max_read = 0; |
83 st->rd = 0; |
83 st->rd = 0; |
|
84 st->chunkedenc = 0; |
|
85 st->buffered = 0; |
84 return (IOStream*)st; |
86 return (IOStream*)st; |
85 } |
87 } |
86 |
88 |
87 ssize_t net_stream_write(IOStream *st, void *buf, size_t nbytes) { |
89 ssize_t net_stream_write(NetIOStream *st, void *buf, size_t nbytes) { |
88 return write(((NetIOStream*)st)->fd, buf, nbytes); |
90 if(st->chunkedenc) { |
89 } |
91 // TODO: on some plattforms iov_len is smaller than size_t |
90 |
92 struct iovec io[2]; |
91 ssize_t net_stream_writev(IOStream *st, struct iovec *iovec, int iovcnt) { |
93 char chunk_len[16]; |
92 return writev(((NetIOStream*)st)->fd, iovec, iovcnt); |
94 io[0].iov_base = chunk_len; |
93 } |
95 io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", nbytes); |
94 |
96 io[1].iov_base = buf; |
95 ssize_t net_stream_read(IOStream *st, void *buf, size_t nbytes) { |
97 io[1].iov_len = nbytes; |
96 NetIOStream *n = (NetIOStream*)st; |
98 ssize_t r = writev(st->fd, io, 2); |
97 if(n->max_read != 0 && n->rd >= n->max_read) { |
99 return r - io[0].iov_len; |
|
100 } else { |
|
101 return write(st->fd, buf, nbytes); |
|
102 } |
|
103 } |
|
104 |
|
105 ssize_t net_stream_writev(NetIOStream *st, struct iovec *iovec, int iovcnt) { |
|
106 if(st->chunkedenc) { |
|
107 struct iovec *io = calloc(iovcnt + 1, sizeof(struct iovec)); |
|
108 char chunk_len[16]; |
|
109 io[0].iov_base = chunk_len; |
|
110 size_t len = 0; |
|
111 for(int i=0;i<iovcnt;i++) { |
|
112 len += iovec[i].iov_len; |
|
113 } |
|
114 io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", len); |
|
115 memcpy(io + 1, iovec, iovcnt * sizeof(struct iovec)); |
|
116 ssize_t r = writev(st->fd, io, iovcnt + 1); |
|
117 return r - io[0].iov_len; |
|
118 } else { |
|
119 return writev(st->fd, iovec, iovcnt); |
|
120 } |
|
121 } |
|
122 |
|
123 ssize_t net_stream_read(NetIOStream *st, void *buf, size_t nbytes) { |
|
124 if(st->max_read != 0 && st->rd >= st->max_read) { |
98 return 0; |
125 return 0; |
99 } |
126 } |
100 ssize_t r = read(n->fd, buf, nbytes); |
127 ssize_t r = read(st->fd, buf, nbytes); |
101 n->rd += r; |
128 st->rd += r; |
102 return r; |
129 return r; |
103 } |
130 } |
104 |
131 |
105 ssize_t net_stream_sendfile(IOStream *st, sendfiledata *sfd) { |
132 ssize_t net_stream_sendfile(NetIOStream *st, sendfiledata *sfd) { |
106 NetIOStream *io = (NetIOStream*)st; |
|
107 // TODO: header and trailer |
133 // TODO: header and trailer |
108 ssize_t ret = 0; |
134 ssize_t ret = 0; |
109 off_t fileoffset = sfd->offset; |
135 off_t fileoffset = sfd->offset; |
110 if(sfd->fd->fd != -1) { |
136 if(sfd->fd->fd != -1) { |
111 ret = sendfile(io->fd, sfd->fd->fd, &fileoffset, sfd->len); |
137 ret = sendfile(st->fd, sfd->fd->fd, &fileoffset, sfd->len); |
112 } else { |
138 } else { |
113 // TODO: regular copy |
139 // TODO: regular copy |
114 fprintf(stderr, "sendfile not implemented for SYS_FILE\n"); |
140 fprintf(stderr, "sendfile not implemented for SYS_FILE\n"); |
115 } |
141 } |
116 |
142 |