/*
 * 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"
#include "qemu/iov.h"
#include "qemu/module.h"

/* Max amount to allow in rawinput/encoutput 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_HEADER_UPGRADE "upgrade"
#define QIO_CHANNEL_WEBSOCK_HEADER_HOST "host"
#define QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION "connection"

#define QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY "binary"
#define QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE "Upgrade"
#define QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET "websocket"

#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
    "Server: QEMU VNC\r\n"                       \
    "Date: %s\r\n"

#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_WITH_PROTO_RES_OK \
    "HTTP/1.1 101 Switching Protocols\r\n"              \
    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON            \
    "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_RES_OK    \
    "HTTP/1.1 101 Switching Protocols\r\n"      \
    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON    \
    "Upgrade: websocket\r\n"                    \
    "Connection: Upgrade\r\n"                   \
    "Sec-WebSocket-Accept: %s\r\n"              \
    "\r\n"
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND \
    "HTTP/1.1 404 Not Found\r\n"                    \
    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON        \
    "Connection: close\r\n"                         \
    "\r\n"
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST \
    "HTTP/1.1 400 Bad Request\r\n"                    \
    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON          \
    "Connection: close\r\n"                           \
    "Sec-WebSocket-Version: "                         \
    QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION             \
    "\r\n"
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR \
    "HTTP/1.1 500 Internal Server Error\r\n"         \
    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON         \
    "Connection: close\r\n"                          \
    "\r\n"
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE  \
    "HTTP/1.1 403 Request Entity Too Large\r\n"      \
    QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON         \
    "Connection: close\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"
#define QIO_CHANNEL_WEBSOCK_HTTP_METHOD "GET"
#define QIO_CHANNEL_WEBSOCK_HTTP_PATH "/"
#define QIO_CHANNEL_WEBSOCK_HTTP_VERSION "HTTP/1.1"

/* 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 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_CONTROL_OPCODE_MASK 0x8

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;
};

typedef struct QIOChannelWebsockHTTPHeader QIOChannelWebsockHTTPHeader;

struct QIOChannelWebsockHTTPHeader {
    char *name;
    char *value;
};

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 void GCC_FMT_ATTR(2, 3)
qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
                                       const char *resmsg,
                                       ...)
{
    va_list vargs;
    char *response;
    size_t responselen;

    va_start(vargs, resmsg);
    response = g_strdup_vprintf(resmsg, vargs);
    responselen = strlen(response);
    buffer_reserve(&ioc->encoutput, responselen);
    buffer_append(&ioc->encoutput, response, responselen);
    g_free(response);
    va_end(vargs);
}

static gchar *qio_channel_websock_date_str(void)
{
    struct tm tm;
    time_t now = time(NULL);
    char datebuf[128];

    gmtime_r(&now, &tm);

    strftime(datebuf, sizeof(datebuf), "%a, %d %b %Y %H:%M:%S GMT", &tm);

    return g_strdup(datebuf);
}

static void qio_channel_websock_handshake_send_res_err(QIOChannelWebsock *ioc,
                                                       const char *resdata)
{
    char *date = qio_channel_websock_date_str();
    qio_channel_websock_handshake_send_res(ioc, resdata, date);
    g_free(date);
}

enum {
    QIO_CHANNEL_WEBSOCK_STATUS_NORMAL = 1000,
    QIO_CHANNEL_WEBSOCK_STATUS_PROTOCOL_ERR = 1002,
    QIO_CHANNEL_WEBSOCK_STATUS_INVALID_DATA = 1003,
    QIO_CHANNEL_WEBSOCK_STATUS_POLICY = 1008,
    QIO_CHANNEL_WEBSOCK_STATUS_TOO_LARGE = 1009,
    QIO_CHANNEL_WEBSOCK_STATUS_SERVER_ERR = 1011,
};

static size_t
qio_channel_websock_extract_headers(QIOChannelWebsock *ioc,
                                    char *buffer,
                                    QIOChannelWebsockHTTPHeader *hdrs,
                                    size_t nhdrsalloc,
                                    Error **errp)
{
    char *nl, *sep, *tmp;
    size_t nhdrs = 0;

    /*
     * First parse the HTTP protocol greeting of format:
     *
     *   $METHOD $PATH $VERSION
     *
     * e.g.
     *
     *   GET / HTTP/1.1
     */

    nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
    if (!nl) {
        error_setg(errp, "Missing HTTP header delimiter");
        goto bad_request;
    }
    *nl = '\0';
    trace_qio_channel_websock_http_greeting(ioc, buffer);

    tmp = strchr(buffer, ' ');
    if (!tmp) {
        error_setg(errp, "Missing HTTP path delimiter");
        return 0;
    }
    *tmp = '\0';

    if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_METHOD)) {
        error_setg(errp, "Unsupported HTTP method %s", buffer);
        goto bad_request;
    }

    buffer = tmp + 1;
    tmp = strchr(buffer, ' ');
    if (!tmp) {
        error_setg(errp, "Missing HTTP version delimiter");
        goto bad_request;
    }
    *tmp = '\0';

    if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_PATH)) {
        qio_channel_websock_handshake_send_res_err(
            ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND);
        error_setg(errp, "Unexpected HTTP path %s", buffer);
        return 0;
    }

    buffer = tmp + 1;

    if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_VERSION)) {
        error_setg(errp, "Unsupported HTTP version %s", buffer);
        goto bad_request;
    }

    buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);

    /*
     * Now parse all the header fields of format
     *
     *   $NAME: $VALUE
     *
     * e.g.
     *
     *   Cache-control: no-cache
     */
    do {
        QIOChannelWebsockHTTPHeader *hdr;

        nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
        if (nl) {
            *nl = '\0';
        }

        sep = strchr(buffer, ':');
        if (!sep) {
            error_setg(errp, "Malformed HTTP header");
            goto bad_request;
        }
        *sep = '\0';
        sep++;
        while (*sep == ' ') {
            sep++;
        }

        if (nhdrs >= nhdrsalloc) {
            error_setg(errp, "Too many HTTP headers");
            goto bad_request;
        }

        hdr = &hdrs[nhdrs++];
        hdr->name = buffer;
        hdr->value = sep;

        /* Canonicalize header name for easier identification later */
        for (tmp = hdr->name; *tmp; tmp++) {
            *tmp = g_ascii_tolower(*tmp);
        }

        if (nl) {
            buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM);
        }
    } while (nl != NULL);

    return nhdrs;

 bad_request:
    qio_channel_websock_handshake_send_res_err(
        ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST);
    return 0;
}

