Expand description
§FOR FUTURE ME (me talking to me in the future)
Well oussama if you come next year and you did take a look at this code, and start blaming yourself on why you wasted time doing this, like you always do, then read the following:
§MOTIVATION
I tried to integrate a couple of websockets crates but boy it was just plain painfull, way too complicated and time consuming when all i need is get the data that the client sent and move on with my life.
So i find it to be easier and straight forward (thanks to tokio) to simply implement a decoder and encoder for websocket frames.
This is in no way a full implementation of RFC 6455, but rather an implementation in a controlled environment that only adds features required by the application, and since the client will always be a legit browser then ill safely make some assumptions and skip some checks (like validating the frame structure).
My minimal websocket implementation will only be used by xtermjs frontend using AttachAddon.
§FEATURES
[+] Receive opcode TEXT
[+] Pong when Ping is received
[+] Handle all payload lengths (**le 125**, **=126**, **=127**)
[+] Mask key
[+] Close websocket connection
[+] Read fragmented payload
[+] Extract websocket to its own crate
[ ] Add binary support
[ ] Send fragmented frame when the size reaches a treshold
[ ] Schedule ping/pong
[ ] Pong with application data included in ping
[ ] Keep track of connected clients
§REFERENCE
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
FIN (1 bit): if 1 -> final fragment
RSV1 RSV2 RSV3 (3 bit): Must be 0 unless an extension defines them (SKIP)
Opcode (4 bit): Always assume its good (data sent from browser)
- 0 -> continuation frame
- 1 -> text frame
- 2 -> binary frame
- 3-7 -> reserved for further non-control frames
- 8 -> connection closed
- 9 -> ping
- A -> pong
- B-F -> reserved for further control frames
Mask (1 bit): if 1 -> masking key is present. #section 5.3
Payload length (7 bit, 7+16 bit, 7+64 bit): length of the payload data
- 0-125 -> thats the payload length
- 126 -> next 2 bytes (UNSIGNED) are the payload length
- 127 -> next 8 bytes (UNSIGNED) are the payload length
Masking key (0 or 4 bytes): present if mask bit is set to 1. #section 5.3
Payload data (x+y bytes): extension data + application data
Extension data (x bytes): is 0 unless an extension is negotiated (not in our case)
Application data (y bytes): is payload length - length of extension data