63 |
63 |
64 #include "../daemon/vfs.h" |
64 #include "../daemon/vfs.h" |
65 #include "io.h" |
65 #include "io.h" |
66 #include "pool.h" |
66 #include "pool.h" |
67 #include "../daemon/netsite.h" |
67 #include "../daemon/netsite.h" |
|
68 #include "../daemon/event.h" |
68 #include "ucx/utils.h" |
69 #include "ucx/utils.h" |
69 |
70 |
70 IOStream native_io_funcs = { |
71 IOStream native_io_funcs = { |
71 (io_write_f)net_sys_write, |
72 (io_write_f)net_sys_write, |
72 (io_writev_f)net_sys_writev, |
73 (io_writev_f)net_sys_writev, |
73 (io_read_f)net_sys_read, |
74 (io_read_f)net_sys_read, |
74 (io_sendfile_f)NET_SYS_SENDFILE, |
75 (io_sendfile_f)NET_SYS_SENDFILE, |
75 (io_close_f)net_sys_close, |
76 (io_close_f)net_sys_close, |
76 NULL |
77 NULL, |
|
78 (io_setmode_f)net_sys_setmode, |
|
79 (io_poll_f)net_sys_poll, |
|
80 0 |
77 }; |
81 }; |
78 |
82 |
79 IOStream http_io_funcs = { |
83 IOStream http_io_funcs = { |
80 (io_write_f)net_http_write, |
84 (io_write_f)net_http_write, |
81 (io_writev_f)net_http_writev, |
85 (io_writev_f)net_http_writev, |
82 (io_read_f)net_http_read, |
86 (io_read_f)net_http_read, |
83 (io_sendfile_f)net_http_sendfile, |
87 (io_sendfile_f)net_http_sendfile, |
84 (io_close_f)net_http_close, |
88 (io_close_f)net_http_close, |
85 (io_finish_f)net_http_finish |
89 (io_finish_f)net_http_finish, |
|
90 (io_setmode_f)net_http_setmode, |
|
91 (io_poll_f)net_http_poll, |
|
92 0 |
86 }; |
93 }; |
87 |
94 |
88 IOStream ssl_io_funcs = { |
95 IOStream ssl_io_funcs = { |
89 (io_write_f)net_ssl_write, |
96 (io_write_f)net_ssl_write, |
90 (io_writev_f)net_ssl_writev, |
97 (io_writev_f)net_ssl_writev, |
91 (io_read_f)net_ssl_read, |
98 (io_read_f)net_ssl_read, |
92 NULL, |
99 NULL, |
93 (io_close_f)net_ssl_close, |
100 (io_close_f)net_ssl_close, |
94 (io_finish_f)net_ssl_finish |
101 (io_finish_f)net_ssl_finish, |
|
102 (io_setmode_f)net_ssl_setmode, |
|
103 (io_poll_f)net_ssl_poll, |
|
104 0 |
95 }; |
105 }; |
96 |
106 |
97 |
107 |
98 /* |
108 /* |
99 * SysStream implementation |
109 * SysStream implementation |
169 |
179 |
170 void net_sys_close(SysStream *st) { |
180 void net_sys_close(SysStream *st) { |
171 system_close(st->fd); |
181 system_close(st->fd); |
172 } |
182 } |
173 |
183 |
|
184 void net_sys_setmode(SysStream *st, int mode) { |
|
185 int flags; |
|
186 if (-1 == (flags = fcntl(st->fd, F_GETFL, 0))) { |
|
187 flags = 0; |
|
188 } |
|
189 if(mode == IO_MODE_BLOCKING) { |
|
190 if (fcntl(st->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) { |
|
191 perror("fcntl"); |
|
192 // TODO: error |
|
193 } |
|
194 } else if(mode == IO_MODE_NONBLOCKING) { |
|
195 if (fcntl(st->fd, F_SETFL, flags | O_NONBLOCK) != 0) { |
|
196 perror("fcntl"); |
|
197 // TODO: error |
|
198 } |
|
199 } |
|
200 } |
|
201 |
|
202 int net_sys_poll(SysStream *st, EventHandler *ev, int events, Event *cb) { |
|
203 switch(events) { |
|
204 default: return -1; |
|
205 case IO_POLL_NONE: return ev_remove_poll(ev, st->fd); |
|
206 case IO_POLL_IN: return ev_pollin(ev, st->fd, cb); |
|
207 case IO_POLL_OUT: return ev_pollout(ev, st->fd, cb); |
|
208 case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement |
|
209 } |
|
210 } |
|
211 |
174 #elif defined(XP_WIN32) |
212 #elif defined(XP_WIN32) |
175 |
213 |
176 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) { |
214 ssize_t net_sys_write(SysStream *st, void *buf, size_t nbytes) { |
177 int ret = send(st->fd, buf, nbytes, 0); |
215 int ret = send(st->fd, buf, nbytes, 0); |
178 if(ret == SOCKET_ERROR) { |
216 if(ret == SOCKET_ERROR) { |
286 if(st->chunked_enc) { |
324 if(st->chunked_enc) { |
287 st->fd->write(st->fd, "0\r\n\r\n", 5); |
325 st->fd->write(st->fd, "0\r\n\r\n", 5); |
288 } |
326 } |
289 } |
327 } |
290 |
328 |
|
329 void net_http_setmode(HttpStream *st, int mode) { |
|
330 st->fd->setmode(st->fd, mode); |
|
331 } |
|
332 |
|
333 int net_http_poll(HttpStream *st, EventHandler *ev, int events, Event *cb) { |
|
334 return st->fd->poll(st->fd, ev, events, cb); |
|
335 } |
|
336 |
291 |
337 |
292 /* |
338 /* |
293 * SSLStream implementation |
339 * SSLStream implementation |
294 */ |
340 */ |
295 |
341 |
340 |
386 |
341 void net_ssl_finish(SSLStream *st) { |
387 void net_ssl_finish(SSLStream *st) { |
342 |
388 |
343 } |
389 } |
344 |
390 |
|
391 void net_ssl_setmode(SSLStream *st, int mode) { |
|
392 int flags; |
|
393 if (-1 == (flags = fcntl(SSL_get_fd(st->ssl), F_GETFL, 0))) { |
|
394 flags = 0; |
|
395 } |
|
396 if(mode == IO_MODE_BLOCKING) { |
|
397 if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags & ~O_NONBLOCK) != 0) { |
|
398 perror("fcntl"); |
|
399 // TODO: error |
|
400 } |
|
401 } else if(mode == IO_MODE_NONBLOCKING) { |
|
402 if (fcntl(SSL_get_fd(st->ssl), F_SETFL, flags | O_NONBLOCK) != 0) { |
|
403 perror("fcntl"); |
|
404 // TODO: error |
|
405 } |
|
406 } |
|
407 } |
|
408 |
|
409 int net_ssl_poll(SSLStream *st, EventHandler *ev, int events, Event *cb) { |
|
410 int fd = SSL_get_fd(st->ssl); |
|
411 switch(events) { |
|
412 default: return -1; |
|
413 case IO_POLL_NONE: return ev_remove_poll(ev, fd); |
|
414 case IO_POLL_IN: return ev_pollin(ev, fd, cb); |
|
415 case IO_POLL_OUT: return ev_pollout(ev, fd, cb); |
|
416 case IO_POLL_IN | IO_POLL_OUT: return -1; // TODO: implement |
|
417 } |
|
418 } |
345 |
419 |
346 /* -------------------- public nsapi network functions -------------------- */ |
420 /* -------------------- public nsapi network functions -------------------- */ |
347 |
421 |
348 ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) { |
422 ssize_t net_read(SYS_NETFD fd, void *buf, size_t nbytes) { |
349 ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes); |
423 ssize_t r = ((IOStream*)fd)->read(fd, buf, nbytes); |
350 if(r == 0) { |
424 if(r == 0) { |
351 return IO_EOF; |
425 return IO_EOF; |
|
426 } else if(r < 0) { |
|
427 ((IOStream*)fd)->io_errno = errno; |
|
428 return IO_ERROR; |
352 } |
429 } |
353 return r; |
430 return r; |
354 } |
431 } |
355 |
432 |
356 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) { |
433 ssize_t net_write(SYS_NETFD fd, void *buf, size_t nbytes) { |
357 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); |
434 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); |
358 if(r < 0) { |
435 if(r < 0) { |
|
436 ((IOStream*)fd)->io_errno = errno; |
359 return IO_ERROR; |
437 return IO_ERROR; |
360 } |
438 } |
361 return r; |
439 return r; |
362 } |
440 } |
363 |
441 |
364 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { |
442 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { |
365 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); |
443 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); |
366 if(r < 0) { |
444 if(r < 0) { |
|
445 ((IOStream*)fd)->io_errno = errno; |
367 return IO_ERROR; |
446 return IO_ERROR; |
368 } |
447 } |
369 return r; |
448 return r; |
370 } |
449 } |
371 |
450 |
374 va_start(arg, format); |
453 va_start(arg, format); |
375 sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg); |
454 sstr_t buf = ucx_vasprintf(ucx_default_allocator(), format, arg); |
376 ssize_t r = net_write(fd, buf.ptr, buf.length); |
455 ssize_t r = net_write(fd, buf.ptr, buf.length); |
377 free(buf.ptr); |
456 free(buf.ptr); |
378 va_end(arg); |
457 va_end(arg); |
|
458 if(r < 0) { |
|
459 ((IOStream*)fd)->io_errno = errno; |
|
460 } |
379 return r; |
461 return r; |
380 } |
462 } |
381 |
463 |
382 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { |
464 ssize_t net_sendfile(SYS_NETFD fd, sendfiledata *sfd) { |
383 IOStream *out = fd; |
465 IOStream *out = fd; |
384 if(out->sendfile && sfd->fd && sfd->fd->fd != -1) { |
466 if(out->sendfile && sfd->fd && sfd->fd->fd != -1) { |
385 ssize_t r = out->sendfile(fd, sfd); |
467 ssize_t r = out->sendfile(fd, sfd); |
386 if(r < 0) { |
468 if(r < 0) { |
|
469 out->io_errno = errno; |
387 return IO_ERROR; |
470 return IO_ERROR; |
388 } |
471 } |
|
472 return r; |
389 } else { |
473 } else { |
390 // stream/file does not support sendfile |
474 // stream/file does not support sendfile |
391 // do regular copy |
475 // do regular copy |
392 return net_fallback_sendfile(out, sfd); |
476 return net_fallback_sendfile(out, sfd); |
393 } |
477 } |
394 return IO_ERROR; |
|
395 } |
478 } |
396 |
479 |
397 // private |
480 // private |
398 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd) { |
481 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd) { |
399 char *buf = malloc(4096); |
482 char *buf = malloc(4096); |