static const char *
qio_channel_websock_find_header(QIOChannelWebsockHTTPHeader *hdrs,
                                size_t nhdrs,
                                const char *name)
{
    size_t i;

    for (i = 0; i < nhdrs; i++) {
        if (g_str_equal(hdrs[i].name, name)) {
            return hdrs[i].value;
        }
    }

    return NULL;
}


static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
                                                      const char *key,
                                                      const bool use_protocols,
                                                      Error **errp)
{
    char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
                      QIO_CHANNEL_WEBSOCK_GUID_LEN + 1];
    char *accept = NULL;
    char *date = NULL;

    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) {
        qio_channel_websock_handshake_send_res_err(
            ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR);
        return;
    }

    date = qio_channel_websock_date_str();
    if (use_protocols) {
            qio_channel_websock_handshake_send_res(
                ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_WITH_PROTO_RES_OK,
                date, accept);
    } else {
            qio_channel_websock_handshake_send_res(
                ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
    }

    g_free(date);
    g_free(accept);
}

static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
                                                  char *buffer,
                                                  Error **errp)
{
    QIOChannelWebsockHTTPHeader hdrs[32];
    size_t nhdrs = G_N_ELEMENTS(hdrs);
    const char *protocols = NULL, *version = NULL, *key = NULL,
        *host = NULL, *connection = NULL, *upgrade = NULL;
    char **connectionv;
    bool upgraded = false;
    size_t i;

    nhdrs = qio_channel_websock_extract_headers(ioc, buffer, hdrs, nhdrs, errp);
    if (!nhdrs) {
        return;
    }

    protocols = qio_channel_websock_find_header(
        hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL);

    version = qio_channel_websock_find_header(
        hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
    if (!version) {
        error_setg(errp, "Missing websocket version header data");
        goto bad_request;
    }

    key = qio_channel_websock_find_header(
        hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_KEY);
    if (!key) {
        error_setg(errp, "Missing websocket key header data");
        goto bad_request;
    }

    host = qio_channel_websock_find_header(
        hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_HOST);
    if (!host) {
        error_setg(errp, "Missing websocket host header data");
        goto bad_request;
    }

    connection = qio_channel_websock_find_header(
        hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION);
    if (!connection) {
        error_setg(errp, "Missing websocket connection header data");
        goto bad_request;
    }

    upgrade = qio_channel_websock_find_header(
        hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE);
    if (!upgrade) {
        error_setg(errp, "Missing websocket upgrade header data");
        goto bad_request;
    }

    trace_qio_channel_websock_http_request(ioc, protocols, version,
                                           host, connection, upgrade, key);

    if (protocols) {
            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 bad_request;
            }
    }

    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 bad_request;
    }

    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 bad_request;
    }

    connectionv = g_strsplit(connection, ",", 0);
    for (i = 0; connectionv != NULL && connectionv[i] != NULL; i++) {
        g_strstrip(connectionv[i]);
        if (strcasecmp(connectionv[i],
                       QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) == 0) {
            upgraded = true;
        }
    }
    g_strfreev(connectionv);
    if (!upgraded) {
        error_setg(errp, "No connection upgrade requested '%s'", connection);
        goto bad_request;
    }

    if (strcasecmp(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET) != 0) {
        error_setg(errp, "Incorrect upgrade method '%s'", upgrade);
        goto bad_request;
    }

    qio_channel_websock_handshake_send_res_ok(ioc, key, !!protocols, errp);
    return;

 bad_request:
    qio_channel_websock_handshake_send_res_err(
        ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST);
}

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) {
            qio_channel_websock_handshake_send_res_err(
                ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE);
            error_setg(errp,
                       "End of headers not found in first 4096 bytes");
            return 1;
        } else if (ret == 0) {
            error_setg(errp,
                       "End of headers not found before connection closed");
            return -1;
        }
        return 0;
    }
    *handshake_end = '\0';

    qio_channel_websock_handshake_process(ioc,
                                          (char *)ioc->encinput.buffer,
                                          errp);

    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, error_get_pretty(err));
        qio_task_set_error(task, err);
        qio_task_complete(task);
        return FALSE;
    }

    buffer_advance(&wioc->encoutput, ret);
    if (wioc->encoutput.offset == 0) {
        if (wioc->io_err) {
            trace_qio_channel_websock_handshake_fail(
                ioc, error_get_pretty(wioc->io_err));
            qio_task_set_error(task, wioc->io_err);
            wioc->io_err = NULL;
            qio_task_complete(task);
        } else {
            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) {
        /*
         * We only take this path on a fatal I/O error reading from
         * client connection, as most of the time we have an
         * HTTP 4xx err response to send instead
         */
        trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
        qio_task_set_error(task, err);
        qio_task_complete(task);
        return FALSE;
    }
    if (ret == 0) {
        trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN);
        /* need more data still */
        return TRUE;
    }

    error_propagate(&wioc->io_err, err);

    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,
                                       uint8_t opcode,
                                       const struct iovec *iov,
                                       size_t niov,
                                       size_t size)
{
    size_t header_size;
    size_t i;
    union {
        char buf[QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT];
        QIOChannelWebsockHeader ws;
    } header;

    assert(size <= iov_size(iov, niov));

    header.ws.b0 = QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN |
        (opcode & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE);
    if (size < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) {
        header.ws.b1 = (uint8_t)size;
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT;
    } else if (size < 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)size);
        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(size);
        header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT;
    }
    header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK;

    trace_qio_channel_websock_encode(ioc, opcode, header_size, size);
    buffer_reserve(&ioc->encoutput, header_size + size);
    buffer_append(&ioc->encoutput, header.buf, header_size);
    for (i = 0; i < niov && size != 0; i++) {
        size_t want = iov[i].iov_len;
        if (want > size) {
            want = size;
        }
        buffer_append(&ioc->encoutput, iov[i].iov_base, want);
        size -= want;
    }
}


