/*
 * QEMU I/O channels driver websockets
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/bswap.h"
#include "io/channel-websock.h"
#include "crypto/hash.h"
#include "trace.h"


/* Max amount to allow in rawinput/rawoutput buffers */
#define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192

#define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24
#define QIO_CHANNEL_WEBSOCK_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#define QIO_CHANNEL_WEBSOCK_GUID_LEN strlen(QIO_CHANNEL_WEBSOCK_GUID)

#define QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL "Sec-WebSocket-Protocol"
#define QIO_CHANNEL_WEBSOCK_HEADER_VERSION "Sec-WebSocket-Version"
#define QIO_CHANNEL_WEBSOCK_HEADER_KEY "Sec-WebSocket-Key"

#define QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY "binary"

#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE  \
    "HTTP/1.1 101 Switching Protocols\r\n"      \
    "Upgrade: websocket\r\n"                    \
    "Connection: Upgrade\r\n"                   \
    "Sec-WebSocket-Accept: %s\r\n"              \
    "Sec-WebSocket-Protocol: binary\r\n"        \
    "\r\n"
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM "\r\n"
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_END "\r\n\r\n"
#define QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "13"

/* The websockets packet header is variable length
 * depending on the size of the payload... */

/* ...length when using 7-bit payload length */
#define QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT 6
/* ...length when using 16-bit payload length */
#define QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT 8
/* ...length when using 64-bit payload length */
#define QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT 14

/* Length of the optional data mask field in header */
#define QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK 4

/* Maximum length that can fit in 7-bit payload size */
#define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT 126
/* Maximum length that can fit in 16-bit payload size */
#define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT 65536

/* Magic 7-bit length to indicate use of 16-bit payload length */
#define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT 126
/* Magic 7-bit length to indicate use of 64-bit payload length */
#define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT 127

/* Bitmasks & shifts for accessing header fields */
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN 0x80
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80
#define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f
#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN 7
#define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK 7

typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader;

struct QEMU_PACKED QIOChannelWebsockHeader {
    unsigned char b0;
    unsigned char b1;
    union {
        struct QEMU_PACKED {
            uint16_t l16;
            QIOChannelWebsockMask m16;
        } s16;
        struct QEMU_PACKED {
            uint64_t l64;
            QIOChannelWebsockMask m64;
        } s64;
        QIOChannelWebsockMask m;
    } u;
};

enum {
    QIO_CHANNEL_WEBSOCK_OPCODE_CONTINUATION = 0x0,
    QIO_CHANNEL_WEBSOCK_OPCODE_TEXT_FRAME = 0x1,
    QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME = 0x2,
    QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE = 0x8,
    QIO_CHANNEL_WEBSOCK_OPCODE_PING = 0x9,
    QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA
};

static char *qio_channel_websock_handshake_entry(const char *handshake,
                                                 size_t handshake_len,
                                                 const char *name)
{
    char *begin, *end, *ret = NULL;
    char *line = g_strdup_printf("%s%s: ",
                                 QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM,
                                 name);
    begin = g_strstr_len(handshake, handshake_len, line);
    if (begin != NULL) {
        begin += strlen(line);
        end = g_strstr_len(begin, handshake_len - (begin - handshake),
                QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
        if (end != NULL) {
            ret = g_strndup(begin, end - begin);
        }
    }
    g_free(line);
    return ret;
}


static int qio_channel_websock_handshake_send_response(QIOChannelWebsock *ioc,
                                                       const char *key,
                                                       Error **errp)
{
    char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
                      QIO_CHANNEL_WEBSOCK_GUID_LEN + 1];
    char *accept = NULL, *response = NULL;
    size_t responselen;

    g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1);
    g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID,
              QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
              QIO_CHANNEL_WEBSOCK_GUID_LEN + 1);

    /* hash and encode it */
    if (qcrypto_hash_base64(QCRYPTO_HASH_ALG_SHA1,
                            combined_key,
                            QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
                            QIO_CHANNEL_WEBSOCK_GUID_LEN,
                            &accept,
                            errp) < 0) {
        return -1;
    }

    response = g_strdup_printf(QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE, accept);
    responselen = strlen(response);
    buffer_reserve(&ioc->encoutput, responselen);
    buffer_append(&ioc->encoutput, response, responselen);

    g_free(accept);
    g_free(response);

    return 0;
}

