io/channel-websock: treat 'binary' and no sub-protocol as the same
noVNC doesn't use 'binary' protocol by default after commit c912230309806aacbae4295faf7ad6406da97617. It will cause qemu return 400 when handshaking. To overcome this problem and remain compatibility of older noVNC client. We treat 'binary' and no sub-protocol as the same so that we can support different version of noVNC client. Tested on noVNC before c912230 and after c912230. Buglink: https://bugs.launchpad.net/qemu/+bug/1849644 Signed-off-by: Yu-Chen Lin <npes87184@gmail.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
5b7686f3fa
commit
c64e1e7538
@ -49,7 +49,7 @@
|
|||||||
"Server: QEMU VNC\r\n" \
|
"Server: QEMU VNC\r\n" \
|
||||||
"Date: %s\r\n"
|
"Date: %s\r\n"
|
||||||
|
|
||||||
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK \
|
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_WITH_PROTO_RES_OK \
|
||||||
"HTTP/1.1 101 Switching Protocols\r\n" \
|
"HTTP/1.1 101 Switching Protocols\r\n" \
|
||||||
QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
|
QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
|
||||||
"Upgrade: websocket\r\n" \
|
"Upgrade: websocket\r\n" \
|
||||||
@ -57,6 +57,13 @@
|
|||||||
"Sec-WebSocket-Accept: %s\r\n" \
|
"Sec-WebSocket-Accept: %s\r\n" \
|
||||||
"Sec-WebSocket-Protocol: binary\r\n" \
|
"Sec-WebSocket-Protocol: binary\r\n" \
|
||||||
"\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 \
|
#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND \
|
||||||
"HTTP/1.1 404 Not Found\r\n" \
|
"HTTP/1.1 404 Not Found\r\n" \
|
||||||
QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
|
QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
|
||||||
@ -336,6 +343,7 @@ qio_channel_websock_find_header(QIOChannelWebsockHTTPHeader *hdrs,
|
|||||||
|
|
||||||
static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
|
static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
|
||||||
const char *key,
|
const char *key,
|
||||||
|
const bool use_protocols,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
|
char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN +
|
||||||
@ -361,8 +369,14 @@ static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
date = qio_channel_websock_date_str();
|
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(
|
qio_channel_websock_handshake_send_res(
|
||||||
ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
|
ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
|
||||||
|
}
|
||||||
|
|
||||||
g_free(date);
|
g_free(date);
|
||||||
g_free(accept);
|
g_free(accept);
|
||||||
@ -387,10 +401,6 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
|
|||||||
|
|
||||||
protocols = qio_channel_websock_find_header(
|
protocols = qio_channel_websock_find_header(
|
||||||
hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL);
|
hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL);
|
||||||
if (!protocols) {
|
|
||||||
error_setg(errp, "Missing websocket protocol header data");
|
|
||||||
goto bad_request;
|
|
||||||
}
|
|
||||||
|
|
||||||
version = qio_channel_websock_find_header(
|
version = qio_channel_websock_find_header(
|
||||||
hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
|
hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
|
||||||
@ -430,11 +440,13 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
|
|||||||
trace_qio_channel_websock_http_request(ioc, protocols, version,
|
trace_qio_channel_websock_http_request(ioc, protocols, version,
|
||||||
host, connection, upgrade, key);
|
host, connection, upgrade, key);
|
||||||
|
|
||||||
|
if (protocols) {
|
||||||
if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) {
|
if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) {
|
||||||
error_setg(errp, "No '%s' protocol is supported by client '%s'",
|
error_setg(errp, "No '%s' protocol is supported by client '%s'",
|
||||||
QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols);
|
QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols);
|
||||||
goto bad_request;
|
goto bad_request;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) {
|
if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) {
|
||||||
error_setg(errp, "Version '%s' is not supported by client '%s'",
|
error_setg(errp, "Version '%s' is not supported by client '%s'",
|
||||||
@ -467,7 +479,7 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
|
|||||||
goto bad_request;
|
goto bad_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
qio_channel_websock_handshake_send_res_ok(ioc, key, errp);
|
qio_channel_websock_handshake_send_res_ok(ioc, key, !!protocols, errp);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bad_request:
|
bad_request:
|
||||||
|
Loading…
Reference in New Issue
Block a user