Demande HTTPS avec Boost.Asio et OpenSSL
Je suis en train de lire le symbole à https://mtgox.com/api/0/data/ticker.php à partir de mon application C++.
J'ai utiliser Boost.Asio et OpenSSL parce que le service nécessite HTTPS.
Boost version: 1.47.0
OpenSSL: 1.0.0 d [8 Fév 2011] Win32
De la demande; j'ai pris l'exemple de http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/ssl/client.cpp
pour commencer et modifié comme suit:
C'est là que je veux me connecter à:
boost::asio::ip::tcp::resolver::query query("mtgox.com", "443");
J'ai mis de vérification pour aucune raison que la négociation échoue sinon. Je ne suis pas sûr si c'est un problème avec mtgox ou que cette mise en œuvre est très stricte parce que quand j'ai imprimer le certificat à l'écran, il semble légitime (et chrome a pas de problème avec lui lors de la visite, le texte défilant de la page).
socket_.set_verify_mode(boost::asio::ssl::context::verify_none);
C'est la demande que j'ai envoyer:
std::stringstream request_;
request_ << "GET /api/0/data/ticker.php HTTP/1.1\r\n";
request_ << "Host: mtgox.com\r\n";
request_ << "Accept-Encoding: *\r\n";
request_ << "\r\n";
boost::asio::async_write(socket_, boost::asio::buffer(request_.str()), boost::bind(&client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
(code complet: http://pastebin.com/zRTTqZVe)
Je tombe sur l'erreur suivante:
Connection OK!
Verifying:
/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
Sending request:
GET /api/0/data/ticker.php HTTP 1.1
Host: mtgox.com
Accept-Encoding: *
Sending request OK!
Read failed: An existing connection was forcibly closed by the remote host
Vais-je dans la bonne direction? Le message d'erreur n'est pas vraiment de la description du problème et je ne sais pas quelle étape j'ai fait de mal.
Mise à jour:
J'ai utilisé cURL pour voir ce qui n'allait pas:
curl --trace-ascii out.txt https://mtgox.com/api/0/data/ticker.php
(pleine de sortie: http://pastebin.com/Rzp0RnAK)
Elle échoue en cours de vérification.
Lorsque je me connecte avec le "dangereux" paramètre
curl --trace-ascii out.txt -k https://mtgox.com/api/0/data/ticker.php
(pleine de sortie: http://pastebin.com/JR43A7ux)
tout fonctionne bien.
Correctif:
- J'ai corrigé la faute de frappe dans les en-têtes HTTP
- J'ai ajouté un certificat racine et
tourné la vérification SSL sur le retour.
Avez-vous essayé d'envoyer cette demande par exemple via curl pour voir si le serveur l'accepte?
Bonne idée! J'ai mis à jour la question.
OriginalL'auteur Maarten | 2011-08-12
Vous devez vous connecter pour publier un commentaire.
En bref:
Vous envoyer "HTTP 1.1" au lieu de "HTTP/1.1". C'est sûrement assez pour rendre le serveur de refuser votre demande. Il existe d'autres différences entre votre demande et la boucle, vous pourriez avoir besoin de modifier ces paramètres ainsi, même si elles peuvent sembler valable pour moi.
Peut-être OpenSSL n'a pas la racine du certificat utilisé par le serveur, contrairement à Chrome, et c'est pourquoi la vérification échoue.
Détails:
Donné un travail et non-travail de l'outil, il faut toujours comparer ce qui se passe. Ici, vous avez cURL production et de demande, de comparer entre eux ont montré un certain nombre de différences; en général, même avec une connexion chiffrée, vous pouvez utiliser un puissant renifleur de paquets comme Wireshark, qui décode autant d'informations à partir de paquets que possible. Ici, il permettrait de voir que le serveur est en fait l'envoi de moins de paquets (j'attends); une autre possibilité aurait été que votre client n'a pas obtenir les données envoyées par le serveur (mot à dire, car le client avait quelques bug).
Si je comprends bien, curl n'a montré qu'pourquoi vous avez besoin de désactiver la vérification, à droite? Le certificat est valide pour moi sur chrome, mais l'autorité de certification racine est tout à fait inconnue; curl, mentionne le "CA cert", c'est à dire le certificat de l'autorité de certification. Le certificat racine de confiance, car il est déjà présent dans un certificat DB sur le client, je pense que google Chrome peut avoir une plus complète de la DB que OpenSSL (qui est utilisé par les deux roulage et de votre programme).
OriginalL'auteur Blaisorblade