static int qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
                                                 const char *line,
                                                 size_t size,
                                                 Error **errp)
{
    int ret = -1;
    char *protocols = qio_channel_websock_handshake_entry(
        line, size, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL);
    char *version = qio_channel_websock_handshake_entry(
        line, size, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
    char *key = qio_channel_websock_handshake_entry(
        line, size, QIO_CHANNEL_WEBSOCK_HEADER_KEY);

    if (!protocols) {
        error_setg(errp, "Missing websocket protocol header data");
        goto cleanup;
    }

    if (!version) {
        error_setg(errp, "Missing websocket version header data");
        goto cleanup;
    }

    if (!key) {
        error_setg(errp, "Missing websocket key header data");
        goto cleanup;
    }

    if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) {
        error_setg(errp, "No '%s' protocol is supported by client '%s'",
                   QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols);
        goto cleanup;
    }

    if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) {
        error_setg(errp, "Version '%s' is not supported by client '%s'",
                   QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION, version);
        goto cleanup;
    }

    if (strlen(key) != QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN) {
        error_setg(errp, "Key length '%zu' was not as expected '%d'",
                   strlen(key), QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN);
        goto cleanup;
    }

    ret = qio_channel_websock_handshake_send_response(ioc, key, errp);

 cleanup:
    g_free(protocols);
    g_free(version);
    g_free(key);
    return ret;
}

static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,
                                              Error **errp)
{
    char *handshake_end;
    ssize_t ret;
    /* Typical HTTP headers from novnc are 512 bytes, so limiting
     * total header size to 4096 is easily enough. */
    size_t want = 4096 - ioc->encinput.offset;
    buffer_reserve(&ioc->encinput, want);
    ret = qio_channel_read(ioc->master,
                           (char *)buffer_end(&ioc->encinput), want, errp);
    if (ret < 0) {
        return -1;
    }
    ioc->encinput.offset += ret;

    handshake_end = g_strstr_len((char *)ioc->encinput.buffer,
                                 ioc->encinput.offset,
                                 QIO_CHANNEL_WEBSOCK_HANDSHAKE_END);
    if (!handshake_end) {
        if (ioc->encinput.offset >= 4096) {
            error_setg(errp,
                       "End of headers not found in first 4096 bytes");
            return -1;
        } else {
            return 0;
        }
    }

    if (qio_channel_websock_handshake_process(ioc,
                                              (char *)ioc->encinput.buffer,
                                              ioc->encinput.offset,
                                              errp) < 0) {
        return -1;
    }

    buffer_advance(&ioc->encinput,
                   handshake_end - (char *)ioc->encinput.buffer +
                   strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_END));
    return 1;
}

static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,
                                                   GIOCondition condition,
                                                   gpointer user_data)
{
    QIOTask *task = user_data;
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(
        qio_task_get_source(task));
    Error *err = NULL;
    ssize_t ret;

    ret = qio_channel_write(wioc->master,
                            (char *)wioc->encoutput.buffer,
                            wioc->encoutput.offset,
                            &err);

    if (ret < 0) {
        trace_qio_channel_websock_handshake_fail(ioc);
        qio_task_abort(task, err);
        error_free(err);
        return FALSE;
    }

    buffer_advance(&wioc->encoutput, ret);
    if (wioc->encoutput.offset == 0) {
        trace_qio_channel_websock_handshake_complete(ioc);
        qio_task_complete(task);
        return FALSE;
    }
    trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT);
    return TRUE;
}

