]> git.proxmox.com Git - mirror_qemu.git/blobdiff - io/channel-websock.c
target: Use vaddr in gen_intermediate_code
[mirror_qemu.git] / io / channel-websock.c
index 77d30f0e4aa496a407e2c3c24a72f20e645a265b..a12acc27cf25d312564c316469949482cb7020d6 100644 (file)
@@ -6,7 +6,7 @@
  * 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.
+ * version 2.1 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
 #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_GUID_LEN (sizeof(QIO_CHANNEL_WEBSOCK_GUID) - 1)
 
 #define QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL "sec-websocket-protocol"
 #define QIO_CHANNEL_WEBSOCK_HEADER_VERSION "sec-websocket-version"
     "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"              \
-    "Sec-WebSocket-Protocol: binary\r\n"        \
     "\r\n"
 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND \
     "HTTP/1.1 404 Not Found\r\n"                    \
@@ -149,7 +157,7 @@ enum {
     QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA
 };
 
-static void GCC_FMT_ATTR(2, 3)
+static void G_GNUC_PRINTF(2, 3)
 qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
                                        const char *resmsg,
                                        ...)
@@ -169,15 +177,9 @@ qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,
 
 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);
+    g_autoptr(GDateTime) now = g_date_time_new_now_utc();
 
-    return g_strdup(datebuf);
+    return g_date_time_format(now, "%a, %d %b %Y %H:%M:%S GMT");
 }
 
 static void qio_channel_websock_handshake_send_res_err(QIOChannelWebsock *ioc,
@@ -335,6 +337,7 @@ qio_channel_websock_find_header(QIOChannelWebsockHTTPHeader *hdrs,
 
 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 +
@@ -360,8 +363,14 @@ static void qio_channel_websock_handshake_send_res_ok(QIOChannelWebsock *ioc,
     }
 
     date = qio_channel_websock_date_str();
-    qio_channel_websock_handshake_send_res(
-        ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK, date, accept);
+    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);
@@ -386,10 +395,6 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
 
     protocols = qio_channel_websock_find_header(
         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(
         hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION);
@@ -429,10 +434,12 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
     trace_qio_channel_websock_http_request(ioc, protocols, version,
                                            host, connection, upgrade, key);
 
-    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 (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)) {
@@ -466,7 +473,7 @@ static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc,
         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;
 
  bad_request:
@@ -733,7 +740,7 @@ static int qio_channel_websock_decode_header(QIOChannelWebsock *ioc,
             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, "
+            error_setg(errp, "unsupported opcode: 0x%04x; only binary, close, "
                        "ping, and pong websocket frames are supported", opcode);
             qio_channel_websock_write_close(
                 ioc, QIO_CHANNEL_WEBSOCK_STATUS_INVALID_DATA ,
@@ -1074,6 +1081,7 @@ static ssize_t qio_channel_websock_readv(QIOChannel *ioc,
                                          size_t niov,
                                          int **fds,
                                          size_t *nfds,
+                                         int flags,
                                          Error **errp)
 {
     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
@@ -1120,6 +1128,7 @@ static ssize_t qio_channel_websock_writev(QIOChannel *ioc,
                                           size_t niov,
                                           int *fds,
                                           size_t nfds,
+                                          int flags,
                                           Error **errp)
 {
     QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);