Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for websocket? #49

Closed
squonk11 opened this issue Jul 12, 2019 · 101 comments
Closed

Support for websocket? #49

squonk11 opened this issue Jul 12, 2019 · 101 comments
Assignees
Projects

Comments

@squonk11
Copy link
Contributor

Hi, congratulations for these nice classes for the ESP32. I am currently searching for a HTTP(S) webserver software with the following attributes:

  1. esp-idf based (not Arduino)
  2. c++ based
  3. TLS cabable
  4. support for websockets (according to RFC6455)
    I see that 1. - 3. is already provided by your classes. The only thing missing for me is the support for websocket communication. Is there a plan to implement the websocket protocol also?
    Best regards
    Lothar
@PerMalmberg
Copy link
Owner

@squonk11 I'm actually currently thinking about how to best implement minimal, but functional, websocket support. If you have suggestions on how, feel free to contribute. PRs are accepted.

@squonk11
Copy link
Contributor Author

Unfortunately I am not a professional SW engineer but a privately interested enthusiast. I implemented already the websocket protocol into this repository. But since this is Arduino I am asking myself if it is easier to port this to esp-idf or implement websocket into "smooth".
I had a short look into your sources but until now I did not get the point how things work together. I see that you are using some quite sophisticated features of C++ which I am currently not so familiar with (as I said: I am not a professional SW engineer). Somewhere there must be the analysis of the received header - here the detection of the websocket connection must be implemented. Then the websocket connection must not be closed after the response - here it is also important to understand how this can be implemented.
Maybe you have some explanations which makes it easier for me to understand your sourecode?

@PerMalmberg
Copy link
Owner

PerMalmberg commented Jul 13, 2019

some quite sophisticated features of C++

Not really, mainly template and polymorphism. I'm sure you can understand it given time and a bit of help :)

The main classes of interest are likely application::network::http::HTTPProtocol and application::network::http::HTTPServerClient. As everything is templated all the way down to the core::network::Socket class, I'm thinking its probably best to extend the HTTPProtocol such that it can operate in two modes - regular HTTP verbs and Websocket. This can probably be done using either inheritance or composition; I'm thinking that the later is the better option since Websockets really aren't the same protocol has regular HTTP.

HTTPProtocol::data_received is likely the place to handle eventual upgrade-requests and once detected, switch "modes" and start delivering data in a format suitable for websockets to the applications. Currently HTTPPacket is used for this, so either that has to be changed, or some other way has to be found. An important part of the Smooth framework is that everything is event based so this will have to be too, meaning that just as there may be several HTTPPacket received by the application (e.g. a file is POST:ed by the client) in a single requests, websockets may have to split data into several parts too (unless Websockets guarantee a max packet size?)

Keep-alive is already property of the HTTPSServerClient so that functionality is easily achieved.

I'll be thinking about this a bit more while doing some gardening. Btw, I'm usually on IRC in #ESP32 @ freenode, under nick "permal" if you want to chat.

@PerMalmberg
Copy link
Owner

So I gave this some thought. I think the proper way is to rework the HTTPProtocol class such that it holds either a "regular HTTP protocol" or a "websocket protocol" implementation, but only one at a time. This way we can keep memory usage to a minimum, while still allowing an upgrade transition at runtime. It also plays nicely with the templatization.

PerMalmberg added a commit that referenced this issue Jul 13, 2019
PerMalmberg added a commit that referenced this issue Jul 13, 2019
PerMalmberg added a commit that referenced this issue Jul 13, 2019
PerMalmberg added a commit that referenced this issue Jul 13, 2019
@PerMalmberg
Copy link
Owner

@squonk11 As you can see, I've begun an implementation of websockets, currently working on the connection upgrade. Do you happen to have a good debugging tool for it, Firefox doesn't give any info on why it doesn't accept the websocket connection from /websocket.html, generated here?

@squonk11
Copy link
Contributor Author

Sorry for not answering yesterday - Saturdays and/or Sundays I have to take care for my father.
Thank you for already taking care of this topic. I think today I will have some time to take a look at the work you have done so far.

@PerMalmberg
Copy link
Owner

No worries, @squonk11. IRL is important :)

@squonk11
Copy link
Contributor Author

Sorry, but I did not get much time to check your sourcecode. What I have seen so far is that you already provided the skeleton for websockets and the detection of the upgrade. But reading the RegularHTTPProtocol.cpp (in order to make a similar WebsocketProtocol.cpp) is still a bit difficult for me as I am not so familiar with templates. I think I need to read first a little bit about using templates.
Additionally I am doing such work during my free time (which currently is quite small) - I would like to support/co-work with you on this but it will take time...