static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc,
                                                 GIOCondition condition,
                                                 gpointer user_data)
{
    QIOTask *task = user_data;
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(
        qio_task_get_source(task));
    Error *err = NULL;
    int ret;

    ret = qio_channel_websock_handshake_read(wioc, &err);
    if (ret < 0) {
        trace_qio_channel_websock_handshake_fail(ioc);
        qio_task_abort(task, err);
        error_free(err);
        return FALSE;
    }
    if (ret == 0) {
        trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
        /* need more data still */
        return TRUE;
    }

    trace_qio_channel_websock_handshake_reply(ioc);
    qio_channel_add_watch(
        wioc->master,
        G_IO_OUT,
        qio_channel_websock_handshake_send,
        task,
        NULL);
    return FALSE;
}


static void qio_channel_websock_encode(QIOChannelWebsock *ioc)
{
    size_t header_size;
    union {
        char buf[QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT];
        QIOChannelWebsockHeader ws;
    } header;

    if (!ioc->rawoutput.offset) {
        return;
    }

    header.ws.b0 = (1 << QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN) |
        (QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &
         QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
    if (ioc->rawoutput.offset <
        QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
        header.ws.b1 = (uint8_t)ioc->rawoutput.offset;
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
    } else if (ioc->rawoutput.offset <
               QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT) {
        header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT;
        header.ws.u.s16.l16 = cpu_to_be16((uint16_t)ioc->rawoutput.offset);
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;
    } else {
        header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT;
        header.ws.u.s64.l64 = cpu_to_be64(ioc->rawoutput.offset);
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
    }
    header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK;

    buffer_reserve(&ioc->encoutput, header_size + ioc->rawoutput.offset);
    buffer_append(&ioc->encoutput, header.buf, header_size);
    buffer_append(&ioc->encoutput, ioc->rawoutput.buffer,
                  ioc->rawoutput.offset);
    buffer_reset(&ioc->rawoutput);
}


static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
                                                 Error **errp)
{
    unsigned char opcode, fin, has_mask;
    size_t header_size;
    size_t payload_len;
    QIOChannelWebsockHeader *header =
        (QIOChannelWebsockHeader *)ioc->encinput.buffer;

    if (ioc->payload_remain) {
        error_setg(errp,
                   "Decoding header but %zu bytes of payload remain",
                   ioc->payload_remain);
        return -1;
    }
    if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) {
        /* header not complete */
        return QIO_CHANNEL_ERR_BLOCK;
    }

    fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >>
        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN;
    opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;
    has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >>
        QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK;
    payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN;

    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.
     * * Only binary encoding is supported.
     */
    if (!fin) {
        error_setg(errp, "websocket fragmentation is not supported");
        return -1;
    }
    if (!has_mask) {
        error_setg(errp, "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;
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
        ioc->mask = header->u.m;
    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT &&
               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) {
        ioc->payload_remain = be16_to_cpu(header->u.s16.l16);
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT;
        ioc->mask = header->u.s16.m16;
    } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT &&
               ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) {
        ioc->payload_remain = be64_to_cpu(header->u.s64.l64);
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
        ioc->mask = header->u.s64.m64;
    } else {
        /* header not complete */
        return QIO_CHANNEL_ERR_BLOCK;
    }

    buffer_advance(&ioc->encinput, header_size);
    return 1;
}


static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc,
                                                  Error **errp)
{
    size_t i;
    size_t payload_len;
    uint32_t *payload32;

    if (!ioc->payload_remain) {
        error_setg(errp,
                   "Decoding payload but no bytes of payload remain");
        return -1;
    }

    /* If we aren't at the end of the payload, then drop
     * off the last bytes, so we're always multiple of 4
     * for purpose of unmasking, except at end of payload
     */
    if (ioc->encinput.offset < ioc->payload_remain) {
        payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4);
    } else {
        payload_len = ioc->payload_remain;
    }
    if (payload_len == 0) {
        return QIO_CHANNEL_ERR_BLOCK;
    }

    ioc->payload_remain -= payload_len;

    /* unmask frame */
    /* process 1 frame (32 bit op) */
    payload32 = (uint32_t *)ioc->encinput.buffer;
    for (i = 0; i < payload_len / 4; i++) {
        payload32[i] ^= ioc->mask.u;
    }
    /* process the remaining bytes (if any) */
    for (i *= 4; i < payload_len; i++) {
        ioc->encinput.buffer[i] ^= ioc->mask.c[i % 4];
    }

    buffer_reserve(&ioc->rawinput, payload_len);
    buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
    buffer_advance(&ioc->encinput, payload_len);
    return payload_len;
}


