From 7917d6b189239ecb7f99bd45fd20471918d1ffce Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Tue, 28 Nov 2017 11:13:27 +0100 Subject: [PATCH] afb-ws & websocket: Fix writing very long data MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This version loops to write very long data on websockets. Bug-AGL: SPEC-1091 Change-Id: I8f17e75e4ef483be29fa8cae2c0af159783ec2c6 Signed-off-by: José Bollo --- src/afb-apiset.c | 1 - src/afb-ws.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- src/websock.c | 10 ---------- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/afb-apiset.c b/src/afb-apiset.c index cad12e97..ae1d9460 100644 --- a/src/afb-apiset.c +++ b/src/afb-apiset.c @@ -29,7 +29,6 @@ #include "afb-apiset.h" #include "afb-context.h" #include "afb-xreq.h" -#include "jobs.h" #define INCR 8 /* CAUTION: must be a power of 2 */ diff --git a/src/afb-ws.c b/src/afb-ws.c index ff625fca..94fd30ea 100644 --- a/src/afb-ws.c +++ b/src/afb-ws.c @@ -347,21 +347,57 @@ int afb_ws_binary_v(struct afb_ws *ws, const struct iovec *iovec, int count) */ static ssize_t aws_writev(struct afb_ws *ws, const struct iovec *iov, int iovcnt) { - ssize_t rc; + int i; + ssize_t rc, sz, dsz; + struct iovec *iov2; + struct pollfd pfd; + + /* compute the size */ + dsz = 0; + i = 0; + while (i < iovcnt) { + dsz += iov[i++].iov_len; + if (dsz < 0) { + errno = EINVAL; + return -1; + } + } + if (dsz == 0) + return 0; + + /* write the data */ + iov2 = (struct iovec*)iov; + sz = dsz; for (;;) { - rc = writev(ws->fd, iov, iovcnt); - if (rc == -1) { + rc = writev(ws->fd, iov2, iovcnt); + if (rc < 0) { if (errno == EINTR) continue; - else if (errno == EAGAIN) { - struct pollfd pfd; - pfd.fd = ws->fd; - pfd.events = POLLOUT; - poll(&pfd, 1, 10); - continue; + if (errno != EAGAIN) + return -1; + } else { + dsz -= rc; + if (dsz == 0) + return sz; + + i = 0; + while (rc >= (ssize_t)iov2[i].iov_len) + rc -= (ssize_t)iov2[i++].iov_len; + + iovcnt -= i; + if (iov2 != iov) + iov2 += i; + else { + iov += i; + iov2 = alloca(iovcnt * sizeof *iov2); + for (i = 0 ; i < iovcnt ; i++) + iov2[i] = iov[i]; } + iov2->iov_base += rc; } - return rc; + pfd.fd = ws->fd; + pfd.events = POLLOUT; + poll(&pfd, 1, 10); } } diff --git a/src/websock.c b/src/websock.c index cc1e191e..84a11d78 100644 --- a/src/websock.c +++ b/src/websock.c @@ -84,16 +84,6 @@ static ssize_t ws_readv(struct websock *ws, const struct iovec *iov, int iovcnt) return ws->itf->readv(ws->closure, iov, iovcnt); } -#if 0 -static ssize_t ws_write(struct websock *ws, const void *buffer, size_t buffer_size) -{ - struct iovec iov; - iov.iov_base = (void *)buffer; /* const cast */ - iov.iov_len = buffer_size; - return ws_writev(ws, &iov, 1); -} -#endif - static ssize_t ws_read(struct websock *ws, void *buffer, size_t buffer_size) { struct iovec iov; -- 2.16.6