[Spice-devel] [PATCH spice-server 10/30] Move RedsWebSocket to header
Frediano Ziglio
fziglio at redhat.com
Mon Nov 21 12:51:57 UTC 2016
Intention is to make private in websockets.c and reduce
changes in reds-stream.c
---
server/reds-stream.c | 40 ++++------------------------------------
server/websocket.c | 42 ++++++++++++++++++++++++++++++++++--------
server/websocket.h | 24 +++++++++++++++++-------
3 files changed, 55 insertions(+), 51 deletions(-)
diff --git a/server/reds-stream.c b/server/reds-stream.c
index b59586b..bf0cbbe 100644
--- a/server/reds-stream.c
+++ b/server/reds-stream.c
@@ -78,17 +78,6 @@ typedef struct RedsSASL {
} RedsSASL;
#endif
-typedef struct {
- int closed;
-
- websocket_frame_t read_frame;
- guint64 write_remainder;
-
- ssize_t (*raw_read)(RedsStream *s, void *buf, size_t nbyte);
- ssize_t (*raw_write)(RedsStream *s, const void *buf, size_t nbyte);
- ssize_t (*raw_writev)(RedsStream *s, const struct iovec *iov, int iovcnt);
-} RedsWebSocket;
-
struct RedsStreamPrivate {
SSL *ssl;
@@ -1151,39 +1140,17 @@ error:
static ssize_t stream_websocket_read(RedsStream *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_write_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(RedsStream *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(RedsStream *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);
}
/*
@@ -1232,6 +1199,7 @@ bool reds_stream_is_websocket(RedsStream *stream, unsigned char *buf, int len)
if (rc == strlen(outbuf)) {
stream->priv->ws = spice_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 1379487..533fc06 100644
--- a/server/websocket.c
+++ b/server/websocket.c
@@ -216,20 +216,29 @@ static int relay_data(guint8* buf, size_t size, websocket_frame_t *frame)
return n;
}
-int websocket_read(void *opaque, guchar *buf, int size, websocket_frame_t *frame,
- websocket_read_cb_t read_cb,
- websocket_write_cb_t write_cb)
+int websocket_read(RedsWebSocket *ws, guchar *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) {
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) {
if (n > 0 && rc == -1 && (errno == EINTR || errno == EAGAIN))
return n;
+ if (rc == 0) {
+ ws->closed = TRUE;
+ }
return rc;
}
frame->header_pos += rc;
@@ -238,6 +247,7 @@ int websocket_read(void *opaque, guchar *buf, int size, websocket_frame_t *frame
} 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));
@@ -245,6 +255,9 @@ int websocket_read(void *opaque, guchar *buf, int size, websocket_frame_t *frame
if (n > 0 && rc == -1 && (errno == EINTR || errno == EAGAIN))
return n;
+ if (rc == 0) {
+ ws->closed = TRUE;
+ }
return rc;
}
@@ -323,8 +336,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, guint64 *remainder,
- websocket_writev_cb_t writev_cb)
+int websocket_writev(RedsWebSocket *ws, struct iovec *iov, int iovcnt)
{
guint8 header[WEBSOCKET_MAX_HEADER_SIZE];
guint64 len;
@@ -333,7 +345,14 @@ int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remai
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;
+ guint64 *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);
@@ -376,12 +395,19 @@ int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remai
return rc;
}
-int websocket_write(void *opaque, const guchar *buf, int len, guint64 *remainder,
- websocket_write_cb_t write_cb)
+int websocket_write(RedsWebSocket *ws, const guchar *buf, int len)
{
guint8 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;
+ guint64 *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 2306492..2eb3431 100644
--- a/server/websocket.h
+++ b/server/websocket.h
@@ -17,6 +17,8 @@
#define WEBSOCKET_MAX_HEADER_SIZE (1 + 9 + 4)
+struct RedsStream;
+
typedef struct {
int type;
int masked;
@@ -32,14 +34,22 @@ typedef ssize_t (*websocket_read_cb_t)(void *opaque, const void *buf, size_t nby
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;
+ guint64 write_remainder;
+
+ struct RedsStream *raw_stream;
+ ssize_t (*raw_read)(struct RedsStream *s, void *buf, size_t nbyte);
+ ssize_t (*raw_write)(struct RedsStream *s, const void *buf, size_t nbyte);
+ ssize_t (*raw_writev)(struct RedsStream *s, const struct iovec *iov, int iovcnt);
+} RedsWebSocket;
+
bool websocket_is_start(gchar *buf);
void websocket_create_reply(gchar *buf, gchar *outbuf);
-int websocket_read(void *opaque, guchar *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 guchar *buf, int len, guint64 *remainder,
- websocket_write_cb_t write_cb);
-int websocket_writev(void *opaque, struct iovec *iov, int iovcnt, guint64 *remainder,
- websocket_writev_cb_t writev_cb);
+int websocket_read(RedsWebSocket *ws, guchar *buf, int len);
+int websocket_write(RedsWebSocket *ws, const guchar *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);
--
2.7.4
More information about the Spice-devel
mailing list