QIOChannelWebsock *
qio_channel_websock_new_server(QIOChannel *master)
{
    QIOChannelWebsock *wioc;
    QIOChannel *ioc;

    wioc = QIO_CHANNEL_WEBSOCK(object_new(TYPE_QIO_CHANNEL_WEBSOCK));
    ioc = QIO_CHANNEL(wioc);

    wioc->master = master;
    if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
        qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
    }
    object_ref(OBJECT(master));

    trace_qio_channel_websock_new_server(wioc, master);
    return wioc;
}

void qio_channel_websock_handshake(QIOChannelWebsock *ioc,
                                   QIOTaskFunc func,
                                   gpointer opaque,
                                   GDestroyNotify destroy)
{
    QIOTask *task;

    task = qio_task_new(OBJECT(ioc),
                        func,
                        opaque,
                        destroy);

    trace_qio_channel_websock_handshake_start(ioc);
    trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
    qio_channel_add_watch(ioc->master,
                          G_IO_IN,
                          qio_channel_websock_handshake_io,
                          task,
                          NULL);
}


static void qio_channel_websock_finalize(Object *obj)
{
    QIOChannelWebsock *ioc = QIO_CHANNEL_WEBSOCK(obj);

    buffer_free(&ioc->encinput);
    buffer_free(&ioc->encoutput);
    buffer_free(&ioc->rawinput);
    buffer_free(&ioc->rawoutput);
    object_unref(OBJECT(ioc->master));
    if (ioc->io_tag) {
        g_source_remove(ioc->io_tag);
    }
    if (ioc->io_err) {
        error_free(ioc->io_err);
    }
}


static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc,
                                             Error **errp)
{
    ssize_t ret;

    if (ioc->encinput.offset < 4096) {
        size_t want = 4096 - ioc->encinput.offset;

        buffer_reserve(&ioc->encinput, want);
        ret = qio_channel_read(ioc->master,
                               (char *)ioc->encinput.buffer +
                               ioc->encinput.offset,
                               want,
                               errp);
        if (ret < 0) {
            return ret;
        }
        if (ret == 0 &&
            ioc->encinput.offset == 0) {
            return 0;
        }
        ioc->encinput.offset += ret;
    }

    if (ioc->payload_remain == 0) {
        ret = qio_channel_websock_decode_header(ioc, errp);
        if (ret < 0) {
            return ret;
        }
        if (ret == 0) {
            return 0;
        }
    }

    ret = qio_channel_websock_decode_payload(ioc, errp);
    if (ret < 0) {
        return ret;
    }
    return ret;
}


static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc,
                                              Error **errp)
{
    ssize_t ret;
    ssize_t done = 0;
    qio_channel_websock_encode(ioc);

    while (ioc->encoutput.offset > 0) {
        ret = qio_channel_write(ioc->master,
                                (char *)ioc->encoutput.buffer,
                                ioc->encoutput.offset,
                                errp);
        if (ret < 0) {
            if (ret == QIO_CHANNEL_ERR_BLOCK &&
                done > 0) {
                return done;
            } else {
                return ret;
            }
        }
        buffer_advance(&ioc->encoutput, ret);
        done += ret;
    }
    return done;
}


static void qio_channel_websock_flush_free(gpointer user_data)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(user_data);
    object_unref(OBJECT(wioc));
}

static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc);

static gboolean qio_channel_websock_flush(QIOChannel *ioc,
                                          GIOCondition condition,
                                          gpointer user_data)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(user_data);
    ssize_t ret;

    if (condition & G_IO_OUT) {
        ret = qio_channel_websock_write_wire(wioc, &wioc->io_err);
        if (ret < 0) {
            goto cleanup;
        }
    }

    if (condition & G_IO_IN) {
        ret = qio_channel_websock_read_wire(wioc, &wioc->io_err);
        if (ret < 0) {
            goto cleanup;
        }
        if (ret == 0) {
            wioc->io_eof = TRUE;
        }
    }

 cleanup:
    qio_channel_websock_set_watch(wioc);
    return FALSE;
}


