问题
I can't get info from MtGox API via WebSockets C++ library named websocketpp:
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
typedef websocketpp::client<websocketpp::config::asio_client> client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_open(websocketpp::connection_hdl hdl)
{
std::cout << "on_open \n";
}
void on_close(websocketpp::connection_hdl hdl)
{
std::cout << "on_close \n";
}
void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg)
{
std::cout << msg->get_payload() << '\n';
}
int main()
{
client c;
try
{
c.init_asio();
c.set_open_handler(on_open);
c.set_close_handler(on_close);
c.set_message_handler(bind(&on_message, &c, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection("ws://websocket.mtgox.com:80/mtgox?Currency=EUR", ec);
c.connect(con);
c.run();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
catch (websocketpp::lib::error_code e)
{
std::cout << e.message() << std::endl;
}
catch (...)
{
std::cout << "other exception" << std::endl;
}
}
Output
[2013-11-18 23:10:10] [connect] Successful connection
[2013-11-18 23:10:14] [error] Server handshake response was invalid: Invalid HTTP status.
[2013-11-18 23:10:14] [disconnect] Failed: Invalid HTTP status.
In the debugger i see "403 forbidden" error, but I can use it via services like http://www.websocket.org/echo.html.
I already tried to use "ws://socketio.mtgox.com:80/mtgox?Currency=EUR", but received the following error:
[2013-11-18 23:18:07] [connect] Successful connection
[2013-11-18 23:18:08] [error] error in handle_read_http_response: End of File
[2013-11-18 23:18:08] [disconnect] Failed: End of File
What's wrong with this code?
回答1:
MtGox appears to be doing origin filtering. Browser based WebSocket connections will have an origin header sent automatically with the value of the domain that the script is being run from. As this is primarily a security measure for browsers running potentially unknown Javascript code, WebSocket++ does not send an origin header by default.
MtGox appears to work fine with any origin that I have tried as long as one is set at all. Presumably they use this to blacklist origins that they deem malicious. You can send an origin header using WebSocket++ with the following code (Fill in whatever origin seems appropriate for your application):
con->replace_header("Origin","http://www.example.com");
Run this after you request your new connection with endpoint::get_connection
, but before calling endpoint::connect
.
See http://en.wikipedia.org/wiki/Same-origin_policy for more details about the 'same-origin policy' security method that is being used here.
来源:https://stackoverflow.com/questions/20055987/mtgox-api-and-websocketpp