@PerMalmberg
Copy link
Owner

@squonk11 Its OK. I wanted this functionality myself so don't feel you owe me anything. I'm currently working out how to decode the incoming frames and how to re-use/transform the HTTPPacket class to act as a carrier for both regular HTTP and Websocket data.

If you have any gotchas from when you implemented the protocol feel free to share them.

FYI: I'm not going to support data frames with sizes given by 64 bits, it just doesn't make sense for an embedded device.

@squonk11
Copy link
Contributor Author

When I implemented the websocket server I implemented a WebsocketHandler class with virtual functions for onMessage, onClose and onError which the end-user has to override. For reading the data I was using a std::streambuf.
I encountered two pitfalls during the implementation:

  1. The extended payload length in the websocket frame is a 16 bit (or 64 bit) value in network byte order; so, that ntohs() (or ntohl() ) have to be used.
  2. The received data has to be de-masked only if the mask bit in the websocket frame is set.

Your approach not to implement frame sizes with 64bit size probably makes sense - although in my application I have to transmit a file with a size of approx. 170kB. Here 64k (16bit) is too small. In order to handle that amount of data I will be using a Wroover module with 8MB PSRAM. But I think I can also cut the file into pieces of <64kB.

@PerMalmberg
Copy link
Owner

I realized that handling 65k or larger is no additional work compared to handling <65k so I implemented it.

@PerMalmberg
Copy link
Owner

And it is thankfully reproducible on Linux.

@squonk11
Copy link
Contributor Author

squonk11 commented Aug 4, 2019

Good to know that it also happens on Linux. I will try to make some investigation this evening (when I am back home) using debug outputs on the ESP32. Maybe the root cause can be isolated by this.

@PerMalmberg
Copy link
Owner

I know now that something goes wrong when receiving data in WebSocketProtocol.cpp. Sometimes, the data in the buffer looks like garbage. I'm wondering if the de-masking is to blame?

@squonk11
Copy link
Contributor Author

squonk11 commented Aug 4, 2019

I now detected that sometimes the data sent from ESP to the client gets partially corrupted. I can see in the wireshark traces that some of the "a" are damaged. Everytime when this happens the client (browser) closes the TCP connection.
In the attached wireshark trace you can see this in packet #672; bytes 0x246 up to 0x248 are not "a" but 0xcf, 0xdf and 0xe9. This specific data sent from client to the ESP32 is o.k. - no corruption every byte is "a".
Maybe the client closes the TCP connection because the TCP checksum is not o.k (although wireshark does not indicate this... hmmm.).
websocket_disconnect_5.zip

PerMalmberg added a commit that referenced this issue Aug 4, 2019
option is trickier to get right re. indexing.
@PerMalmberg
Copy link
Owner

PerMalmberg commented Aug 4, 2019

Yep - it was the de-masking of the data that were wrong, so when the data was echoed back, it was just garbage. I tried to do it on the fly, but the indexing got wrong. Now it is done on a per-fragment basis instead. I'm still not sure if this covers all cases with different chunk sizes, but at at least I can't force the error any longer

I did have a look at this earlier today, but didn't see the issue then... oh well, got to keep oneself busy, right? :)

@PerMalmberg
Copy link
Owner

Ah, found a way to force the issue - set a chink size of 53 and send data in blocks of 8092. At least I now know what the problem is.

PerMalmberg added a commit that referenced this issue Aug 4, 2019
@PerMalmberg
Copy link
Owner

Argh, dammit. Its still possible to break it.

@PerMalmberg
Copy link
Owner

Hm, this is annoying. All of a sudden, a single message can't be properly demasked, but those before and after can. Is the masking key somehow corrupted?