static void qio_channel_websock_unset_watch(QIOChannelWebsock *ioc)
{
    if (ioc->io_tag) {
        g_source_remove(ioc->io_tag);
        ioc->io_tag = 0;
    }
}

static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc)
{
    GIOCondition cond = 0;

    qio_channel_websock_unset_watch(ioc);

    if (ioc->io_err) {
        return;
    }

    if (ioc->encoutput.offset) {
        cond |= G_IO_OUT;
    }
    if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER &&
        !ioc->io_eof) {
        cond |= G_IO_IN;
    }

    if (cond) {
        object_ref(OBJECT(ioc));
        ioc->io_tag =
            qio_channel_add_watch(ioc->master,
                                  cond,
                                  qio_channel_websock_flush,
                                  ioc,
                                  qio_channel_websock_flush_free);
    }
}


static ssize_t qio_channel_websock_readv(QIOChannel *ioc,
                                         const struct iovec *iov,
                                         size_t niov,
                                         int **fds,
                                         size_t *nfds,
                                         Error **errp)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
    size_t i;
    ssize_t got = 0;
    ssize_t ret;

    if (wioc->io_err) {
        *errp = error_copy(wioc->io_err);
        return -1;
    }

    if (!wioc->rawinput.offset) {
        ret = qio_channel_websock_read_wire(QIO_CHANNEL_WEBSOCK(ioc), errp);
        if (ret < 0) {
            return ret;
        }
    }

    for (i = 0 ; i < niov ; i++) {
        size_t want = iov[i].iov_len;
        if (want > (wioc->rawinput.offset - got)) {
            want = (wioc->rawinput.offset - got);
        }

        memcpy(iov[i].iov_base,
               wioc->rawinput.buffer + got,
               want);
        got += want;

        if (want < iov[i].iov_len) {
            break;
        }
    }

    buffer_advance(&wioc->rawinput, got);
    qio_channel_websock_set_watch(wioc);
    return got;
}


static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
                                          const struct iovec *iov,
                                          size_t niov,
                                          int *fds,
                                          size_t nfds,
                                          Error **errp)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
    size_t i;
    ssize_t done = 0;
    ssize_t ret;

    if (wioc->io_err) {
        *errp = error_copy(wioc->io_err);
        return -1;
    }

    if (wioc->io_eof) {
        error_setg(errp, "%s", "Broken pipe");
        return -1;
    }

    for (i = 0; i < niov; i++) {
        size_t want = iov[i].iov_len;
        if ((want + wioc->rawoutput.offset) > QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
            want = (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->rawoutput.offset);
        }
        if (want == 0) {
            goto done;
        }

        buffer_reserve(&wioc->rawoutput, want);
        buffer_append(&wioc->rawoutput, iov[i].iov_base, want);
        done += want;
        if (want < iov[i].iov_len) {
            break;
        }
    }

 done:
    ret = qio_channel_websock_write_wire(wioc, errp);
    if (ret < 0 &&
        ret != QIO_CHANNEL_ERR_BLOCK) {
        qio_channel_websock_unset_watch(wioc);
        return -1;
    }

    qio_channel_websock_set_watch(wioc);

    if (done == 0) {
        return QIO_CHANNEL_ERR_BLOCK;
    }

    return done;
}

static int qio_channel_websock_set_blocking(QIOChannel *ioc,
                                            bool enabled,
                                            Error **errp)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);

    qio_channel_set_blocking(wioc->master, enabled, errp);
    return 0;
}

static void qio_channel_websock_set_delay(QIOChannel *ioc,
                                          bool enabled)
{
    QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc);

    qio_channel_set_delay(tioc->master, enabled);
}

static void qio_channel_websock_set_cork(QIOChannel *ioc,
                                         bool enabled)
{
    QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc);

    qio_channel_set_cork(tioc->master, enabled);
}

