Доступ к REST API: код JS и Python выполняет свою работу, но Qt / C ++ не может.Зачем? - PullRequest
0 голосов
/ 17 декабря 2018

Я пишу клиент для работы с сервером Python, работающим в локальной сети.Я думаю, что код сервера не имеет смысла показывать здесь, потому что он работает как положено (протестировано с клиентами, написанными на JavaScript и Python ... и Почтальон ).

Проблема: клиент, написанный на Qt / C ++, не работает должным образом.Тело ответа всегда пусто.

Сервер .

На мой конкретный запрос сервер отвечает кодом ошибки 500 и телом в формате: { "message" : "error reason" }.

Wireshark .Я использовал этот инструмент, чтобы узнать количество запросов и проверить тела ответов.Во всех случаях ответы имели ожидаемые тела.

Клиент Qt / C ++.

Клиент Qt написан простым, очень стандартным способом Qt:

manager = new QNetworkAccessManager();
QObject::connect(manager, &QNetworkAccessManager::finished,
                [](QNetworkReply *reply)
{
    QByteArray response = reply->readAll();
    qDebug() << "Response body:" << response;
    if (reply->error())
        qDebug() << "System error msg:" << reply->errorString();
    else
        qDebug() << "Success!";
});

qDebug() << "Sending IrsInit request:";
QString initApi = "http://192.168.101.127:1122/api/v1/replay/initReplay";
QUrl url = QUrl(initApi);
QNetworkRequest request = QNetworkRequest(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
QJsonObject bodyObj
{
    { "game_id", "5c0768177fb8217354de84d0" },
    { "objects", QJsonArray{
            QJsonObject{ {"id", "5c0768207fb8217354de84d1"}, {"name", "Demon"} }
        }
    }
};
QJsonDocument *doc = new QJsonDocument(bodyObj);
qDebug() << "url:" << url.toString() << "\nbody:" << doc->toJson();

manager->post(request, doc->toJson());

Вот вывод:

Sending IrsInit request:
url: "http://192.168.101.127:1122/api/v1/replay/initReplay" 
body: "{"game_id": "5c0768177fb8217354de84d0", "objects": [{"id":"5c0768207fb8217354de84d1","name": "Demon"}]}"
Response body: ""
System error msg: "Connection closed"    // error code is QNetworkReply::RemoteHostClosedError

Здесь вывод показывает, что один запрос был отправлен, а тело ответа пусто (и код ответа также примечание 500, я думаю,).Тем не менее, Wireshark показывает совершенно другое для этого запроса:

IP-адрес сервера - *.*.*.127
IP-адрес клиента - *.*.*.128

enter image description here

Как я проверил с сервером, при отправке одного запроса от этого клиента сервер получал не только один, но и разное количество запросов (от 1 до 4).В этом примере сервер показывает 4 полученных запроса соответственно.Более того, в Wireshark, все ответы имеют ожидаемые тела .

Я не знаю, почему это происходит: Qt показывает, что он отправил один запрос, но Wireshark и сервер говорят, что было отправлено 4 запроса.Долгие часы отладки не давали никаких намеков.Буду признателен за любые предложения (решения, отладка, указания)!


JavaScript-клиент.

var xhr = new XMLHttpRequest();
var url = "http://192.168.101.127:1122/api/v1/replay/initReplay";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {          
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log('Status 200');
        console.log('Response\n');
        var json = JSON.parse(xhr.responseText);
        console.log(json);
    }

    if (xhr.status === 500) {
        console.log('Status 500');
        console.log('Response\n');
        var json = JSON.parse(xhr.responseText);
        console.log(json);
    }
};
var data = JSON.stringify({"game_id":"5c0768177fb8217354de84d0","objects":[{"id":"5c0768207fb8217354de84d1","name":"Demon"}]});
xhr.send(data);

Вывод :

enter image description here

Я не знаю, почему он напечатал три раза, но сервер получил (всегда правильно) один запрос.И Wireshark доказывает это:

enter image description here

Python-клиент.

import sys
import requests

post_fields = {
   "game_id":"5c0768177fb8217354de84d0",
   "objects":[
   {
      "id":"5c0768207fb8217354de84d1",
      "name":"Demon"
   }
   ]
}
link    = 'http://192.168.101.127:1122/api/v1/replay/initReplay'
s = requests.Session()
resp    = s.post(link,data=post_fields)
print(resp)
print(resp.content)

Вывод :

enter image description here

Клиент Python работал идеально.Выход Wireshark:

enter image description here

...