2011-08-12 19 views
14

Tôi đang cố gắng đọc biểu tượng ticker tại https://mtgox.com/api/0/data/ticker.php từ ứng dụng C++ của tôi. Tôi sử dụng Boost.Asio và OpenSSL vì dịch vụ yêu cầu HTTPS. phiên bảnYêu cầu HTTPS với Boost.Asio và OpenSSL

Boost: 1.47.0

OpenSSL: 1.0.0d [ngày 08 tháng 2 năm 2011] Win32

Đối với các ứng dụng; Tôi lấy ví dụ từ http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/ssl/client.cpp để bắt đầu và sửa đổi nó như sau:

Đây là nơi tôi muốn kết nối:

boost::asio::ip::tcp::resolver::query query("mtgox.com", "443"); 

tôi đặt xác minh không ai sánh kịp vì cái bắt tay thất bại khác. Tôi không chắc chắn nếu đây là một vấn đề với mtgox hoặc thực hiện điều này là thực sự nghiêm ngặt bởi vì khi tôi in chứng chỉ vào màn hình có vẻ hợp pháp (và chrome không có vấn đề với nó khi truy cập vào trang ticker).

socket_.set_verify_mode(boost::asio::ssl::context::verify_none); 

Đây là yêu cầu tôi gửi:

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)); 

(đầy đủ mã: http://pastebin.com/zRTTqZVe)

tôi chạy vào báo lỗi sau:

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 

Tôi đi trong đúng hướng với điều này? Thông báo lỗi không thực sự mô tả vấn đề và tôi không biết bước nào tôi đã làm sai.

Cập nhật: tôi đã sử dụng cURL để xem những gì đã xảy ra:

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

(đầy đủ đầu ra: http://pastebin.com/Rzp0RnAK) Nó thất bại trong xác minh. Khi tôi kết nối với "không an toàn" tham số

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

(đầy đủ đầu ra: http://pastebin.com/JR43A7ux)

tất cả mọi thứ hoạt động tốt.

Fix:

  1. Tôi cố định typo trong tiêu đề HTTP
  2. Tôi đã thêm một chứng chỉ gốc và quay xác minh SSL trở lại.
+2

Tại sao bạn tạo khóa? Bạn không ký bất cứ điều gì, máy chủ là. Bạn sẽ cần tin tưởng vào chứng chỉ gốc của máy chủ. –

+1

Bạn đã thử gửi yêu cầu đó, ví dụ như qua curl để xem máy chủ có chấp nhận yêu cầu đó không? –

+0

Ý tưởng hay! Tôi đã cập nhật câu hỏi. – Maarten

Trả lời

10

Nói tóm lại:

  1. Bạn gửi "HTTP 1.1" thay vì "HTTP/1.1". Điều đó chắc chắn đủ để làm cho máy chủ từ chối yêu cầu của bạn. Có những khác biệt khác giữa yêu cầu của bạn và cURL, bạn có thể cần phải thay đổi các tham số đó - ngay cả khi chúng có vẻ hợp lệ với tôi.

  2. Có thể OpenSSL không có chứng chỉ gốc được máy chủ sử dụng, không giống như Chrome và đó là lý do tại sao xác minh không thành công.

chi tiết:

  1. Cho một lao động và công cụ phi lao, bạn nên luôn luôn so sánh những gì đang xảy ra. Ở đây bạn có đầu ra của cURL và yêu cầu của bạn - so sánh chúng cho thấy một số khác biệt; thường, ngay cả với một kết nối được mã hóa, bạn có thể sử dụng một gói sniffer mạnh mẽ như Wireshark, giải mã càng nhiều thông tin từ các gói càng tốt. Ở đây nó sẽ cho phép thấy rằng máy chủ thực sự gửi ít gói hơn (tôi mong đợi); một khả năng khác có thể là khách hàng của bạn không nhận được dữ liệu được gửi bởi máy chủ (nói vì khách hàng có lỗi).

  2. Nếu tôi hiểu chính xác, hãy chỉ cho biết lý do bạn cần tắt xác minh, đúng không? Chứng chỉ có vẻ hợp lệ đối với tôi trên chrome, nhưng cơ quan cấp giấy chứng nhận gốc không rõ ràng; curl đề cập đến "chứng chỉ CA", nghĩa là giấy chứng nhận của cơ quan cấp chứng nhận. Chứng chỉ gốc được tin cậy vì nó đã có trong một chứng chỉ DB trên máy khách - tôi nghĩ rằng Chrome có thể có một DB hoàn chỉnh hơn OpenSSL (được sử dụng bởi cả cURL và chương trình của bạn).

+0

Cảm ơn! Tôi đã sửa lỗi đánh máy và thêm chứng chỉ gốc gần đây dưới dạng ssl "context", mọi thứ hoạt động tốt ngay bây giờ :). – Maarten