static int qio_channel_websock_shutdown(QIOChannel *ioc,
                                        QIOChannelShutdown how,
                                        Error **errp)
{
    QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc);

    return qio_channel_shutdown(tioc->master, how, errp);
}

static int qio_channel_websock_close(QIOChannel *ioc,
                                     Error **errp)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);

    return qio_channel_close(wioc->master, errp);
}

typedef struct QIOChannelWebsockSource QIOChannelWebsockSource;
struct QIOChannelWebsockSource {
    GSource parent;
    QIOChannelWebsock *wioc;
    GIOCondition condition;
};

static gboolean
qio_channel_websock_source_prepare(GSource *source,
                                   gint *timeout)
{
    QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
    GIOCondition cond = 0;
    *timeout = -1;

    if (wsource->wioc->rawinput.offset) {
        cond |= G_IO_IN;
    }
    if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
        cond |= G_IO_OUT;
    }

    return cond & wsource->condition;
}

static gboolean
qio_channel_websock_source_check(GSource *source)
{
    QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
    GIOCondition cond = 0;

    if (wsource->wioc->rawinput.offset) {
        cond |= G_IO_IN;
    }
    if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
        cond |= G_IO_OUT;
    }

    return cond & wsource->condition;
}

static gboolean
qio_channel_websock_source_dispatch(GSource *source,
                                    GSourceFunc callback,
                                    gpointer user_data)
{
    QIOChannelFunc func = (QIOChannelFunc)callback;
    QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
    GIOCondition cond = 0;

    if (wsource->wioc->rawinput.offset) {
        cond |= G_IO_IN;
    }
    if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
        cond |= G_IO_OUT;
    }

    return (*func)(QIO_CHANNEL(wsource->wioc),
                   (cond & wsource->condition),
                   user_data);
}

static void
qio_channel_websock_source_finalize(GSource *source)
{
    QIOChannelWebsockSource *ssource = (QIOChannelWebsockSource *)source;

    object_unref(OBJECT(ssource->wioc));
}

GSourceFuncs qio_channel_websock_source_funcs = {
    qio_channel_websock_source_prepare,
    qio_channel_websock_source_check,
    qio_channel_websock_source_dispatch,
    qio_channel_websock_source_finalize
};

static GSource *qio_channel_websock_create_watch(QIOChannel *ioc,
                                                 GIOCondition condition)
{
    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
    QIOChannelWebsockSource *ssource;
    GSource *source;

    source = g_source_new(&qio_channel_websock_source_funcs,
                          sizeof(QIOChannelWebsockSource));
    ssource = (QIOChannelWebsockSource *)source;

    ssource->wioc = wioc;
    object_ref(OBJECT(wioc));

    ssource->condition = condition;

    qio_channel_websock_set_watch(wioc);
    return source;
}

static void qio_channel_websock_class_init(ObjectClass *klass,
                                           void *class_data G_GNUC_UNUSED)
{
    QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);

    ioc_klass->io_writev = qio_channel_websock_writev;
    ioc_klass->io_readv = qio_channel_websock_readv;
    ioc_klass->io_set_blocking = qio_channel_websock_set_blocking;
    ioc_klass->io_set_cork = qio_channel_websock_set_cork;
    ioc_klass->io_set_delay = qio_channel_websock_set_delay;
    ioc_klass->io_close = qio_channel_websock_close;
    ioc_klass->io_shutdown = qio_channel_websock_shutdown;
    ioc_klass->io_create_watch = qio_channel_websock_create_watch;
}

static const TypeInfo qio_channel_websock_info = {
    .parent = TYPE_QIO_CHANNEL,
    .name = TYPE_QIO_CHANNEL_WEBSOCK,
    .instance_size = sizeof(QIOChannelWebsock),
    .instance_finalize = qio_channel_websock_finalize,
    .class_init = qio_channel_websock_class_init,
};

static void qio_channel_websock_register_types(void)
{
    type_register_static(&qio_channel_websock_info);
}

type_init(qio_channel_websock_register_types);
