I am writing a small WebSocket server application that should support both draft 17 and older variations such as draft 00. I didn’t have any problems with the newest draft, but I cannot make the draft 00 client happy.
For testing purposes I used the example provided in the official (old) draft 00 docuemnt, page 7:
Sec-WebSocket-Key1: 18x 6]8vM;54 *(5: { U1]8 z [ 8
Sec-WebSocket-Key2: 1_ tx7X d < nw 334J702) 7]o}` 0
Tm[K T2u
When calculating the keys by concatenating the digits and dividing by spaces count, I get the following two integers: 155712099 and 173347027 (the document has these two numbers as well).
Next, it says to:
- Convert them individually to Big Endian
- Concatenate the result in a string and append the last eight bits (
Tm[K T2u). - Create a 128 bits MD5 sum from the string produced in step 1 and 2.
Armed with this knowledge I’ve produced the following code:
#define BYTE 8
#define WORD 16
// Little Endian to Big Endian short
#define LE_TO_BE_SHORT(SHORT)\
(((SHORT >> BYTE) & 0x00FF) | ((SHORT << BYTE) & 0xFF00))
// Little Endian to Big Endian long
#define LE_TO_BE_LONG(LONG)\
(((LE_TO_BE_SHORT(LONG >> WORD)) | \
((LE_TO_BE_SHORT((LONG & 0xFFFF)) << WORD))))
uint num1 = LE_TO_BE_LONG(155712099);
uint num2 = LE_TO_BE_LONG(173347027);
QString cookie = QString::fromUtf8("Tm[K T2u");
QString c = QString::number(num1) + QString::number(num2) + cookie;
QByteArray data = c.toUtf8();
qDebug() << QCryptographicHash::hash(data, QCryptographicHash::Md5);
Here’s what I get:
←→»α√r¼??┐☺║Pa♠µ
And here’s what’s expected (again, based on the draft example)
fQJ,fN/4F4!~K~MH
On the other side, I’ve noticed that the wikipedia article does not mention anything about Endian conversion. I tried the above code without conversion (both wikipedia example and the example from the draft) and still cannot reproduce the expected result.
Anyone can point out what is the problem here?
EDIT:
I found this document has a better explanation of the protocol. It is a different draft (76) but is similar to 00 in terms of handshake.
Finally with the help of fresh eyes from my colleagues, I figured out what I was doing wrong. Basically I was literally concatenating the two integers into a string. Instead I needed to concatenate the bytes:
Make sure that you don’t use the overloaded constructor that does not take the size because Qt will crate a slightly larger array padded with garbage. At least that was in my case.