I)WP: {"message_id":89,"data":"abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abc
(I)WP: defghijklmonpqrstuvwxyz12","length":4096}
(I)WP: {"message_id":90,"data":"abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abc
(I)WP: defghijklmonpqrstuvwxyz12","length":4096}
(I)WP: ��B>�N<��F?���j��K:�
a��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8��I<��E0��@5�](�Y,�Uj���n���b��M8
(I)WP: defghijklmonpqrstuvwxyz12","length":4096}
(I)WP: {"message_id":92,"data":"abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abc
(I)WP: defghijklmonpqrstuvwxyz12","length":4096}
(I)WP: {"message_id":93,"data":"abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abcdefghijklmonpqrstuvwxyz1234567890abc
(I)WP: defghijklmonpqrstuvwxyz12","length":4096}

@PerMalmberg
Copy link
Owner

Observation: It's always the first fragment of the message. The second part is OK.

(I)WP: �h�`�9�b���a�p�7�h�d�+�?�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f�/�b�#�n�'�k�;�v�?�r�3�4�y�0�}�<�+�f
(I)WP: defghijklmonpqrstuvwxyz12","length":4096}

@PerMalmberg
Copy link
Owner

Has to be a logic error in WebsocketProtocol::data_received. Taking a break until tomorrow evening.

@PerMalmberg
Copy link
Owner

Made the code as simple as I can and while it is much more stable now, sometimes the de-masked data is still garbage in the first fragment. The de-mask key is intact between the different fragments so that's not the problem.

It only seems to happen when FF or Chrome sends lots of data in a short amount of time. For example, I can send 10M multiple times, then all of a sudden there is demasked garbage.

@squonk11
Copy link
Contributor Author

squonk11 commented Aug 5, 2019

I could imagine that the problem is related to concurrency of incoming packets. E.g. I see that the demasking is done at the very end of WebsocketProtocol::data_received and that you do the demasking depending on the call to is_data_masked() just before. If in the meantime already the next packet arrived then is_data_masked() will deliver false because frame_data.header[1] & 0x80 for the letter "a" will be 0x0.

@PerMalmberg
Copy link
Owner

PerMalmberg commented Aug 5, 2019

The mask key is held for all fragments so it is still valid (and the code for demaksing is running)

https://github.com/PerMalmberg/Smooth/blob/feature/49-websocket/lib/smooth/application/network/http/websocket/WebsocketProtocol.cpp#L165

@PerMalmberg
Copy link
Owner

I think I've found the actual root cause. I've forgotten that there is no guarantee that data_received receives the amount requested in get_wanted_amount, only that it never receives more than the requested amount. As such the the protocol gets out of sync with the data and things stop working. I'm going to push a work-in-progress commit that logs some data that shows this is the case. To fix it, I'll probably rewrite the data_received, get_wanted_amount and get_write_pos. as can be seen in the coming commit, it just gets messy when trying to patch it.

@squonk11
Copy link
Contributor Author

squonk11 commented Aug 6, 2019

When I implemented websocket communication in the previous project I used std::streambuf for this. That worked quite painless. But I must confess that I didn't test it with large data objects.

@PerMalmberg
Copy link
Owner

With the last changes I'm now able to push gigabytes through a single websock connection without errors on a Linux system. However, when run on the ESP and really stressing the system, the connection breaks occationally, but I cannot see that it has anything to do with the implementation.

As such, I consider the implementation correct until someone proves otherwise, and it is repeatable on a Linux system.

@PerMalmberg
Copy link
Owner

@squonk11 I've merge websocket support into master. Closing this issue. Please open a new one if needed.

Smooth automation moved this from In progress to Done Aug 7, 2019
@squonk11
Copy link
Contributor Author

squonk11 commented Aug 9, 2019

I just wanted to inform you about the following observation:
I still had issues with large websocket transmissions: I found out that there are sometimes just single bytes destroyed in the packets received by the browser and due to this the browser stopped the TCP connection.
Now I found your conversation here. In this thread @igrr published a fix to the psram library. I also downloaded this fix and installed it.
Now the problem dissapeard! Your library seems to work perfectly now.

One other topic: I will need the ESP32 wifi to be working in access point mode. I will make a class "wifiAP" for this (similar to your wifi class). Are you interested in a pull request?

@PerMalmberg
Copy link
Owner

@squonk11 That's a good observation, and one I was hoping for. Memory issue are a pain; I'm glad I can develop on Linux before running things on the ESP, it allows me to be more sure of my own code.

Yes, I will accept PRs; expect constructive criticism. I've long thought of adding AP-support to the Wifi class, but never gotten around to it. Give some thought on if you can add it to the existing one, possibly renaming set_ap_credentialsto just set_credentials etc.

Please open a new issue for further discussions.

@squonk11
Copy link
Contributor Author

@PerMalmberg Yes, I will open a new issue for the wifi access point topic. But be aware that my progress will be quite slow because I am working on this during my free time which is very rare at the moment and in SW I am a hobbyist only (my profession is more related to HW).
Concerning the "constructive criticism": I am aware that criticism is the source of wisdom...
... and of course: this library is your code - so you decide which PR you take over and how the source shall be implemented. I will try to follow the current style of the existing sources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Smooth
  
Done
Development

No branches or pull requests

2 participants