[spice-server,05/23] websocket: Move RedsWebSocket to header

Submitted by Frediano Ziglio on June 25, 2019, 4:11 p.m.

Details

Message ID 20190625161147.25211-6-fziglio@redhat.com
State Accepted
Commit 98c183a6f6907e679749acb899454779e6f7b8a7
Headers show
Series "WebSocket support" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Frediano Ziglio June 25, 2019, 4:11 p.m.
Intention is to make private in websockets.c and reduce
changes in red-stream.c

Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
 server/red-stream.c | 40 ++++------------------------------------
 server/websocket.c  | 39 +++++++++++++++++++++++++++++++--------
 server/websocket.h  | 24 +++++++++++++++++-------
 3 files changed, 52 insertions(+), 51 deletions(-)

Patch hide | download patch | download mbox

diff --git a/server/red-stream.c b/server/red-stream.c
index 4b8992411..d6a00dd9f 100644
--- a/server/red-stream.c
+++ b/server/red-stream.c
@@ -78,17 +78,6 @@  typedef struct RedSASL {
 } RedSASL;
 #endif
 
-typedef struct {
-    int closed;
-
-    websocket_frame_t read_frame;
-    uint64_t write_remainder;
-
-    ssize_t (*raw_read)(RedStream *s, void *buf, size_t nbyte);
-    ssize_t (*raw_write)(RedStream *s, const void *buf, size_t nbyte);
-    ssize_t (*raw_writev)(RedStream *s, const struct iovec *iov, int iovcnt);
-} RedsWebSocket;
-
 struct RedStreamPrivate {
     SSL *ssl;
 
@@ -1174,39 +1163,17 @@  error:
 
 static ssize_t stream_websocket_read(RedStream *s, void *buf, size_t size)
 {
-    int rc;
-
-    if (s->priv->ws->closed)
-        return 0;
-
-    rc = websocket_read((void *)s, buf, size, &s->priv->ws->read_frame,
-        (websocket_read_cb_t) s->priv->ws->raw_read,
-        (websocket_write_cb_t) s->priv->ws->raw_write);
-
-    if (rc == 0)
-        s->priv->ws->closed = 1;
-
-    return rc;
+    return websocket_read(s->priv->ws, buf, size);
 }
 
 static ssize_t stream_websocket_write(RedStream *s, const void *buf, size_t size)
 {
-    if (s->priv->ws->closed) {
-        errno = EPIPE;
-        return -1;
-    }
-    return websocket_write((void *)s, buf, size, &s->priv->ws->write_remainder,
-        (websocket_write_cb_t) s->priv->ws->raw_write);
+    return websocket_write(s->priv->ws, buf, size);
 }
 
 static ssize_t stream_websocket_writev(RedStream *s, const struct iovec *iov, int iovcnt)
 {
-    if (s->priv->ws->closed) {
-        errno = EPIPE;
-        return -1;
-    }
-    return websocket_writev((void *)s, (struct iovec *) iov, iovcnt, &s->priv->ws->write_remainder,
-        (websocket_writev_cb_t) s->priv->ws->raw_writev);
+    return websocket_writev(s->priv->ws, (struct iovec *) iov, iovcnt);
 }
 
 /*
@@ -1256,6 +1223,7 @@  bool red_stream_is_websocket(RedStream *stream, const void *buf, size_t len)
         if (rc == strlen(outbuf)) {
             stream->priv->ws = g_malloc0(sizeof(*stream->priv->ws));
 
+            stream->priv->ws->raw_stream = stream;
             stream->priv->ws->raw_read = stream->priv->read;
             stream->priv->ws->raw_write = stream->priv->write;
 
diff --git a/server/websocket.c b/server/websocket.c
index fc1d82c28..145d829f4 100644
--- a/server/websocket.c
+++ b/server/websocket.c
@@ -226,17 +226,23 @@  static int relay_data(uint8_t* buf, size_t size, websocket_frame_t *frame)
     return n;
 }
 
-int websocket_read(void *opaque, uint8_t *buf, int size, websocket_frame_t *frame,
-                    websocket_read_cb_t read_cb,
-                    websocket_write_cb_t write_cb)
+int websocket_read(RedsWebSocket *ws, uint8_t *buf, int size)
 {
     int n = 0;
     int rc;
+    websocket_frame_t *frame = &ws->read_frame;
+    void *opaque = ws->raw_stream;
+    websocket_read_cb_t read_cb = (websocket_read_cb_t) ws->raw_read;
+    websocket_write_cb_t write_cb = (websocket_write_cb_t) ws->raw_write;
+
+    if (ws->closed) {
+        return 0;
+    }
 
     while (size > 0) {
         // make sure we have a proper frame ready
         if (!frame->frame_ready) {
-            rc = read_cb(opaque, frame->header + frame->header_pos, frame_bytes_needed(frame));
+            rc = read_cb(ws->raw_stream, frame->header + frame->header_pos, frame_bytes_needed(frame));
             if (rc <= 0) {
                 goto read_error;
             }
@@ -246,6 +252,7 @@  int websocket_read(void *opaque, uint8_t *buf, int size, websocket_frame_t *fram
         } else if (frame->type == CLOSE_FRAME) {
             websocket_ack_close(opaque, write_cb);
             websocket_clear_frame(frame);
+            ws->closed = true;
             return 0;
         } else if (frame->type == BINARY_FRAME) {
             rc = read_cb(opaque, buf, MIN(size, frame->expected_len - frame->relayed));
@@ -274,6 +281,9 @@  read_error:
     if (n > 0 && rc == -1 && (errno == EINTR || errno == EAGAIN)) {
         return n;
     }
+    if (rc == 0) {
+        ws->closed = true;
+    }
     return rc;
 }
 
@@ -332,8 +342,7 @@  static void constrain_iov(struct iovec *iov, int iovcnt,
 
 
 /* Write a WebSocket frame with the enclosed data out. */
-int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, uint64_t *remainder,
-         websocket_writev_cb_t writev_cb)
+int websocket_writev(RedsWebSocket *ws, struct iovec *iov, int iovcnt)
 {
     uint8_t header[WEBSOCKET_MAX_HEADER_SIZE];
     uint64_t len;
@@ -342,7 +351,14 @@  int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, uint64_t *rema
     int iov_out_cnt;
     int i;
     int header_len;
+    void *opaque = ws->raw_stream;
+    websocket_writev_cb_t writev_cb = (websocket_writev_cb_t) ws->raw_writev;
+    uint64_t *remainder = &ws->write_remainder;
 
+    if (ws->closed) {
+        errno = EPIPE;
+        return -1;
+    }
     if (*remainder > 0) {
         constrain_iov(iov, iovcnt, &iov_out, &iov_out_cnt, *remainder);
         rc = writev_cb(opaque, iov_out, iov_out_cnt);
@@ -385,12 +401,19 @@  int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, uint64_t *rema
     return rc;
 }
 
-int websocket_write(void *opaque, const uint8_t *buf, int len, uint64_t *remainder,
-         websocket_write_cb_t write_cb)
+int websocket_write(RedsWebSocket *ws, const uint8_t *buf, int len)
 {
     uint8_t header[WEBSOCKET_MAX_HEADER_SIZE];
     int rc;
     int header_len;
+    void *opaque = ws->raw_stream;
+    websocket_write_cb_t write_cb = (websocket_write_cb_t) ws->raw_write;
+    uint64_t *remainder = &ws->write_remainder;
+
+    if (ws->closed) {
+        errno = EPIPE;
+        return -1;
+    }
 
     if (*remainder == 0) {
         header_len = fill_header(header, len);
diff --git a/server/websocket.h b/server/websocket.h
index 63d7b10c2..f65b4e3d0 100644
--- a/server/websocket.h
+++ b/server/websocket.h
@@ -17,6 +17,8 @@ 
 
 #define WEBSOCKET_MAX_HEADER_SIZE (1 + 9 + 4)
 
+struct RedStream;
+
 typedef struct {
     int type;
     int masked;
@@ -32,13 +34,21 @@  typedef ssize_t (*websocket_read_cb_t)(void *opaque, void *buf, size_t nbyte);
 typedef ssize_t (*websocket_write_cb_t)(void *opaque, const void *buf, size_t nbyte);
 typedef ssize_t (*websocket_writev_cb_t)(void *opaque, struct iovec *iov, int iovcnt);
 
+typedef struct {
+    int closed;
+
+    websocket_frame_t read_frame;
+    uint64_t write_remainder;
+
+    struct RedStream *raw_stream;
+    ssize_t (*raw_read)(struct RedStream *s, void *buf, size_t nbyte);
+    ssize_t (*raw_write)(struct RedStream *s, const void *buf, size_t nbyte);
+    ssize_t (*raw_writev)(struct RedStream *s, const struct iovec *iov, int iovcnt);
+} RedsWebSocket;
+
 bool websocket_is_start(char *buf);
 void websocket_create_reply(char *buf, char *outbuf);
-int websocket_read(void *opaque, uint8_t *buf, int len, websocket_frame_t *frame,
-         websocket_read_cb_t read_cb,
-         websocket_write_cb_t write_cb);
-int websocket_write(void *opaque, const uint8_t *buf, int len, uint64_t *remainder,
-         websocket_write_cb_t write_cb);
-int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, uint64_t *remainder,
-         websocket_writev_cb_t writev_cb);
+int websocket_read(RedsWebSocket *ws, uint8_t *buf, int len);
+int websocket_write(RedsWebSocket *ws, const uint8_t *buf, int len);
+int websocket_writev(RedsWebSocket *ws, struct iovec *iov, int iovcnt);
 void websocket_ack_close(void *opaque, websocket_write_cb_t write_cb);