[Libwebsockets] Max char limit on websocket requests.

Andy Green andy at warmcat.com
Mon Nov 1 18:22:21 CET 2021

On 11/1/21 15:19, Arsh Patankar wrote:

cc-ing to the list again...

> Been in a back and forth with binance and they've now discovered that my 
> problem is due to a bug on their servers. They advise to open multiple 

Well, I did point out that it's always a policy decision of the server 
if it will give you a 400 or not...

> connections of up to 108 streams (instead of the quoted 200) until they 
> can fix it. What's the best way to do this using lws? I tried throwing 
> the same thing on two threads (where each one individually runs fine) it 
> like this:
> std::thread websocket1(VWAP::start_websockets, info);
> std::thread websocket2(VWAP::start_websockets, info);
> websocket1.join();
> websocket2.join();
> But that didn't work.

No... event loops are not threadsafe


but the good news is you can just use the connection creation info twice 
to create two connections, ie call lws_client_connect_via_info() twice, 
I guess modifying the path part inbetwwen to do the other half of 
whatever it is.


> -Arsh
> On 10/29/21 3:40 PM, Andy Green wrote:
>> On 10/29/21 15:32, Arsh Patankar wrote:
>>> I've made the changes you said with regards to path and adding the 
>>> CMake option to the debugger:
>>> I can see now that the cmake debug has been filled with data but non 
>>> of it shows the request (I scrolled through it all a number of times 
>>> attached is just an example):
>> When it says "Manually-specified variables were not used by the 
>> project" it means cmake could not wire up what you gave to an option 
>> in the CMakeLists.txt.
>> But, that has been an option in lws for a while
>> https://libwebsockets.org/git/libwebsockets/tree/CMakeLists.txt#n194
>> either the lws is too old to have that option, or something to do with 
>> your build process; I guess you're giving the cmake option to the 
>> outer project.
>> What I would do is hack the couple of lines this enables in, this is 
>> the place
>> https://libwebsockets.org/git/libwebsockets/tree/lib/tls/openssl/openssl-ssl.c#n343-351 
>> -Andy
>>> The standard debugger isn't showing anything useful either:
>>> the path is, however, correct. Just to show you, here is an example 
>>> of it working when the request is smaller:
>>> Have I done what you said correctly?
>>> -Arsh
>>> On 10/29/21 7:12 AM, Andy Green wrote:
>>>> On 10/28/21 21:15, Arsh Patankar wrote:
>>>>> I've found the bit of code that sets that up now. The relavent one 
>>>>> I believe is this one:
>>>>> void binance::Websocket::init()
>>>>> {
>>>>>     lws_context_creation_info info;
>>>>>     memset(&info,0,sizeof(info));
>>>>>     info.port =CONTEXT_PORT_NO_LISTEN;
>>>>>     info.protocols = protocols;
>>>>>     info.gid = -1;
>>>>>     info.uid = -1;
>>>>>      info.pt_serv_buf_size=4096*5;
>>>>>      info.max_http_header_data =1024*20;
>>>>>     // This option is needed here to imply 
>>>>> LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT // option, which must be set 
>>>>> on newer versions of OpenSSL. info.options 
>>>>>     context = lws_create_context(&info);
>>>>> }
>>>> Yes that looks like the one.
>>>>> This function also exists but i don't think it is the limiting factor:
>>>>> void binance::Websocket::connect_fendpoint(CB cb,const char* path)
>>>>> {
>>>>>      binance::Logger::write_log("<connect_endpoint>");
>>>>>      char ws_path[1024*20];// was 1024 strcpy(ws_path, path);
>>>> So the strcpy() is a buffer overflow, but since the path is not 
>>>> modified, the whole ws_path[] thing and the strcpy can go away and 
>>>> just set ccinfo.path to path itself.  Copying it into a stack buffer 
>>>> doesn't do anything except crash your program if it's bigger than 
>>>> the buffer. Internally lws handles it by a mixture of preallocated 
>>>> buffers (that it carefully size checks) and a custom-sized heap 
>>>> buffer to hold it in case of need later for redirects.
>>>>>      // Connect if we are not connected to the server. 
>>>>> lws_client_connect_info ccinfo = {0 };
>>>>>      ccinfo.context = context;
>>>>>      ccinfo.address =BINANCE_FWS_HOST;
>>>>>      ccinfo.port =BINANCE_FWS_PORT;
>>>>>      ccinfo.path = ws_path;
>>>>>      ccinfo.host = lws_canonical_hostname(context);
>>>>>      ccinfo.origin ="origin";
>>>>>      ccinfo.protocol = protocols[0].name;
>>>>>      ccinfo.ssl_connection =LCCSCF_USE_SSL |LCCSCF_ALLOW_SELFSIGNED 
>>>>>      lws* conn = lws_client_connect_via_info(&ccinfo);
>>>>>      handles[conn] = cb;
>>>>> }
>>>>> Also just noticed a different error (was hidden in the logs) 
>>>>> 'LWS_CALLBACK_CLIENT_CONNECTION_ERROR'. Not sure if this gives a 
>>>>> clue into what is causing the problem. I've added the 
>>>>> 'info.pt_serv_buf_size=4096*5;' but that hasn't fixed it.
>>>> If there's more than one problem, not finding yourself suddenly at 
>>>> the top of the mountain doesn't change you are no longer at the 
>>>> bottom of the mountain.  For example the strcpy [1024] thing alone 
>>>> would kill you and I can't guess the existence of that.  What it 
>>>> means is [y]our model of what is really happening, doesn't reflect 
>>>> reality yet.
>>>> Lws works with, and tests for operation with in CI, huge urls (2KB 
>>>> path)
>>>> https://libwebsockets.org/git/libwebsockets/tree/minimal-examples-lowlevel/http-client/minimal-http-client-hugeurl 
>>>> so this is not new ground and as far as that goes, it is supported.
>>>> There's a convenient, simple (if noisy) debug helper cmake option 
>>>> for lws, -DLWS_TLS_LOG_PLAINTEXT_TX=1, this will hexdump what lws is 
>>>> sending on the tls connection just before the data is encrypted.  So 
>>>> it will show you what we are actually trying to send to the server.  
>>>> Unless the server decides to 400 us for its own policy reasons, 
>>>> whatever is wrong should show up in there, even if the root cause is 
>>>> earlier.
>>>> -Andy
>>>>> -Arsh
>>>>> On 10/27/21 3:29 PM, andy at warmcat.com wrote:
>>>>>> On 27 October 2021 14:25:53 UTC, Arsh 
>>>>>> Patankar<arsh.patankar at btinternet.com>  wrote:
>>>>>>> You are correct, what I am using came with lws. Following
>>>>>>> 'pt_serv_buf_size', I find usages in the file 'context.c'.
>>>>>> ... no, you do not need to change lws.
>>>>>> Some other software, outside of lws, is creating an lws context 
>>>>>> using one of those info structs.  Find and modify that before it 
>>>>>> calls through to lws to create the context.
>>>>>> -Andy

More information about the Libwebsockets mailing list