Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [client HTTP]réponse au format xml ?  (Lu 8480 fois)

0 Membres et 1 Invité sur ce sujet

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
[client HTTP]réponse au format xml ?
« le: Janvier 12, 2013, 02:03:08 am »
Bonjour,

j'ai un web service respectant le protocole REST et utilisant l'API CodeIgniter et j'aimerais utiliser la SFML et son client HTTP pour envoyer mes requêtes GET et POST.  Malheureusement, je reçois le code erreur 1000 (invalid http response) là où mon web service renvoie quelque chose comme :

<xml>
   <item>
      toto
   </item>
</xml>
 

N'est-ce pas possible de récupérer des informations sous ce format ? (Même chose avec le format JSON).

Voici mon code :
     // Create a new HTTP client
     sf::Http http("http://localhost/President/index.php/testcontroller/");

     // Prepare a request to get the 'features.php' page
     sf::Http::Request request("test/id/1");
     request.setField("Content-Type", "application/xml");
     
     // Send the request
     sf::Http::Response response = http.sendRequest(request);

     // Check the status code and display the result
     sf::Http::Response::Status status = response.getStatus();

     if (status == sf::Http::Response::Ok)
     {
         std::cout << response.getBody() << std::endl;
     }
     else
     {
         std::cout << "Error " << status << std::endl;
     }
 

Merci d'avence pour votre aide..
« Modifié: Janvier 12, 2013, 02:20:32 am par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #1 le: Janvier 12, 2013, 09:17:32 am »
Non ce n'est pas possible. sf::Http gère du HTTP, pas du JSON ou du XML.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [client HTTP]réponse au format xml ?
« Réponse #2 le: Janvier 12, 2013, 09:42:12 am »
void Http::Response::parse(const std::string& data)
{
    std::istringstream in(data);

    // Extract the HTTP version from the first line
    std::string version;
    if (in >> version)
    {
        if ((version.size() >= 8) && (version[6] == '.') &&
            (toLower(version.substr(0, 5)) == "http/")   &&
             isdigit(version[5]) && isdigit(version[7]))
        {
            m_majorVersion = version[5] - '0';
            m_minorVersion = version[7] - '0';
        }
        else
        {
            // Invalid HTTP version
            m_status = InvalidResponse;
            return;
        }
    }

    // Extract the status code from the first line
    int status;
    if (in >> status)
    {
        m_status = static_cast<Status>(status);
    }
    else
    {
        // Invalid status code
        m_status = InvalidResponse;
        return;
    }

    // Ignore the end of the first line
    in.ignore(10000, '\n');

    // Parse the other lines, which contain fields, one by one
    std::string line;
    while (std::getline(in, line) && (line.size() > 2))
    {
        std::string::size_type pos = line.find(": ");
        if (pos != std::string::npos)
        {
            // Extract the field name and its value
            std::string field = line.substr(0, pos);
            std::string value = line.substr(pos + 2);

            // Remove any trailing \r
            if (!value.empty() && (*value.rbegin() == '\r'))
                value.erase(value.size() - 1);

            // Add the field
            m_fields[toLower(field)] = value;
        }
    }

    // Finally extract the body
    m_body.clear();
    std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(m_body));
}
 



J'ai l'impression qu'il ne faudrait pas grand chose pour que ma version de sfml autorise le xml.. c'est réalisable  non ?

Je penses àjouter une nouvelle méthode parseXml et vérifier le Content-Type dans la méthode SendRequest mais je ne voudrais pas perdre mon temps^^ : si tu devais le faire tu ferais comment ? Je sais que la structure (m_body, etc) n'est pas spécialement adaptée, mais..

Dernière question : si c'était fait proprement tu trouverais cela intéressent que ton client Http accepte d'autre format en retour de requête ?


