mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-15 05:10:11 +00:00
websocket: Move RedsWebSocket to header
Intention is to make private in websockets.c and reduce changes in red-stream.c Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Jeremy White <jwhite@codeweavers.com>
This commit is contained in:
parent
26fad876a0
commit
98c183a6f6
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user