diff options
author | Brandon Carpenter <brandon.carpenter@cypherpath.com> | 2017-09-12 08:21:49 -0700 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2017-10-04 13:21:53 +0100 |
commit | ff1300e626949fa9850b0f91dc5e8c2cb45b6a88 (patch) | |
tree | 197f76576bfb71b5bf918a35f610b11fd6ca0618 /io | |
parent | eefa3d8ef649f9055611361e2201cca49f8c3433 (diff) | |
download | qemu-ff1300e626949fa9850b0f91dc5e8c2cb45b6a88.zip qemu-ff1300e626949fa9850b0f91dc5e8c2cb45b6a88.tar.gz qemu-ff1300e626949fa9850b0f91dc5e8c2cb45b6a88.tar.bz2 |
io: Add support for fragmented websocket binary frames
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 <brandon.carpenter@cypherpath.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'io')
-rw-r--r-- | io/channel-websock.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/io/channel-websock.c b/io/channel-websock.c index 4e5afb2..909d636 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -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; |