Edit : ou alors il suffirait  de dissocier le parsing de la méthode sendRequest, ce serait peut-être mieux non (ne s'occuper que des autres informations (status, ...), et transmettre les données brutes au m_body)?
« Modifié: Janvier 12, 2013, 10:11:07 am par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #3 le: Janvier 12, 2013, 10:29:34 am »
Mais concrètement ta réponse, c'est juste du XML ou bien il y a quand même un en-tête HTTP, et le XML n'est que le corps ?
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [client HTTP]réponse au format xml ?
« Réponse #4 le: Janvier 12, 2013, 10:35:35 am »
xml pur : voici le code source de la page dont j'ai posé un exemple en premier post :
<?xml version="1.0" encoding="utf-8"?>
<xml><item>toto</item></xml>
 

Et évidemment si je choisi le format json dans mon url le code source est encore plus démuni :

"toto"
 
« Modifié: Janvier 12, 2013, 10:39:35 am par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #5 le: Janvier 12, 2013, 10:54:13 am »
Ok, donc non c'est vraiment pas possible :)
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Re : [client HTTP]réponse au format xml ?
« Réponse #6 le: Janvier 12, 2013, 11:03:47 am »
Ok, donc non c'est vraiment pas possible :)

sans modifier SFML je veux bien le croire, mais en modifiant sendRequest c'est pas possible non plus ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #7 le: Janvier 12, 2013, 01:00:38 pm »
En le modifiant de quelle manière ?

De toute façon, sf::Http::Response est conçu comme étant une réponse HTTP (avec son en-tête et tout ce qu'il contient). Ca n'aurait pas vraiment de sens de coller du XML ou du JSON dedans.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Re : [client HTTP]réponse au format xml ?
« Réponse #8 le: Janvier 12, 2013, 03:09:24 pm »
En le modifiant de quelle manière ?

De toute façon, sf::Http::Response est conçu comme étant une réponse HTTP (avec son en-tête et tout ce qu'il contient). Ca n'aurait pas vraiment de sens de coller du XML ou du JSON dedans.

Justement en modifiant l'utilisation de sf::HttpResponse : après tout m_body est un std::string, et je ne dis pas que ce serait propre ni que ça aurait du sens, mais que ça pourrait marcher (et à moi éviter de passer par un client HTPP très ennuyeux style cURL++ ou libwww).

Pour la manière, j'ai deux solutions : aucune n'est propre, mais ce sont loin d'être les seules solutions (la mieux serait surement que je me serve de SFML Network pour créer une classe "sf::XmlResponse" ou "sf::Xml" pour ne pas utiliser sf::Http, mais je ne suis pas sur de comment gérer la méthode POST). Soit je passe la méthode parse à une visibilité publique, et je retire son appel de la méthode sendRequest, remplaçant par une autre méthode ou par du code directement pour coller le contenu de "receivedStr" dans le httpResponse, sans parsing, et modifier les autres membre de httpResponse selon la situation... soit en créant une méthode "parseXML" et en faisant un test du style :

if (toSend.getField("Content-Type") == "application/xml")
    parseXml(receivedStr);
else
   parse(receivedStr);
 

Mis à part cela, je penses que les clients http servent le plus souvent à attaquer des webServices, et peu d'entre eux renvoi des informations au format html. Généralement, je penses qu'il s'agit de format adapté au rapatriement de données, issues de base de données par exemple. A ce jeu le xml et encore plus le json (ou encore le csv) sont d'excellents atouts.

De plus, dans d'autres langages, comme en C#, un framework comme .Net permet de deserialiser très facilement le contenu d'un XML pour l'intégrer dans un DTO (grace aux attributes notamment), et les client http permettent de renseigner le "Content-Type", ce qui a un véritable effet. C'est ce que je souhaiterais reproduire avec la SFML (la dernière partie sur le Content-Type").


Edit: pour exposer le contexte : j'ai un jeu de carte en ligne (client/serveur) assez abouti (jouable en LAN/WLAN pour le moment, et en ligne prochainement si j'arrive à mettre en place ce dont on parle), utilisant de fond en comble la SFML, j'ai un serveur WAMP installé et prêt à être utilisé, et pour que le joueur puisse se connecter via un compte, j'ai mis une table profil au point que j'attaque avec le client via une couche de webservices, afin d'autoriser des connexion, et rapatrier des données d'historique de partie, et de trouver des parties en cours, ce qui permettra au client de rejoindre une partie sans demander l'adresse ip à l'utilisateur. le webService que j'ai mis au point s'appuie sur CodeIgniter et utilise un protocole REST vraiment sympa d'utilisation, permettant même de choisir son format de retour de réposne : xml, json, ou csv... quand j'ai vu un client http avec la SFML, je me suis dit banco : "je vais pouvoir faire la même chose qu'en .Net au boulot avec les HttpClient du framework".C'est pour cela que je cherche un moyen de contourner ce petit souci de format de réponse.
« Modifié: Janvier 12, 2013, 03:20:32 pm par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #9 le: Janvier 12, 2013, 04:26:51 pm »
Je comprends ton problème. Mais malheureusement, sf::Http est plus un joujou qu'une classe complète. Ca fait parti des fonctionnalités très peu utilisées (et à la limite de ce que SFML est censée fournir), du coup je ne souhaite pas la rendre plus complexe et me rajouter du boulot. D'autant plus que parser du XML ou du JSON, ça ne se fait pas vraiment en 3 lignes de code. En plus il faudrait que je fournisse une API correspondante, et ça poserait de nouveaux problèmes.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [client HTTP]réponse au format xml ?
« Réponse #10 le: Janvier 19, 2013, 06:35:16 pm »
bonjour Laurent,

désolé de relancer le sujet, mais je n'arrive pas à décortiquer le corps type que sf::http attend d'une réponse http. Pourrais-tu me dire exactement à quoi doit ressembler le corps de ma réponse ?


Voilà la chose la plus pertinente que j'ai tenté :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
        <body>
             test numero un
        </body>
</html>
 

c'est le corps de la page www.sfml-dev.org/features.php qui fonctionne parfaitement, le contenu en moins biens sur. Mais jai toujours une erreur 1000 (invalid response)

Niveau code, je n'ai remplacé que l'host, et fourni le "controller/method/param/value" à la requete :

 // We'll work on http://www.sfml-dev.org
 http.setHost("http://www.sfml-dev.org");

 // Prepare a request to get the 'features.php' page
 sf::Http::Request request("features.php");

//devient...

 // We'll work on http://www.sfml-dev.org
 http.setHost("http://localhost/President/index.php");

 // Prepare a request to get the 'features.php' page
 sf::Http::Request request("testcontroller/test/id/1");
 

Et "http://localhost/President/index.php/testcontroller/test/id/1" contient exactement le contenu copié-collé dans ce message (le corps de features.php)

Une idée de ce qu'il me manque ?



Edit : pour être encore plus précis : voilà le contenu de la méthode appelée :
    function test_get()
    {
                HttpResponse::status(200);
                HttpResponse::setContentType('text/html');             
                HttpResponse::setData('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
                <body>
                        test numero un
                </body>
        </html>'
);
                HttpResponse::send();
    }
 

« Modifié: Janvier 19, 2013, 06:38:40 pm par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #11 le: Janvier 19, 2013, 11:34:46 pm »
Regarde dans le code source la raison qui fait qu'un code 1000 est généré. Là comme ça je ne peux pas te dire.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : [client HTTP]réponse au format xml ?
« Réponse #12 le: Janvier 20, 2013, 09:29:10 am »
Bon j'ai trouvé une solution avant de commencer à chercher dans le code source.

Et je penses que ça te fera même plaisir de le savoir, mais le xml est tout à fait pris en charge par ton client HTTP ! :)

<?xml version="1.0" encoding="utf-8"?>
<xml><item>test numero un</item></xml>
 

Mais comme tout ça ne peut pas être magique, et que je commence à bien connaitre le fonctionnement interne de cette classe http, je savais qu'elle ne pouvait pas fonctionner sans que des infos supplémentaires aient été transmises, et j'ai donc intégré la classe http à mon code pour pouvoir la modifier. J'ai ensuite affiché l'ensemble des données reçues, et j'ai obtenu ceci :

HTTP/1.1 200 OK
Date: Sun, 20 Jan 2013 08:31:45 GMT
Server: Apache/2.2.22 (Win32) PHP/5.3.13
X-Powered-By: PHP/5.3.13
Status: 200
Content-Length: 78
Connection: close
Content-Type: application/xml
<?xml version="1.0" encoding="utf-8"?>
<xml><item>test numero un</item></xml>
 

Donc voilà ! peu importe les infos qui suivent le Content-Type, même du xml est pris en charge (étant donné qu'on ne fait que lire dans un buffer, je me doutais bien que ce n'était pas possible cette histoire d'incompatibilité).


Ah et oui la solution de ce problème :

// AVANT ...

 // We'll work on http://www.sfml-dev.org
 http.setHost("http://localhost/President/index.php");

 // Prepare a request to get the 'features.php' page
 sf::Http::Request request("testcontroller/test/id/1");


// APRES...
 // We'll work on http://www.sfml-dev.org
 http.setHost("http://localhost");

 // Prepare a request to get the 'features.php' page
 sf::Http::Request request("President/index.php/testcontroller/test/id/1");
 


Tout bête comme erreur :)
« Modifié: Janvier 20, 2013, 09:40:39 am par kamui »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [client HTTP]réponse au format xml ?
« Réponse #13 le: Janvier 20, 2013, 10:48:29 am »
Ben, oui, si tu encapsules ton XML dans une réponse au format HTTP, logiquement ça va commencer à fonctionner ;)

Le cors en lui-même n'est pas interprété, donc qu'il contienne du XML ou du toto ne change rien pour SFML, elle le transmets tel quel sans problème.

D'après ce que tu m'avais dit, j'avais compris que la réponse ne contenait que du XML. Mais si c'est encapsulé dans du HTTP standard alors aucun problème, évidemment.

Note que ce qui termine l'en-tête ce n'est pas le champ Content-Type, c'est un double \r\n.
Laurent Gomila - SFML developer

kamui

  • Sr. Member
  • ****
  • Messages: 291
    • Voir le profil
Re : Re : [client HTTP]réponse au format xml ?
« Réponse #14 le: Janvier 20, 2013, 10:58:32 am »
Ben, oui, si tu encapsules ton XML dans une réponse au format HTTP, logiquement ça va commencer à fonctionner ;)

Le cors en lui-même n'est pas interprété, donc qu'il contienne du XML ou du toto ne change rien pour SFML, elle le transmets tel quel sans problème.

D'après ce que tu m'avais dit, j'avais compris que la réponse ne contenait que du XML. Mais si c'est encapsulé dans du HTTP standard alors aucun problème, évidemment.

Note que ce qui termine l'en-tête ce n'est pas le champ Content-Type, c'est un double \r\n.

Exact.

Pour le contenu effectivement je me suis trompé, la visualisation du code source ne m'affichait pas toutes les infos. Mais bon tant mieux si tout rentre dans l'ordre. Maintenant je passer au problème suivant ^^ ( à savoir que le post n'a pas l'air d'envoyer le body que je fourni (ou plutot il l'envoie mais...), car à la réception, $_POST semble être vide :/)

Merci tout de même.