Запрос HTTPS с Boost.Asio и OpenSSL
Я пытаюсь прочитать символ тикера в https://mtgox.com/api/0/data/ticker.php из моего приложения C++. Я использую Boost.Asio и OpenSSL, потому что служба требует HTTPS.
версия Boost: 1.47.0
OpenSSL: 1.0.0 d [8 Feb 2011] Win32
для приложения; я взял пример из http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/ssl/client.cpp чтобы начать и изменить его как следует:
здесь я хочу подключиться к:
boost::asio::ip::tcp::resolver::query query("mtgox.com", "443");
Я проверку не потому, что рукопожатия не иначе. Я не уверен, что это проблема с mtgox или что эта реализация действительно строгая, потому что когда я печатаю сертификат на экран, он выглядит законным (и у chrome нет проблем с ним при посещении страницы тикера).
socket_.set_verify_mode(boost::asio::ssl::context::verify_none);
это запрос, который я посылаю:
std::stringstream request_;
request_ << "GET /api/0/data/ticker.php HTTP/1.1rn";
request_ << "Host: mtgox.comrn";
request_ << "Accept-Encoding: *rn";
request_ << "rn";
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));
(полный код: http://pastebin.com/zRTTqZVe)
я сталкиваюсь со следующей ошибкой:
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
Я иду в правильном направлении с этим? Сообщение об ошибке на самом деле не описывает проблему, и я не знаю, какой шаг я сделал неправильно.
обновление: Я использовал cURL, чтобы увидеть, что пошло не так:
curl --trace-ascii out.txt https://mtgox.com/api/0/data/ticker.php
(полный выход:http://pastebin.com/Rzp0RnAK) Он терпит неудачу во время проверки. Когда я соединяюсь с " небезопасным" параметр
curl --trace-ascii out.txt -k https://mtgox.com/api/0/data/ticker.php
(полный выход:http://pastebin.com/JR43A7ux)
все работает нормально.
исправления:
- я исправил опечатку в заголовках HTTP
- я добавил корневой сертификат и повернул проверки SSL обратно.
1 ответов
короче:
вы отправляете "HTTP 1.1" вместо "HTTP / 1.1". Этого достаточно, чтобы сервер отклонил ваш запрос. Есть и другие различия между вашей просьбой и просьбой керла, вам также может потребоваться изменить эти параметры, даже если они кажутся мне действительными.
возможно, OpenSSL не имеет корневого сертификата, используемого сервером, в отличие от Chrome, и поэтому проверка недостаток.
детали:
учитывая рабочий и нерабочий инструмент, вы всегда должны сравнивать, что происходит. Здесь у вас есть выход cURL и ваш запрос-сравнение их показало ряд различий; обычно, даже с зашифрованным соединением, вы можете использовать мощный анализатор пакетов, такой как Wireshark, который декодирует как можно больше информации из пакетов. Здесь это позволит увидеть, что сервер на самом деле отправляет меньше пакеты (я ожидаю); другой возможностью было бы то, что ваш клиент не получал данные, отправленные сервером (скажем, потому, что у клиента была какая-то ошибка).
Если я правильно понял, curl показал только, почему вам нужно отключить проверку, верно? Сертификат также выглядит действительным для меня в chrome, но корневой центр сертификации совершенно неизвестен; curl упоминает "сертификат CA", т. е. сертификат центра сертификации. Корневой сертификат доверенный, потому что он уже присутствует в БД сертификата на клиенте - я думаю, что Chrome может иметь более полную БД, чем OpenSSL (который используется как cURL, так и вашей программой).