Browse Source

rollback to 2.6.0

pull/770/head
orignal 8 years ago
parent
commit
417eb56a9b
  1. 199
      I2PControl.cpp
  2. 4
      I2PControl.h

199
I2PControl.cpp

@ -2,6 +2,8 @@
#include <sstream> #include <sstream>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/local_time/local_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/property_tree/ini_parser.hpp> #include <boost/property_tree/ini_parser.hpp>
@ -14,7 +16,6 @@
#include "Crypto.h" #include "Crypto.h"
#include "FS.h" #include "FS.h"
#include "Log.h" #include "Log.h"
#include "HTTP.h"
#include "Config.h" #include "Config.h"
#include "NetDb.h" #include "NetDb.h"
#include "RouterContext.h" #include "RouterContext.h"
@ -189,66 +190,71 @@ namespace client
if (ecode) { if (ecode) {
LogPrint (eLogError, "I2PControl: read error: ", ecode.message ()); LogPrint (eLogError, "I2PControl: read error: ", ecode.message ());
return; return;
}
/* try to parse received data */
std::stringstream json;
std::string response;
bool isHTTP = false;
if (memcmp (buf->data (), "POST", 4) == 0) {
long int remains = 0;
isHTTP = true;
i2p::http::HTTPReq req;
std::size_t len = req.parse(buf->data(), bytes_transferred);
if (len <= 0) {
LogPrint(eLogError, "I2PControl: incomplete/malformed POST request");
return;
}
/* append to json chunk of data from 1st request */
json.write(buf->data() + len, bytes_transferred - len);
remains = req.content_length();
/* if request has Content-Length header, fetch rest of data and store to json buffer */
while (remains > 0) {
len = ((long int) buf->size() < remains) ? buf->size() : remains;
bytes_transferred = boost::asio::read (*socket, boost::asio::buffer (buf->data (), len));
json.write(buf->data(), bytes_transferred);
remains -= bytes_transferred;
}
} else { } else {
json.write(buf->data(), bytes_transferred); try
} {
//LogPrint(eLogDebug, "I2PControl: json from request: ", json.str()); bool isHtml = !memcmp (buf->data (), "POST", 4);
std::stringstream ss;
ss.write (buf->data (), bytes_transferred);
if (isHtml)
{
std::string header;
size_t contentLength = 0;
while (!ss.eof () && header != "\r")
{
std::getline(ss, header);
auto colon = header.find (':');
if (colon != std::string::npos && header.substr (0, colon) == "Content-Length")
contentLength = std::stoi (header.substr (colon + 1));
}
if (ss.eof ())
{
LogPrint (eLogError, "I2PControl: malformed request, HTTP header expected");
return; // TODO:
}
std::streamoff rem = contentLength + ss.tellg () - bytes_transferred; // more bytes to read
if (rem > 0)
{
bytes_transferred = boost::asio::read (*socket, boost::asio::buffer (buf->data (), rem));
ss.write (buf->data (), bytes_transferred);
}
}
std::ostringstream response;
#if GCC47_BOOST149 #if GCC47_BOOST149
LogPrint (eLogError, "I2PControl: json_read is not supported due bug in boost 1.49 with gcc 4.7"); LogPrint (eLogError, "I2PControl: json_read is not supported due bug in boost 1.49 with gcc 4.7");
BuildErrorResponse(response, 32603, "JSON requests is not supported with this version of boost"); response << "{\"id\":null,\"error\":";
response << "{\"code\":-32603,\"message\":\"JSON requests is not supported with this version of boost\"},";
response << "\"jsonrpc\":\"2.0\"}";
#else #else
/* now try to parse json itself */ boost::property_tree::ptree pt;
std::string j_str = json.str(); boost::property_tree::read_json (ss, pt);
std::stringstream _json(j_str);
try { std::string id = pt.get<std::string>("id");
boost::property_tree::ptree pt; std::string method = pt.get<std::string>("method");
boost::property_tree::read_json (_json, pt); auto it = m_MethodHandlers.find (method);
if (it != m_MethodHandlers.end ())
std::string id = pt.get<std::string>("id"); {
std::string method = pt.get<std::string>("method"); response << "{\"id\":" << id << ",\"result\":{";
auto it = m_MethodHandlers.find (method); (this->*(it->second))(pt.get_child ("params"), response);
if (it != m_MethodHandlers.end ()) { response << "},\"jsonrpc\":\"2.0\"}";
std::ostringstream ss; } else {
ss << "{\"id\":" << id << ",\"result\":{"; LogPrint (eLogWarning, "I2PControl: unknown method ", method);
(this->*(it->second))(pt.get_child ("params"), ss); response << "{\"id\":null,\"error\":";
ss << "},\"jsonrpc\":\"2.0\"}"; response << "{\"code\":-32601,\"message\":\"Method not found\"},";
response = ss.str(); response << "\"jsonrpc\":\"2.0\"}";
} else { }
LogPrint (eLogWarning, "I2PControl: unknown method ", method); #endif
BuildErrorResponse(response, 32601, "Method not found"); SendResponse (socket, buf, response, isHtml);
}
catch (std::exception& ex)
{
LogPrint (eLogError, "I2PControl: exception when handle request: ", ex.what ());
}
catch (...)
{
LogPrint (eLogError, "I2PControl: handle request unknown exception");
} }
} catch (std::exception& ex) {
LogPrint (eLogError, "I2PControl: exception when handle request: ", ex.what ());
BuildErrorResponse(response, 32603, ex.what());
} catch (...) {
LogPrint (eLogError, "I2PControl: handle request unknown exception");
} }
#endif
SendResponse (socket, buf, response, isHTTP);
} }
void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, int value) const void I2PControlService::InsertParam (std::ostringstream& ss, const std::string& name, int value) const
@ -270,28 +276,27 @@ namespace client
ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value; ss << "\"" << name << "\":" << std::fixed << std::setprecision(2) << value;
} }
void I2PControlService::BuildErrorResponse (std::string & content, int code, const char *message) {
std::stringstream ss;
ss << "{\"id\":null,\"error\":";
ss << "{\"code\":" << -code << ",\"message\":\"" << message << "\"},";
ss << "\"jsonrpc\":\"2.0\"}";
content = ss.str();
}
void I2PControlService::SendResponse (std::shared_ptr<ssl_socket> socket, void I2PControlService::SendResponse (std::shared_ptr<ssl_socket> socket,
std::shared_ptr<I2PControlBuffer> buf, std::string& content, bool isHTTP) std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml)
{ {
if (isHTTP) { size_t len = response.str ().length (), offset = 0;
i2p::http::HTTPRes res; if (isHtml)
res.code = 200; {
res.add_header("Content-Type", "application/json"); std::ostringstream header;
res.add_header("Connection", "close"); header << "HTTP/1.1 200 OK\r\n";
res.body = content; header << "Connection: close\r\n";
std::string tmp = res.to_string(); header << "Content-Length: " << boost::lexical_cast<std::string>(len) << "\r\n";
content = tmp; header << "Content-Type: application/json\r\n";
header << "Date: ";
auto facet = new boost::local_time::local_time_facet ("%a, %d %b %Y %H:%M:%S GMT");
header.imbue(std::locale (header.getloc(), facet));
header << boost::posix_time::second_clock::local_time() << "\r\n";
header << "\r\n";
offset = header.str ().size ();
memcpy (buf->data (), header.str ().c_str (), offset);
} }
std::copy(content.begin(), content.end(), buf->begin()); memcpy (buf->data () + offset, response.str ().c_str (), len);
boost::asio::async_write (*socket, boost::asio::buffer (buf->data (), content.length()), boost::asio::async_write (*socket, boost::asio::buffer (buf->data (), offset + len),
boost::asio::transfer_all (), boost::asio::transfer_all (),
std::bind(&I2PControlService::HandleResponseSent, this, std::bind(&I2PControlService::HandleResponseSent, this,
std::placeholders::_1, std::placeholders::_2, socket, buf)); std::placeholders::_1, std::placeholders::_2, socket, buf));
@ -318,7 +323,7 @@ namespace client
} }
InsertParam (results, "API", api); InsertParam (results, "API", api);
results << ","; results << ",";
std::string token = std::to_string(i2p::util::GetSecondsSinceEpoch ()); std::string token = boost::lexical_cast<std::string>(i2p::util::GetSecondsSinceEpoch ());
m_Tokens.insert (token); m_Tokens.insert (token);
InsertParam (results, "Token", token); InsertParam (results, "Token", token);
} }
@ -344,10 +349,9 @@ namespace client
(this->*(it1->second))(it.second.data ()); (this->*(it1->second))(it.second.data ());
InsertParam (results, it.first, ""); InsertParam (results, it.first, "");
} }
else { else
LogPrint (eLogError, "I2PControl: I2PControl unknown request: ", it.first); LogPrint (eLogError, "I2PControl: I2PControl unknown request: ", it.first);
} }
}
} }
void I2PControlService::PasswordHandler (const std::string& value) void I2PControlService::PasswordHandler (const std::string& value)
@ -361,20 +365,17 @@ namespace client
void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results) void I2PControlService::RouterInfoHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{ {
for (auto it = params.begin (); it != params.end (); ++it) for (auto it = params.begin (); it != params.end (); it++)
{ {
LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first); LogPrint (eLogDebug, "I2PControl: RouterInfo request: ", it->first);
if (it != params.begin ()) results << ",";
auto it1 = m_RouterInfoHandlers.find (it->first); auto it1 = m_RouterInfoHandlers.find (it->first);
if (it1 != m_RouterInfoHandlers.end ()) if (it1 != m_RouterInfoHandlers.end ())
{ {
if (it != params.begin ()) results << ",";
(this->*(it1->second))(results); (this->*(it1->second))(results);
} }
else else
{
InsertParam(results, it->first, "");
LogPrint (eLogError, "I2PControl: RouterInfo unknown request ", it->first); LogPrint (eLogError, "I2PControl: RouterInfo unknown request ", it->first);
}
} }
} }
@ -440,20 +441,15 @@ namespace client
void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results) void I2PControlService::RouterManagerHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{ {
for (auto it = params.begin (); it != params.end (); ++it) for (auto it = params.begin (); it != params.end (); it++)
{ {
if (it != params.begin ()) results << ","; if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first); LogPrint (eLogDebug, "I2PControl: RouterManager request: ", it->first);
auto it1 = m_RouterManagerHandlers.find (it->first); auto it1 = m_RouterManagerHandlers.find (it->first);
if (it1 != m_RouterManagerHandlers.end ()) if (it1 != m_RouterManagerHandlers.end ()) {
{ (this->*(it1->second))(results);
(this->*(it1->second))(results); } else
}
else
{
InsertParam(results, it->first, "");
LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first); LogPrint (eLogError, "I2PControl: RouterManager unknown request: ", it->first);
}
} }
} }
@ -494,20 +490,15 @@ namespace client
// network setting // network setting
void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results) void I2PControlService::NetworkSettingHandler (const boost::property_tree::ptree& params, std::ostringstream& results)
{ {
for (auto it = params.begin (); it != params.end (); ++it) for (auto it = params.begin (); it != params.end (); it++)
{ {
if (it != params.begin ()) results << ","; if (it != params.begin ()) results << ",";
LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first); LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first);
auto it1 = m_NetworkSettingHandlers.find (it->first); auto it1 = m_NetworkSettingHandlers.find (it->first);
if (it1 != m_NetworkSettingHandlers.end ()) if (it1 != m_NetworkSettingHandlers.end ()) {
{ (this->*(it1->second))(it->second.data (), results);
(this->*(it1->second))(it->second.data (), results); } else
}
else
{
InsertParam(results, it->first, "");
LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first); LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first);
}
} }
} }

4
I2PControl.h

@ -45,9 +45,8 @@ namespace client
void ReadRequest (std::shared_ptr<ssl_socket> socket); void ReadRequest (std::shared_ptr<ssl_socket> socket);
void HandleRequestReceived (const boost::system::error_code& ecode, size_t bytes_transferred, void HandleRequestReceived (const boost::system::error_code& ecode, size_t bytes_transferred,
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf); std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf);
void BuildErrorResponse (std::string & content, int code, const char *message);
void SendResponse (std::shared_ptr<ssl_socket> socket, void SendResponse (std::shared_ptr<ssl_socket> socket,
std::shared_ptr<I2PControlBuffer> buf, std::string& response, bool isHtml); std::shared_ptr<I2PControlBuffer> buf, std::ostringstream& response, bool isHtml);
void HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, void HandleResponseSent (const boost::system::error_code& ecode, std::size_t bytes_transferred,
std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf); std::shared_ptr<ssl_socket> socket, std::shared_ptr<I2PControlBuffer> buf);
@ -120,4 +119,3 @@ namespace client
} }
#endif #endif

Loading…
Cancel
Save