static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *, Error **);


static void qio_channel_websock_write_close(QIOChannelWebsock *ioc,
                                            uint16_t code, const char *reason)
{
    struct iovec iov[2] = {
        { .iov_base = &code, .iov_len = sizeof(code) },
    };
    size_t niov = 1;
    size_t size = iov[0].iov_len;

    cpu_to_be16s(&code);

    if (reason) {
        iov[1].iov_base = (void *)reason;
        iov[1].iov_len = strlen(reason);
        size += iov[1].iov_len;
        niov++;
    }
    qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
                               iov, niov, size);
    qio_channel_websock_write_wire(ioc, NULL);
    qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
}


static int 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);
        qio_channel_websock_write_close(
            ioc, QIO_CHANNEL_WEBSOCK_STATUS_SERVER_ERR,
            "internal server error");
        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;
    opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE;
    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;
    }

    trace_qio_channel_websock_header_partial_decode(ioc, payload_len,
                                                    fin, opcode, (int)has_mask);

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

    /* Websocket frame sanity check:
     * * Fragmentation is only supported for binary frames.
     * * All frames sent by a client MUST be masked.
     * * Only binary and ping/pong encoding is supported.
     */
    if (!fin) {
        if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
            error_setg(errp, "only binary websocket frames may be fragmented");
            qio_channel_websock_write_close(
                ioc, QIO_CHANNEL_WEBSOCK_STATUS_POLICY ,
                "only binary frames may be fragmented");
            return -1;
        }
    } else {
        if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME &&
            opcode != QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE &&
            opcode != QIO_CHANNEL_WEBSOCK_OPCODE_PING &&
            opcode != QIO_CHANNEL_WEBSOCK_OPCODE_PONG) {
            error_setg(errp, "unsupported opcode: %#04x; only binary, close, "
                       "ping, and pong websocket frames are supported", opcode);
            qio_channel_websock_write_close(
                ioc, QIO_CHANNEL_WEBSOCK_STATUS_INVALID_DATA ,
                "only binary, close, ping, and pong frames are supported");
            return -1;
        }
    }
    if (!has_mask) {
        error_setg(errp, "client websocket frames must be masked");
        qio_channel_websock_write_close(
            ioc, QIO_CHANNEL_WEBSOCK_STATUS_PROTOCOL_ERR,
            "client frames must be masked");
        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 (opcode & QIO_CHANNEL_WEBSOCK_CONTROL_OPCODE_MASK) {
        error_setg(errp, "websocket control frame is too large");
        qio_channel_websock_write_close(
            ioc, QIO_CHANNEL_WEBSOCK_STATUS_PROTOCOL_ERR,
            "control frame is too large");
        return -1;
    } 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;
    }

    trace_qio_channel_websock_header_full_decode(
        ioc, header_size, ioc->payload_remain, ioc->mask.u);
    buffer_advance(&ioc->encinput, header_size);
    return 0;
}


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

    if (ioc->payload_remain) {
        /* 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) {
            /* Wait for the entire payload before processing control frames
             * because the payload will most likely be echoed back. */
            if (ioc->opcode & QIO_CHANNEL_WEBSOCK_CONTROL_OPCODE_MASK) {
                return QIO_CHANNEL_ERR_BLOCK;
            }
            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];
        }
    }

    trace_qio_channel_websock_payload_decode(
        ioc, ioc->opcode, ioc->payload_remain);

    if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) {
        if (payload_len) {
            /* binary frames are passed on */
            buffer_reserve(&ioc->rawinput, payload_len);
            buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len);
        }
    } else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) {
        /* close frames are echoed back */
        error_setg(errp, "websocket closed by peer");
        if (payload_len) {
            /* echo client status */
            struct iovec iov = { .iov_base = ioc->encinput.buffer,
                                 .iov_len = ioc->encinput.offset };
            qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE,
                                       &iov, 1, iov.iov_len);
            qio_channel_websock_write_wire(ioc, NULL);
            qio_channel_shutdown(ioc->master, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
        } else {
            /* send our own status */
            qio_channel_websock_write_close(
                ioc, QIO_CHANNEL_WEBSOCK_STATUS_NORMAL, "peer requested close");
        }
        return -1;
    } else if (ioc->opcode == QIO_CHANNEL_WEBSOCK_OPCODE_PING) {
        /* ping frames produce an immediate reply, as long as we've not still
         * got a previous pong queued, in which case we drop the new pong */
        if (ioc->pong_remain == 0) {
            struct iovec iov = { .iov_base = ioc->encinput.buffer,
                                 .iov_len = ioc->encinput.offset };
            qio_channel_websock_encode(ioc, QIO_CHANNEL_WEBSOCK_OPCODE_PONG,
                                       &iov, 1, iov.iov_len);
            ioc->pong_remain = ioc->encoutput.offset;
        }
    }   /* pong frames are ignored */

    if (payload_len) {
        buffer_advance(&ioc->encinput, payload_len);
    }
    return 0;
}


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);
    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) {
            ioc->io_eof = TRUE;
            return 0;
        }
        ioc->encinput.offset += ret;
    }

    while (ioc->encinput.offset != 0) {
        if (ioc->payload_remain == 0) {
            ret = qio_channel_websock_decode_header(ioc, errp);
            if (ret < 0) {
                return ret;
            }
        }

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


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

    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;
        if (ioc->pong_remain < ret) {
            ioc->pong_remain = 0;
        } else {
            ioc->pong_remain -= 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;
        }
    }

 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) {
        error_propagate(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);
    ssize_t want = iov_size(iov, niov);
    ssize_t avail;
    ssize_t ret;

    if (wioc->io_err) {
        error_propagate(errp, error_copy(wioc->io_err));
        return -1;
    }

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

    avail = wioc->encoutput.offset >= QIO_CHANNEL_WEBSOCK_MAX_BUFFER ?
        0 : (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->encoutput.offset);
    if (want > avail) {
        want = avail;
    }

    if (want) {
        qio_channel_websock_encode(wioc,
                                   QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME,
                                   iov, niov, want);
    }

    /* Even if want == 0, we'll try write_wire in case there's
     * pending data we could usefully flush out
     */
    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 (want == 0) {
        return QIO_CHANNEL_ERR_BLOCK;
    }

    return want;
}

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);

    trace_qio_channel_websock_close(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_check(GSource *source)
{
    QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source;
    GIOCondition cond = 0;

    if (wsource->wioc->rawinput.offset) {
        cond |= G_IO_IN;
    }
    if (wsource->wioc->encoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) {
        cond |= G_IO_OUT;
    }
    if (wsource->wioc->io_eof) {
        cond |= G_IO_HUP;
    }
    if (wsource->wioc->io_err) {
        cond |= G_IO_ERR;
    }

    return cond & wsource->condition;
}

static gboolean
qio_channel_websock_source_prepare(GSource *source,
                                   gint *timeout)
{
    *timeout = -1;
    return qio_channel_websock_source_check(source);
}

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

    return (*func)(QIO_CHANNEL(wsource->wioc),
                   qio_channel_websock_source_check(source),
                   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);
