Ответ WebSockets со стороны сервера, черновик 00 - PullRequest
0 голосов
/ 22 февраля 2012

Я пишу небольшое серверное приложение WebSocket, которое должно поддерживать как черновик 17 , так и более старые варианты, такие как черновик 00 . У меня не было проблем с новейшим черновиком, но я не могу осчастливить клиента черновика 00.

В целях тестирования я использовал приведенный в официальном (старом) примере черновик 00 документов , стр. 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

При вычислении ключей путем объединения цифр и деления на количество пробелов я получаю следующие два целых числа: 155712099 и 173347027 (в документе также есть эти два числа).

Далее говорится:

  1. Конвертировать их по отдельности в Big Endian
  2. Объединить результат в строку и добавить последние восемь бит (Tm[K T2u).
  3. Создает 128-битную сумму MD5 из строки, созданной в шагах 1 и 2.

Вооружившись этим знанием, я создал следующий код:

#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);

Вот что я получаю:

←→»α√r¼??┐☺║Pa♠µ

И вот что ожидается (опять же, на основе чернового примера)

fQJ,fN/4F4!~K~MH

С другой стороны, я заметил, что в статье Википедии ничего не говорится о преобразовании Endian. Я пробовал приведенный выше код без преобразования (как пример википедии, так и пример из черновика) и до сих пор не могу воспроизвести ожидаемый результат.

Кто-нибудь может указать, в чем здесь проблема?


EDIT:

Я нашел этот документ содержит лучшее объяснение протокола. Это другой проект (76), но он похож на 00 с точки зрения рукопожатия.

Ответы [ 2 ]

2 голосов
/ 23 февраля 2012

Наконец, с помощью свежих глаз от моих коллег, я понял, что я делаю не так.По сути, я буквально объединял два целых числа в строку.Вместо этого мне нужно было объединить байты:

uint num1 = LE_TO_BE_LONG(155712099); // macros definition can
uint num2 = LE_TO_BE_LONG(173347027); // be found in the question
QString cookie = QString::fromUtf8("Tm[K T2u");

QByteArray array;

array =  QByteArray((const char*)&num1, sizeof(int));
array += QByteArray((const char*)&num2, sizeof(int));
array += QByteArray(cookie.toStdString().data(), cookie.length());

qDebug() << QCryptographicHash::hash(array, QCryptographicHash::Md5);

Убедитесь, что , что вы не используете перегруженный конструктор, который не принимает размер, потому что Qt создаст немного больший массив, дополненныймусор.По крайней мере, так было в моем случае.

2 голосов
/ 23 февраля 2012

Здесь - это расчет в реализации C websockify . Я знаю, что это работает, так что вы можете использовать это в качестве ссылки.

...