|
|
@ -230,100 +230,7 @@ namespace http { |
|
|
|
{ "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, |
|
|
|
{ "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::Receive () |
|
|
|
void ShowStatus (std::stringstream& s) |
|
|
|
{ |
|
|
|
|
|
|
|
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), |
|
|
|
|
|
|
|
std::bind(&HTTPConnection::HandleReceive, shared_from_this (), |
|
|
|
|
|
|
|
std::placeholders::_1, std::placeholders::_2)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (ecode) { |
|
|
|
|
|
|
|
if (ecode != boost::asio::error::operation_aborted) |
|
|
|
|
|
|
|
Terminate (ecode); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m_Buffer[bytes_transferred] = '\0'; |
|
|
|
|
|
|
|
m_BufferLen = bytes_transferred; |
|
|
|
|
|
|
|
RunRequest(); |
|
|
|
|
|
|
|
Receive (); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::RunRequest () |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
HTTPReq request; |
|
|
|
|
|
|
|
int ret = request.parse(m_Buffer); |
|
|
|
|
|
|
|
if (ret < 0) { |
|
|
|
|
|
|
|
m_Buffer[0] = '\0'; |
|
|
|
|
|
|
|
m_BufferLen = 0; |
|
|
|
|
|
|
|
return; /* error */ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ret == 0) |
|
|
|
|
|
|
|
return; /* need more data */ |
|
|
|
|
|
|
|
HandleRequest (request.uri); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::Terminate (const boost::system::error_code& ecode) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (ecode == boost::asio::error::operation_aborted) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
boost::system::error_code ignored_ec; |
|
|
|
|
|
|
|
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); |
|
|
|
|
|
|
|
m_Socket->close (); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandleRequest (const std::string &uri) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::stringstream s; |
|
|
|
|
|
|
|
// Html5 head start
|
|
|
|
|
|
|
|
s << |
|
|
|
|
|
|
|
"<!DOCTYPE html>\r\n" |
|
|
|
|
|
|
|
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */ |
|
|
|
|
|
|
|
" <head>\r\n" |
|
|
|
|
|
|
|
" <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */ |
|
|
|
|
|
|
|
" <link rel='shortcut icon' href='" << itoopieFavicon << "'>\r\n" |
|
|
|
|
|
|
|
" <title>Purple I2P " VERSION " Webconsole</title>\r\n" |
|
|
|
|
|
|
|
<< cssStyles << |
|
|
|
|
|
|
|
"</head>\r\n"; |
|
|
|
|
|
|
|
s << |
|
|
|
|
|
|
|
"<body>\r\n" |
|
|
|
|
|
|
|
"<div class=header><b>i2pd</b> webconsole</div>\r\n" |
|
|
|
|
|
|
|
"<div class=wrapper>\r\n" |
|
|
|
|
|
|
|
"<div class=left>\r\n" |
|
|
|
|
|
|
|
" <a href=/>Main page</a><br>\r\n<br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << ">Local destinations</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_TUNNELS << ">Tunnels</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << ">Transit tunnels</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_TRANSPORTS << ">Transports</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_I2P_TUNNELS << ">I2P tunnels</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_JUMPSERVICES << "&address=example.i2p>Jump services</a><br>\r\n" |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
if (i2p::client::context.GetSAMBridge ()) |
|
|
|
|
|
|
|
s << " <a href=/?page=" << HTTP_PAGE_SAM_SESSIONS << ">SAM sessions</a><br>\r\n"; |
|
|
|
|
|
|
|
/* commands */ |
|
|
|
|
|
|
|
s << " <br>\r\n"; |
|
|
|
|
|
|
|
s << " <a href=/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n"; |
|
|
|
|
|
|
|
if (i2p::context.AcceptsTunnels ()) |
|
|
|
|
|
|
|
s << " <a href=/?cmd=" << HTTP_COMMAND_STOP_ACCEPTING_TUNNELS << ">Stop accepting tunnels</a><br>\r\n"; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
s << " <a href=/?cmd=" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n"; |
|
|
|
|
|
|
|
s << "</div>\r\n"; |
|
|
|
|
|
|
|
s << "<div class=right>"; |
|
|
|
|
|
|
|
if (uri.find("page=") != std::string::npos) |
|
|
|
|
|
|
|
HandlePage (s, uri); |
|
|
|
|
|
|
|
else if (uri.find("cmd=") != std::string::npos) |
|
|
|
|
|
|
|
HandleCommand (s, uri); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
ShowStatus (s); |
|
|
|
|
|
|
|
s << |
|
|
|
|
|
|
|
"</div></div>\r\n" |
|
|
|
|
|
|
|
"</body>\r\n" |
|
|
|
|
|
|
|
"</html>\r\n"; |
|
|
|
|
|
|
|
SendReply (s.str ()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowStatus (std::stringstream& s) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Uptime:</b> " << boost::posix_time::to_simple_string ( |
|
|
|
s << "<b>Uptime:</b> " << boost::posix_time::to_simple_string ( |
|
|
|
boost::posix_time::time_duration (boost::posix_time::seconds ( |
|
|
|
boost::posix_time::time_duration (boost::posix_time::seconds ( |
|
|
@ -392,59 +299,7 @@ namespace http { |
|
|
|
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n"; |
|
|
|
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) |
|
|
|
void ShowJumpServices (std::stringstream& s, const std::string& address) |
|
|
|
{ |
|
|
|
|
|
|
|
std::map<std::string, std::string> params; |
|
|
|
|
|
|
|
std::string page(""); |
|
|
|
|
|
|
|
URL url; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
url.parse(uri); |
|
|
|
|
|
|
|
url.parse_query(params); |
|
|
|
|
|
|
|
page = params["page"]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (page == HTTP_PAGE_TRANSPORTS) |
|
|
|
|
|
|
|
ShowTransports (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_TUNNELS) |
|
|
|
|
|
|
|
ShowTunnels (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_JUMPSERVICES) |
|
|
|
|
|
|
|
ShowJumpServices (s, params["address"]); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_TRANSIT_TUNNELS) |
|
|
|
|
|
|
|
ShowTransitTunnels (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) |
|
|
|
|
|
|
|
ShowLocalDestinations (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_LOCAL_DESTINATION) |
|
|
|
|
|
|
|
ShowLocalDestination (s, params["b32"]); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_SAM_SESSIONS) |
|
|
|
|
|
|
|
ShowSAMSessions (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_SAM_SESSION) |
|
|
|
|
|
|
|
ShowSAMSession (s, params["sam_id"]); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_I2P_TUNNELS) |
|
|
|
|
|
|
|
ShowI2PTunnels (s); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
SendError("Unknown page: " + page); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::map<std::string, std::string> params; |
|
|
|
|
|
|
|
std::string cmd(""); |
|
|
|
|
|
|
|
URL url; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
url.parse(uri); |
|
|
|
|
|
|
|
url.parse_query(params); |
|
|
|
|
|
|
|
cmd = params["cmd"]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) |
|
|
|
|
|
|
|
StartAcceptingTunnels (s); |
|
|
|
|
|
|
|
else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) |
|
|
|
|
|
|
|
StopAcceptingTunnels (s); |
|
|
|
|
|
|
|
else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) |
|
|
|
|
|
|
|
RunPeerTest (s); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
SendError("Unknown command: " + cmd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<form type=\"GET\" action=\"/\">"; |
|
|
|
s << "<form type=\"GET\" action=\"/\">"; |
|
|
|
s << "<input type=\"hidden\" name=\"page\" value=\"jumpservices\">"; |
|
|
|
s << "<input type=\"hidden\" name=\"page\" value=\"jumpservices\">"; |
|
|
@ -458,7 +313,7 @@ namespace http { |
|
|
|
s << "</ul>\r\n"; |
|
|
|
s << "</ul>\r\n"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowLocalDestinations (std::stringstream& s) |
|
|
|
void ShowLocalDestinations (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n"; |
|
|
|
for (auto& it: i2p::client::context.GetDestinations ()) |
|
|
|
for (auto& it: i2p::client::context.GetDestinations ()) |
|
|
@ -469,7 +324,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowLocalDestination (std::stringstream& s, const std::string& b32) |
|
|
|
void ShowLocalDestination (std::stringstream& s, const std::string& b32) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Local Destination:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Local Destination:</b><br>\r\n<br>\r\n"; |
|
|
|
i2p::data::IdentHash ident; |
|
|
|
i2p::data::IdentHash ident; |
|
|
@ -555,7 +410,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowTunnels (std::stringstream& s) |
|
|
|
void ShowTunnels (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n"; |
|
|
|
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n"; |
|
|
@ -584,7 +439,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowTransitTunnels (std::stringstream& s) |
|
|
|
void ShowTransitTunnels (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) |
|
|
|
for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) |
|
|
@ -599,7 +454,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowTransports (std::stringstream& s) |
|
|
|
void ShowTransports (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Transports:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Transports:</b><br>\r\n<br>\r\n"; |
|
|
|
auto ntcpServer = i2p::transport::transports.GetNTCPServer (); |
|
|
|
auto ntcpServer = i2p::transport::transports.GetNTCPServer (); |
|
|
@ -648,7 +503,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowSAMSessions (std::stringstream& s) |
|
|
|
void ShowSAMSessions (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>SAM Sessions:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>SAM Sessions:</b><br>\r\n<br>\r\n"; |
|
|
|
auto sam = i2p::client::context.GetSAMBridge (); |
|
|
|
auto sam = i2p::client::context.GetSAMBridge (); |
|
|
@ -662,7 +517,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowSAMSession (std::stringstream& s, const std::string& id) |
|
|
|
void ShowSAMSession (std::stringstream& s, const std::string& id) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>SAM Session:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>SAM Session:</b><br>\r\n<br>\r\n"; |
|
|
|
auto sam = i2p::client::context.GetSAMBridge (); |
|
|
|
auto sam = i2p::client::context.GetSAMBridge (); |
|
|
@ -698,7 +553,7 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::ShowI2PTunnels (std::stringstream& s) |
|
|
|
void ShowI2PTunnels (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Client Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Client Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
for (auto& it: i2p::client::context.GetClientTunnels ()) |
|
|
|
for (auto& it: i2p::client::context.GetClientTunnels ()) |
|
|
@ -721,27 +576,172 @@ namespace http { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::StopAcceptingTunnels (std::stringstream& s) |
|
|
|
void StopAcceptingTunnels (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Stop Accepting Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Stop Accepting Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
i2p::context.SetAcceptsTunnels (false); |
|
|
|
i2p::context.SetAcceptsTunnels (false); |
|
|
|
s << "Accepting tunnels stopped" << std::endl; |
|
|
|
s << "Accepting tunnels stopped" << std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::StartAcceptingTunnels (std::stringstream& s) |
|
|
|
void StartAcceptingTunnels (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Start Accepting Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Start Accepting Tunnels:</b><br>\r\n<br>\r\n"; |
|
|
|
i2p::context.SetAcceptsTunnels (true); |
|
|
|
i2p::context.SetAcceptsTunnels (true); |
|
|
|
s << "Accepting tunnels started" << std::endl; |
|
|
|
s << "Accepting tunnels started" << std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::RunPeerTest (std::stringstream& s) |
|
|
|
void RunPeerTest (std::stringstream& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
s << "<b>Run Peer Test:</b><br>\r\n<br>\r\n"; |
|
|
|
s << "<b>Run Peer Test:</b><br>\r\n<br>\r\n"; |
|
|
|
i2p::transport::transports.PeerTest (); |
|
|
|
i2p::transport::transports.PeerTest (); |
|
|
|
s << "Peer test is running" << std::endl; |
|
|
|
s << "Peer test is running" << std::endl; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::Receive () |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), |
|
|
|
|
|
|
|
std::bind(&HTTPConnection::HandleReceive, shared_from_this (), |
|
|
|
|
|
|
|
std::placeholders::_1, std::placeholders::_2)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (ecode) { |
|
|
|
|
|
|
|
if (ecode != boost::asio::error::operation_aborted) |
|
|
|
|
|
|
|
Terminate (ecode); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m_Buffer[bytes_transferred] = '\0'; |
|
|
|
|
|
|
|
m_BufferLen = bytes_transferred; |
|
|
|
|
|
|
|
RunRequest(); |
|
|
|
|
|
|
|
Receive (); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::RunRequest () |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
HTTPReq request; |
|
|
|
|
|
|
|
int ret = request.parse(m_Buffer); |
|
|
|
|
|
|
|
if (ret < 0) { |
|
|
|
|
|
|
|
m_Buffer[0] = '\0'; |
|
|
|
|
|
|
|
m_BufferLen = 0; |
|
|
|
|
|
|
|
return; /* error */ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ret == 0) |
|
|
|
|
|
|
|
return; /* need more data */ |
|
|
|
|
|
|
|
HandleRequest (request.uri); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::Terminate (const boost::system::error_code& ecode) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (ecode == boost::asio::error::operation_aborted) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
boost::system::error_code ignored_ec; |
|
|
|
|
|
|
|
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); |
|
|
|
|
|
|
|
m_Socket->close (); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandleRequest (const std::string &uri) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::stringstream s; |
|
|
|
|
|
|
|
// Html5 head start
|
|
|
|
|
|
|
|
s << |
|
|
|
|
|
|
|
"<!DOCTYPE html>\r\n" |
|
|
|
|
|
|
|
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */ |
|
|
|
|
|
|
|
" <head>\r\n" |
|
|
|
|
|
|
|
" <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */ |
|
|
|
|
|
|
|
" <link rel='shortcut icon' href='" << itoopieFavicon << "'>\r\n" |
|
|
|
|
|
|
|
" <title>Purple I2P " VERSION " Webconsole</title>\r\n" |
|
|
|
|
|
|
|
<< cssStyles << |
|
|
|
|
|
|
|
"</head>\r\n"; |
|
|
|
|
|
|
|
s << |
|
|
|
|
|
|
|
"<body>\r\n" |
|
|
|
|
|
|
|
"<div class=header><b>i2pd</b> webconsole</div>\r\n" |
|
|
|
|
|
|
|
"<div class=wrapper>\r\n" |
|
|
|
|
|
|
|
"<div class=left>\r\n" |
|
|
|
|
|
|
|
" <a href=/>Main page</a><br>\r\n<br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << ">Local destinations</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_TUNNELS << ">Tunnels</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << ">Transit tunnels</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_TRANSPORTS << ">Transports</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_I2P_TUNNELS << ">I2P tunnels</a><br>\r\n" |
|
|
|
|
|
|
|
" <a href=/?page=" << HTTP_PAGE_JUMPSERVICES << "&address=example.i2p>Jump services</a><br>\r\n" |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
if (i2p::client::context.GetSAMBridge ()) |
|
|
|
|
|
|
|
s << " <a href=/?page=" << HTTP_PAGE_SAM_SESSIONS << ">SAM sessions</a><br>\r\n"; |
|
|
|
|
|
|
|
/* commands */ |
|
|
|
|
|
|
|
s << " <br>\r\n"; |
|
|
|
|
|
|
|
s << " <a href=/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n"; |
|
|
|
|
|
|
|
if (i2p::context.AcceptsTunnels ()) |
|
|
|
|
|
|
|
s << " <a href=/?cmd=" << HTTP_COMMAND_STOP_ACCEPTING_TUNNELS << ">Stop accepting tunnels</a><br>\r\n"; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
s << " <a href=/?cmd=" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n"; |
|
|
|
|
|
|
|
s << "</div>\r\n"; |
|
|
|
|
|
|
|
s << "<div class=right>"; |
|
|
|
|
|
|
|
if (uri.find("page=") != std::string::npos) |
|
|
|
|
|
|
|
HandlePage (s, uri); |
|
|
|
|
|
|
|
else if (uri.find("cmd=") != std::string::npos) |
|
|
|
|
|
|
|
HandleCommand (s, uri); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
ShowStatus (s); |
|
|
|
|
|
|
|
s << |
|
|
|
|
|
|
|
"</div></div>\r\n" |
|
|
|
|
|
|
|
"</body>\r\n" |
|
|
|
|
|
|
|
"</html>\r\n"; |
|
|
|
|
|
|
|
SendReply (s.str ()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::map<std::string, std::string> params; |
|
|
|
|
|
|
|
std::string page(""); |
|
|
|
|
|
|
|
URL url; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
url.parse(uri); |
|
|
|
|
|
|
|
url.parse_query(params); |
|
|
|
|
|
|
|
page = params["page"]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (page == HTTP_PAGE_TRANSPORTS) |
|
|
|
|
|
|
|
ShowTransports (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_TUNNELS) |
|
|
|
|
|
|
|
ShowTunnels (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_JUMPSERVICES) |
|
|
|
|
|
|
|
ShowJumpServices (s, params["address"]); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_TRANSIT_TUNNELS) |
|
|
|
|
|
|
|
ShowTransitTunnels (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) |
|
|
|
|
|
|
|
ShowLocalDestinations (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_LOCAL_DESTINATION) |
|
|
|
|
|
|
|
ShowLocalDestination (s, params["b32"]); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_SAM_SESSIONS) |
|
|
|
|
|
|
|
ShowSAMSessions (s); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_SAM_SESSION) |
|
|
|
|
|
|
|
ShowSAMSession (s, params["sam_id"]); |
|
|
|
|
|
|
|
else if (page == HTTP_PAGE_I2P_TUNNELS) |
|
|
|
|
|
|
|
ShowI2PTunnels (s); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
SendError("Unknown page: " + page); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::map<std::string, std::string> params; |
|
|
|
|
|
|
|
std::string cmd(""); |
|
|
|
|
|
|
|
URL url; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
url.parse(uri); |
|
|
|
|
|
|
|
url.parse_query(params); |
|
|
|
|
|
|
|
cmd = params["cmd"]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) |
|
|
|
|
|
|
|
StartAcceptingTunnels (s); |
|
|
|
|
|
|
|
else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) |
|
|
|
|
|
|
|
StopAcceptingTunnels (s); |
|
|
|
|
|
|
|
else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) |
|
|
|
|
|
|
|
RunPeerTest (s); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
SendError("Unknown command: " + cmd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void HTTPConnection::SendReply (const std::string& content, int code) |
|
|
|
void HTTPConnection::SendReply (const std::string& content, int code) |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::time_t time_now = std::time(nullptr); |
|
|
|
std::time_t time_now = std::time(nullptr); |
|
|
|