[PATCH] winhttp: Support WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET option

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Fri Jun 12 01:32:45 CDT 2020


Example used
https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/WinhttpWebsocket

When this option is used, it adds the following headers
Connection, Upgrade, Sec-WebSocket-Key, Sec-WebSocket-Version

Using wireshark shows,

Without Option

GET /index.html HTTP/1.1
Connection: Keep-Alive
User-Agent: WebSocket sample
Host: XXXXX

With Option

GET /index.html HTTP/1.1
Connection: Upgrade
Upgrade: websocket
User-Agent: WebSocket sample
Sec-WebSocket-Key: FbVt3BszLghHUJlUAGA+kw==
Sec-WebSocket-Version: 13
Host: XXXXX

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/winhttp/session.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 24455d858a6..105e292b15d 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -1042,6 +1042,38 @@ static BOOL request_set_option( struct object_header *hdr, DWORD option, void *b
         FIXME("WINHTTP_OPTION_CONNECT_RETRIES\n");
         return TRUE;
 
+    case WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET:
+    {
+        BYTE buf[16];
+        WCHAR str[64];
+        DWORD length = 64;
+        int i;
+
+        add_request_headers(request, L"Connection: Upgrade", -1,
+                                WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
+        add_request_headers(request, L"Upgrade: websocket", -1,
+                                WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
+        add_request_headers(request, L"Sec-WebSocket-Version: 13", -1,
+                                WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
+
+        for(i = 0; i < sizeof(buf); i++)
+            buf[i] = rand() % 256;
+
+        /*
+         * As per rfc6455, Sec-WebSocket-Key is a base64-encoded 16 BYTE array value.
+         */
+        if (CryptBinaryToStringW(buf, sizeof(buf), CRYPT_STRING_BASE64, str, &length))
+        {
+            WCHAR websocketkey[64];
+
+            swprintf(websocketkey, ARRAY_SIZE(websocketkey), L"Sec-WebSocket-Key: %s", str);
+
+            add_request_headers(request, websocketkey, -1,
+                                    WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
+        }
+        return TRUE;
+    }
+
     default:
         FIXME("unimplemented option %u\n", option);
         SetLastError( ERROR_WINHTTP_INVALID_OPTION );
-- 
2.26.2




More information about the wine-devel mailing list