From nobody Sun Feb 8 01:21:33 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505222645942497.74616250673296; Tue, 12 Sep 2017 06:24:05 -0700 (PDT) Received: from localhost ([::1]:35847 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drlAb-0000PK-0P for importer@patchew.org; Tue, 12 Sep 2017 09:24:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40099) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drl5i-0005B8-Nd for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drl5d-0001Gh-V0 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55394) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drl5d-0001G2-Ll for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:18:57 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C8F2DC04B93A; Tue, 12 Sep 2017 13:18:56 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7778A66835; Tue, 12 Sep 2017 13:18:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C8F2DC04B93A Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 14:18:45 +0100 Message-Id: <20170912131847.27684-2-berrange@redhat.com> In-Reply-To: <20170912131847.27684-1-berrange@redhat.com> References: <20170912131847.27684-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 12 Sep 2017 13:18:56 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 1/3] io: send proper HTTP response for websocket errors X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Rak , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" When any error occurs while processing the websockets handshake, QEMU just terminates the connection abruptly. This is in violation of the HTTP specs and does not help the client understand what they did wrong. This is particularly bad when the client gives the wrong path, as a "404 Not Found" would be very helpful. Refactor the handshake code so that it always sends a response to the client unless there was an I/O error. Fixes bug: #1715186 Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Daniel P. Berrange --- io/channel-websock.c | 185 ++++++++++++++++++++++++++++++++++++++---------= ---- 1 file changed, 139 insertions(+), 46 deletions(-) diff --git a/io/channel-websock.c b/io/channel-websock.c index 5a3badbec2..f5fac5b422 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -25,6 +25,8 @@ #include "crypto/hash.h" #include "trace.h" =20 +#include + =20 /* Max amount to allow in rawinput/rawoutput buffers */ #define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192 @@ -44,13 +46,40 @@ #define QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE "Upgrade" #define QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET "websocket" =20 -#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE \ +#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \ + "Server: QEMU VNC\r\n" \ + "Date: %s\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" \ "Sec-WebSocket-Protocol: binary\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" @@ -123,8 +152,46 @@ enum { QIO_CHANNEL_WEBSOCK_OPCODE_PONG =3D 0xA }; =20 +static void qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc, + const char *resmsg, + ...) +{ + va_list vargs; + char *response; + size_t responselen; + + va_start(vargs, resmsg); + response =3D g_strdup_vprintf(resmsg, vargs); + responselen =3D strlen(response); + buffer_reserve(&ioc->encoutput, responselen); + buffer_append(&ioc->encoutput, response, responselen); + va_end(vargs); +} + +static gchar *qio_channel_websock_date_str(void) +{ + struct tm tm; + time_t now =3D 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 =3D qio_channel_websock_date_str(); + qio_channel_websock_handshake_send_res(ioc, resdata, date); + g_free(date); +} + static size_t -qio_channel_websock_extract_headers(char *buffer, +qio_channel_websock_extract_headers(QIOChannelWebsock *ioc, + char *buffer, QIOChannelWebsockHTTPHeader *hdrs, size_t nhdrsalloc, Error **errp) @@ -145,7 +212,7 @@ qio_channel_websock_extract_headers(char *buffer, nl =3D strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM); if (!nl) { error_setg(errp, "Missing HTTP header delimiter"); - return 0; + goto bad_request; } *nl =3D '\0'; =20 @@ -158,18 +225,20 @@ qio_channel_websock_extract_headers(char *buffer, =20 if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_METHOD)) { error_setg(errp, "Unsupported HTTP method %s", buffer); - return 0; + goto bad_request; } =20 buffer =3D tmp + 1; tmp =3D strchr(buffer, ' '); if (!tmp) { error_setg(errp, "Missing HTTP version delimiter"); - return 0; + goto bad_request; } *tmp =3D '\0'; =20 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; } @@ -178,7 +247,7 @@ qio_channel_websock_extract_headers(char *buffer, =20 if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_VERSION)) { error_setg(errp, "Unsupported HTTP version %s", buffer); - return 0; + goto bad_request; } =20 buffer =3D nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM); @@ -203,7 +272,7 @@ qio_channel_websock_extract_headers(char *buffer, sep =3D strchr(buffer, ':'); if (!sep) { error_setg(errp, "Malformed HTTP header"); - return 0; + goto bad_request; } *sep =3D '\0'; sep++; @@ -213,7 +282,7 @@ qio_channel_websock_extract_headers(char *buffer, =20 if (nhdrs >=3D nhdrsalloc) { error_setg(errp, "Too many HTTP headers"); - return 0; + goto bad_request; } =20 hdr =3D &hdrs[nhdrs++]; @@ -231,6 +300,11 @@ qio_channel_websock_extract_headers(char *buffer, } while (nl !=3D NULL); =20 return nhdrs; + + bad_request: + qio_channel_websock_handshake_send_res_err( + ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST); + return 0; } =20 static const char * @@ -250,14 +324,14 @@ qio_channel_websock_find_header(QIOChannelWebsockHTTP= Header *hdrs, } =20 =20 -static int qio_channel_websock_handshake_send_response(QIOChannelWebsock *= ioc, - const char *key, - Error **errp) +static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *i= oc, + const char *key, + Error **errp) { char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + QIO_CHANNEL_WEBSOCK_GUID_LEN + 1]; - char *accept =3D NULL, *response =3D NULL; - size_t responselen; + char *accept =3D NULL; + char *date =3D qio_channel_websock_date_str(); =20 g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1); g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID, @@ -271,105 +345,108 @@ static int qio_channel_websock_handshake_send_respo= nse(QIOChannelWebsock *ioc, QIO_CHANNEL_WEBSOCK_GUID_LEN, &accept, errp) < 0) { - return -1; + qio_channel_websock_handshake_send_res_err( + ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR); + return; } =20 - response =3D g_strdup_printf(QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE, a= ccept); - responselen =3D strlen(response); - buffer_reserve(&ioc->encoutput, responselen); - buffer_append(&ioc->encoutput, response, responselen); + qio_channel_websock_handshake_send_res( + ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept); =20 + g_free(date); g_free(accept); - g_free(response); - - return 0; } =20 -static int qio_channel_websock_handshake_process(QIOChannelWebsock *ioc, - char *buffer, - Error **errp) +static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc, + char *buffer, + Error **errp) { QIOChannelWebsockHTTPHeader hdrs[32]; size_t nhdrs =3D G_N_ELEMENTS(hdrs); const char *protocols =3D NULL, *version =3D NULL, *key =3D NULL, *host =3D NULL, *connection =3D NULL, *upgrade =3D NULL; =20 - nhdrs =3D qio_channel_websock_extract_headers(buffer, hdrs, nhdrs, err= p); + nhdrs =3D qio_channel_websock_extract_headers(ioc, buffer, hdrs, nhdrs= , errp); if (!nhdrs) { - return -1; + return; } =20 protocols =3D qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL); if (!protocols) { error_setg(errp, "Missing websocket protocol header data"); - return -1; + goto bad_request; } =20 version =3D qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION); if (!version) { error_setg(errp, "Missing websocket version header data"); - return -1; + goto bad_request; } =20 key =3D qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_KEY); if (!key) { error_setg(errp, "Missing websocket key header data"); - return -1; + goto bad_request; } =20 host =3D qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_HOST); if (!host) { error_setg(errp, "Missing websocket host header data"); - return -1; + goto bad_request; } =20 connection =3D qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION); if (!connection) { error_setg(errp, "Missing websocket connection header data"); - return -1; + goto bad_request; } =20 upgrade =3D qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE); if (!upgrade) { error_setg(errp, "Missing websocket upgrade header data"); - return -1; + goto bad_request; } =20 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); - return -1; + goto bad_request; } =20 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); - return -1; + goto bad_request; } =20 if (strlen(key) !=3D 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); - return -1; + goto bad_request; } =20 if (!g_strrstr(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE)) { error_setg(errp, "No connection upgrade requested '%s'", connectio= n); - return -1; + goto bad_request; } =20 if (!g_str_equal(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET)) { error_setg(errp, "Incorrect upgrade method '%s'", upgrade); - return -1; + goto bad_request; } =20 - return qio_channel_websock_handshake_send_response(ioc, key, errp); + qio_channel_websock_handshake_send_res_ok(ioc, key, errp); + return; + + bad_request: + qio_channel_websock_handshake_send_res_err( + ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST); } =20 static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc, @@ -393,20 +470,20 @@ static int qio_channel_websock_handshake_read(QIOChan= nelWebsock *ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_END); if (!handshake_end) { if (ioc->encinput.offset >=3D 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; + return 1; } else { return 0; } } *handshake_end =3D '\0'; =20 - if (qio_channel_websock_handshake_process(ioc, - (char *)ioc->encinput.buffer, - errp) < 0) { - return -1; - } + qio_channel_websock_handshake_process(ioc, + (char *)ioc->encinput.buffer, + errp); =20 buffer_advance(&ioc->encinput, handshake_end - (char *)ioc->encinput.buffer + @@ -438,8 +515,15 @@ static gboolean qio_channel_websock_handshake_send(QIO= Channel *ioc, =20 buffer_advance(&wioc->encoutput, ret); if (wioc->encoutput.offset =3D=3D 0) { - trace_qio_channel_websock_handshake_complete(ioc); - qio_task_complete(task); + if (wioc->io_err) { + trace_qio_channel_websock_handshake_fail(ioc); + qio_task_set_error(task, wioc->io_err); + wioc->io_err =3D 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); @@ -458,6 +542,11 @@ static gboolean qio_channel_websock_handshake_io(QIOCh= annel *ioc, =20 ret =3D 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); qio_task_set_error(task, err); qio_task_complete(task); @@ -469,6 +558,10 @@ static gboolean qio_channel_websock_handshake_io(QIOCh= annel *ioc, return TRUE; } =20 + if (err) { + error_propagate(&wioc->io_err, err); + } + trace_qio_channel_websock_handshake_reply(ioc); qio_channel_add_watch( wioc->master, --=20 2.13.5 From nobody Sun Feb 8 01:21:33 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505222543230791.578630535891; Tue, 12 Sep 2017 06:22:23 -0700 (PDT) Received: from localhost ([::1]:35838 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drl8w-0007ER-91 for importer@patchew.org; Tue, 12 Sep 2017 09:22:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40078) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drl5g-0005Ae-5q for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drl5f-0001Hb-2c for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38626) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drl5e-0001HJ-R6 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:18:59 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 03C0D81DF5; Tue, 12 Sep 2017 13:18:58 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 13F0D66857; Tue, 12 Sep 2017 13:18:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 03C0D81DF5 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 14:18:46 +0100 Message-Id: <20170912131847.27684-3-berrange@redhat.com> In-Reply-To: <20170912131847.27684-1-berrange@redhat.com> References: <20170912131847.27684-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 12 Sep 2017 13:18:58 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 2/3] io: include full error message in websocket handshake trace X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Rak , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" When the websocket handshake fails it is useful to log the real error message via the trace points for debugging purposes. Fixes bug: #1715186 Reviewed-by: Philippe Mathieu-Daud=C3=A9 Signed-off-by: Daniel P. Berrange --- io/channel-websock.c | 7 ++++--- io/trace-events | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/io/channel-websock.c b/io/channel-websock.c index f5fac5b422..6ddcec1549 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -507,7 +507,7 @@ static gboolean qio_channel_websock_handshake_send(QIOC= hannel *ioc, &err); =20 if (ret < 0) { - trace_qio_channel_websock_handshake_fail(ioc); + trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err= )); qio_task_set_error(task, err); qio_task_complete(task); return FALSE; @@ -516,7 +516,8 @@ static gboolean qio_channel_websock_handshake_send(QIOC= hannel *ioc, buffer_advance(&wioc->encoutput, ret); if (wioc->encoutput.offset =3D=3D 0) { if (wioc->io_err) { - trace_qio_channel_websock_handshake_fail(ioc); + trace_qio_channel_websock_handshake_fail( + ioc, error_get_pretty(wioc->io_err)); qio_task_set_error(task, wioc->io_err); wioc->io_err =3D NULL; qio_task_complete(task); @@ -547,7 +548,7 @@ static gboolean qio_channel_websock_handshake_io(QIOCha= nnel *ioc, * client connection, as most of the time we have an * HTTP 4xx err response to send instead */ - trace_qio_channel_websock_handshake_fail(ioc); + trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err= )); qio_task_set_error(task, err); qio_task_complete(task); return FALSE; diff --git a/io/trace-events b/io/trace-events index 3d233698d0..6459f71f5b 100644 --- a/io/trace-events +++ b/io/trace-events @@ -46,7 +46,7 @@ qio_channel_websock_new_server(void *ioc, void *master) "= Websock new client ioc=3D qio_channel_websock_handshake_start(void *ioc) "Websock handshake start io= c=3D%p" qio_channel_websock_handshake_pending(void *ioc, int status) "Websock hand= shake pending ioc=3D%p status=3D%d" qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply io= c=3D%p" -qio_channel_websock_handshake_fail(void *ioc) "Websock handshake fail ioc= =3D%p" +qio_channel_websock_handshake_fail(void *ioc, const char *msg) "Websock ha= ndshake fail ioc=3D%p err=3D%s" qio_channel_websock_handshake_complete(void *ioc) "Websock handshake compl= ete ioc=3D%p" =20 # io/channel-command.c --=20 2.13.5 From nobody Sun Feb 8 01:21:33 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505222428768932.0592511805181; Tue, 12 Sep 2017 06:20:28 -0700 (PDT) Received: from localhost ([::1]:35819 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drl76-0005rc-4A for importer@patchew.org; Tue, 12 Sep 2017 09:20:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40090) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drl5h-0005Ak-HN for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drl5g-0001Ia-7b for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50614) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drl5g-0001Ht-2p for qemu-devel@nongnu.org; Tue, 12 Sep 2017 09:19:00 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 34B455F73A; Tue, 12 Sep 2017 13:18:59 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.22.189]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3B68A66835; Tue, 12 Sep 2017 13:18:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 34B455F73A Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=berrange@redhat.com From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 14:18:47 +0100 Message-Id: <20170912131847.27684-4-berrange@redhat.com> In-Reply-To: <20170912131847.27684-1-berrange@redhat.com> References: <20170912131847.27684-1-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 12 Sep 2017 13:18:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 3/3] io: use case insensitive check for Connection & Upgrade websock headers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Brian Rak , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When checking the value of the Connection and Upgrade HTTP headers the websock RFC (6455) requires the comparison to be case insensitive. The Connection value should be an exact match not a substring. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange --- io/channel-websock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/io/channel-websock.c b/io/channel-websock.c index 6ddcec1549..2258557a21 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -431,12 +431,12 @@ static void qio_channel_websock_handshake_process(QIO= ChannelWebsock *ioc, goto bad_request; } =20 - if (!g_strrstr(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE)) { + if (strcasecmp(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) != =3D 0) { error_setg(errp, "No connection upgrade requested '%s'", connectio= n); goto bad_request; } =20 - if (!g_str_equal(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET)) { + if (strcasecmp(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET) !=3D 0)= { error_setg(errp, "Incorrect upgrade method '%s'", upgrade); goto bad_request; } --=20 2.13.5