HTTPS-запрос с Boost.Asio и OpenSSL - PullRequest
       42

HTTPS-запрос с Boost.Asio и OpenSSL

14 голосов
/ 13 августа 2011

Я пытаюсь прочитать символ тикера в https://mtgox.com/api/0/data/ticker.php из моего приложения C ++.Я использую Boost.Asio и OpenSSL, потому что для службы требуется HTTPS.

Повышенная версия: 1.47.0

OpenSSL: 1.0.0d [8 февраля 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.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));

(полный код: 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) Ошибка при проверке. При подключении с параметром "unsafe"

curl --trace-ascii out.txt -k https://mtgox.com/api/0/data/ticker.php

(полноевывод: http://pastebin.com/JR43A7ux)

все работает нормально.

Исправлено:

  1. Я исправил опечатку в заголовках HTTP
  2. Я добавил корневой сертификат и снова включил проверку SSL.

1 Ответ

10 голосов
/ 13 августа 2011

Короче говоря:

  1. Вы отправляете «HTTP 1.1» вместо «HTTP / 1.1». Этого достаточно, чтобы сервер отклонил ваш запрос. Есть и другие различия между вашим запросом и cURL, вам, возможно, придется изменить и эти параметры - даже если они кажутся действительными для меня.

  2. Возможно, OpenSSL не имеет корневого сертификата, используемого сервером, в отличие от Chrome, и поэтому проверка не проходит.

Подробности:

  1. Учитывая работающий и нерабочий инструмент, вы всегда должны сравнивать происходящее. Здесь у вас есть вывод cURL и ваш запрос - сравнение их показало ряд различий; обычно даже при зашифрованном соединении вы можете использовать мощный анализатор пакетов, такой как Wireshark, который декодирует как можно больше информации из пакетов. Здесь это позволит увидеть, что сервер на самом деле отправляет меньше пакетов (я ожидаю); другая возможность состояла бы в том, что ваш клиент не получал данные, отправленные сервером (скажем, потому что у клиента была какая-то ошибка).

  2. Если я правильно понимаю, curl показывал только, почему вам нужно было отключить проверку, верно? Сертификат выглядит действительным и для меня на chrome, но корневой центр сертификации совершенно неизвестен; В керле упоминается «CA-сертификат», т. е. сертификат центра сертификации. Корневой сертификат является доверенным, поскольку он уже присутствует в клиентской БД сертификата - я думаю, что в Chrome может быть более полная БД, чем в OpenSSL (который используется как cURL, так и вашей программой).

...