src/server/util/io.c

changeset 66
74babc0082b7
parent 65
14722c5f8856
child 69
4a10bc0ee80d
equal deleted inserted replaced
65:14722c5f8856 66:74babc0082b7
78 IOStream* net_stream_from_fd(pool_handle_t *pool, int fd) { 78 IOStream* net_stream_from_fd(pool_handle_t *pool, int fd) {
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->read = 0;
84 st->chunkedenc = 0; 84 st->chunked_enc = 0;
85 st->buffered = 0; 85 st->buffered = 0;
86 return (IOStream*)st; 86 return (IOStream*)st;
87 } 87 }
88 88
89 ssize_t net_stream_write(NetIOStream *st, void *buf, size_t nbytes) { 89 ssize_t net_stream_write(NetIOStream *st, void *buf, size_t nbytes) {
90 if(st->chunkedenc) { 90 if(st->chunked_enc) {
91 // TODO: on some plattforms iov_len is smaller than size_t 91 // TODO: on some plattforms iov_len is smaller than size_t
92 struct iovec io[2]; 92 struct iovec io[2];
93 char chunk_len[16]; 93 char chunk_len[16];
94 io[0].iov_base = chunk_len; 94 io[0].iov_base = chunk_len;
95 io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", nbytes); 95 io[0].iov_len = snprintf(chunk_len, 16, "\n%x\r\n", nbytes);
101 return write(st->fd, buf, nbytes); 101 return write(st->fd, buf, nbytes);
102 } 102 }
103 } 103 }
104 104
105 ssize_t net_stream_writev(NetIOStream *st, struct iovec *iovec, int iovcnt) { 105 ssize_t net_stream_writev(NetIOStream *st, struct iovec *iovec, int iovcnt) {
106 if(st->chunkedenc) { 106 if(st->chunked_enc) {
107 struct iovec *io = calloc(iovcnt + 1, sizeof(struct iovec)); 107 struct iovec *io = calloc(iovcnt + 1, sizeof(struct iovec));
108 char chunk_len[16]; 108 char chunk_len[16];
109 io[0].iov_base = chunk_len; 109 io[0].iov_base = chunk_len;
110 size_t len = 0; 110 size_t len = 0;
111 for(int i=0;i<iovcnt;i++) { 111 for(int i=0;i<iovcnt;i++) {
119 return writev(st->fd, iovec, iovcnt); 119 return writev(st->fd, iovec, iovcnt);
120 } 120 }
121 } 121 }
122 122
123 ssize_t net_stream_read(NetIOStream *st, void *buf, size_t nbytes) { 123 ssize_t net_stream_read(NetIOStream *st, void *buf, size_t nbytes) {
124 if(st->max_read != 0 && st->rd >= st->max_read) { 124 if(st->max_read != 0 && st->read >= st->max_read) {
125 return 0; 125 return 0;
126 } 126 }
127 ssize_t r = read(st->fd, buf, nbytes); 127 ssize_t r = read(st->fd, buf, nbytes);
128 st->rd += r; 128 st->read += r;
129 return r; 129 return r;
130 } 130 }
131 131
132 ssize_t net_stream_sendfile(NetIOStream *st, sendfiledata *sfd) { 132 ssize_t net_stream_sendfile(NetIOStream *st, sendfiledata *sfd) {
133 // TODO: header and trailer 133 // TODO: header and trailer
177 free(buf); 177 free(buf);
178 return r; 178 return r;
179 } 179 }
180 180
181 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { 181 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) {
182 IOStream *out = fd; 182 NetIOStream *out = fd;
183 if(out->sendfile) { 183 if(out->st.sendfile && sfd->fd && sfd->fd->fd != -1) {
184 ssize_t r = ((IOStream*)fd)->sendfile(fd, sfd); 184 ssize_t r = ((IOStream*)fd)->sendfile(fd, sfd);
185 if(r < 0) { 185 if(r < 0) {
186 return IO_ERROR; 186 return IO_ERROR;
187 } 187 }
188 } else { 188 } else {
189 fprintf(stderr, "stream does not support sendfile\n"); 189 // stream/file does not support sendfile
190 // do regular copy
191 char *buf = malloc(4096);
192 if(!buf) {
193 // TODO: out of memory error
194 return IO_ERROR;
195 }
196 char *header = (char*)sfd->header;
197 int hlen = sfd->hlen;
198 char *trailer = (char*)sfd->trailer;
199 int tlen = sfd->tlen;
200 if(header == NULL) {
201 hlen = 0;
202 }
203 if(trailer == NULL) {
204 tlen = 0;
205 }
206
207 ssize_t r;
208 while(hlen > 0) {
209 r = out->st.write(fd, header, hlen);
210 header += r;
211 hlen -= r;
212 if(r <= 0) {
213 free(buf);
214 return IO_ERROR;
215 }
216 }
217
218 if(system_lseek(sfd->fd, sfd->offset, SEEK_SET) == -1) {
219 free(buf);
220 return IO_ERROR;
221 }
222
223 size_t length = sfd->len;
224 while(length > 0) {
225 if((r = system_fread(sfd->fd, buf, 4096)) <= 0) {
226 break;
227 }
228 char *write_buf = buf;
229 while(r > 0) {
230 ssize_t w = out->st.write(fd, write_buf, r);
231 r -= w;
232 length -= w;
233 write_buf += w;
234 }
235 }
236 free(buf);
237 if(length > 0) {
238 return IO_ERROR;
239 }
240
241 while(tlen > 0) {
242 r = out->st.write(fd, trailer, tlen);
243 trailer += r;
244 tlen -= r;
245 if(r <= 0) {
246 return IO_ERROR;
247 }
248 }
249
250 return sfd->hlen + sfd->len + sfd->tlen;
190 } 251 }
191 return IO_ERROR; 252 return IO_ERROR;
192 } 253 }
193 254
194 255

mercurial