0

I am trying to use WinHTTP to connect to server, unfortunately when i am trying to upgrade the protocol from http to webscoket, the API WinHttpSetOption fails.

hSessionHandle    = WinHttpOpen(L"WebSocket sample",WINHTTP_ACCESS_TYPE_NO_PROXY,NULL,  NULL,0);
hConnectionHandle = WinHttpConnect(hSessionHandle, L"localhost",INTERNET_DEFAULT_HTTP_PORT, 0);
hRequestHandle    = WinHttpOpenRequest(hConnectionHandle,L"GET",L"/ws",NULL,NULL,NULL,  0);

// Request protocol upgrade from http to websocket.
fStatus = WinHttpSetOption(hRequestHandle,WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET,NULL,0);
if (!fStatus)
{
   dwError = GetLastError();
   goto quit;
}

fStatus returns FALSE, with GetLastError returning error code 12009 which says

ERROR_WINHTTP_INVALID_OPTION
12009: A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value.

The above code is taken from the Microsoft WinHttp WebSocket demo (new GitHub home)

My system is Windows 7. Does the OS need to be Windows 8 or above? Any clues of this API fail?

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Sukhas
  • 89
  • 1
  • 8
  • Since the upgrade completion function, [`WinHttpWebSocketCompleteUpgrade`](https://msdn.microsoft.com/en-us/library/windows/desktop/hh707326(v=vs.85).aspx) clearly specifies Windows 8 as the minimal platform, I'm going to go ahead and say yeah, you need Windows 8 or beyond. – WhozCraig May 05 '16 at 07:39
  • Thanks WhozCraig....Is there any way we can use websockets with winHttp in Win 7? – Sukhas May 05 '16 at 08:44

2 Answers2

3

There's a great C++ WebSocket library here that works in Windows 7, its header-only and uses just boost. It comes with example code and documentation: http://vinniefalco.github.io/

Here's a complete program that sends a message to the echo server. This will work in Windows 7 for you.

#include <beast/websocket.hpp>
#include <beast/buffers_debug.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>

int main()
{
    // Normal boost::asio setup
    std::string const host = "echo.websocket.org";
    boost::asio::io_service ios;
    boost::asio::ip::tcp::resolver r(ios);
    boost::asio::ip::tcp::socket sock(ios);
    boost::asio::connect(sock,
        r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));

    using namespace beast::websocket;

    // WebSocket connect and send message using beast
    stream<boost::asio::ip::tcp::socket&> ws(sock);
    ws.handshake(host, "/");
    ws.write(boost::asio::buffer("Hello, world!"));

    // Receive WebSocket message, print and close using beast
    beast::streambuf sb;
    opcode op;
    ws.read(op, sb);
    ws.close(close_code::normal);
    std::cout <<
        beast::debug::buffers_to_string(sb.data()) << "\n";
}
Vinnie Falco
  • 5,173
  • 28
  • 43
0

Did you get this working?

I found that using "echo.websocket.org" was great for testing.

Also these are the values that worked for me:

WinHttpOpenRequest(
  IN HINTERNET hConnect,
  IN LPCWSTR   pwszVerb,           --- "GET"
  IN LPCWSTR   pwszObjectName,     --- NULL
  IN LPCWSTR   pwszVersion,        --- NULL
  IN LPCWSTR   pwszReferrer,       --- WINHTTP_NO_REFERER
  IN LPCWSTR   *ppwszAcceptTypes,  --- WINHTTP_DEFAULT_ACCEPT_TYPES
  IN DWORD     dwFlags             --- 0
);