Skip to content

Commit

Permalink
io: Add support for fragmented websocket binary frames
Browse files Browse the repository at this point in the history
Allows fragmented binary frames by saving the previous opcode. Handles
the case where an intermediary (i.e., web proxy) fragments frames
originally sent unfragmented by the client.

Signed-off-by: Brandon Carpenter <[email protected]>
Signed-off-by: Daniel P. Berrange <[email protected]>
  • Loading branch information
Brandon Carpenter authored and berrange committed Oct 4, 2017
1 parent eefa3d8 commit ff1300e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
1 change: 1 addition & 0 deletions include/io/channel-websock.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct QIOChannelWebsock {
guint io_tag;
Error *io_err;
gboolean io_eof;
uint8_t opcode;
};

/**
Expand Down
26 changes: 18 additions & 8 deletions io/channel-websock.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,28 +636,38 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
has_mask = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK;
payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;

/* Save or restore opcode. */
if (opcode) {
ioc->opcode = opcode;
} else {
opcode = ioc->opcode;
}

if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
/* disconnect */
return 0;
}

/* Websocket frame sanity check:
* * Websocket fragmentation is not supported.
* * All websockets frames sent by a client have to be masked.
* * Fragmentation is only supported for binary frames.
* * All frames sent by a client MUST be masked.
* * Only binary encoding is supported.
*/
if (!fin) {
error_setg(errp, "websocket fragmentation is not supported");
return -1;
if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
error_setg(errp, "only binary websocket frames may be fragmented");
return -1;
}
} else {
if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
error_setg(errp, "only binary websocket frames are supported");
return -1;
}
}
if (!has_mask) {
error_setg(errp, "client websocket frames must be masked");
return -1;
}
if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
error_setg(errp, "only binary websocket frames are supported");
return -1;
}

if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) {
ioc->payload_remain = payload_len;
Expand Down

0 comments on commit ff1300e

Please sign in to comment.