Example used https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/Win...
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@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 );
On Fri, 2020-06-12 at 16:32 +1000, Alistair Leslie-Hughes wrote:
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;
ARRAY_SIZE(str)
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);
Can you add a test to show that headers are set here? A simple websocket echo test would be nice too. And please check add_request_headers for failure.
for(i = 0; i < sizeof(buf); i++)
buf[i] = rand() % 256;
Should this be stored somewhere?
Hi Hans,
Thanks for the review.
On 12/6/20 5:15 pm, Hans Leidekker wrote:
On Fri, 2020-06-12 at 16:32 +1000, Alistair Leslie-Hughes wrote:
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
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
Can you add a test to show that headers are set here? A simple websocket echo test would be nice too. And please check add_request_headers for failure.
I started writing a test, which forced the key to specific value, however the returned key failed to validate and is causing a test failure. So, my guess that since it cannot be manually set, these are added during WinHttpSendRequest if the option has been set.
We might need to store the string for validation in WinHttpWebSocketCompleteUpgrade.
I'll update the patch to reflect this.
Regards Alistair.