Browse Source

* HTTPServer.{cpp,h}: * extract css-styles to separate block * split /?page= from /?cmd= requests * cleaner html-template

pull/489/head
hagen 9 years ago
parent
commit
19b0c266f9
  1. 182
      HTTPServer.cpp
  2. 5
      HTTPServer.h

182
HTTPServer.cpp

@ -194,20 +194,37 @@ namespace http {
"MYez0Gm9P2iWna0GOcDp8KY2JhAsnbSQS6Ahh9OgrlklINeM40bWhAkBd4SLIEh8cBURLhOeiBIArVA" "MYez0Gm9P2iWna0GOcDp8KY2JhAsnbSQS6Ahh9OgrlklINeM40bWhAkBd4SLIEh8cBURLhOeiBIArVA"
"U4yTRvJItk5PRehQVFaYfpbt9PBtTmdziaXyyUzjaHT/QZBQuKHAA0UxAAAAABJRU5ErkJggg=="; "U4yTRvJItk5PRehQVFaYfpbt9PBtTmdziaXyyUzjaHT/QZBQuKHAA0UxAAAAABJRU5ErkJggg==";
const char HTTP_COMMAND_TUNNELS[] = "tunnels"; const char *cssStyles =
const char HTTP_COMMAND_TRANSIT_TUNNELS[] = "transit_tunnels"; "<style>\r\n"
const char HTTP_COMMAND_TRANSPORTS[] = "transports"; " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n"
" a { text-decoration: none; color: #894C84; }\r\n"
" a:hover { color: #FAFAFA; background: #894C84; }\r\n"
" .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n"
" .wrapper { margin: 0 auto; padding: 1em; max-width: 60em; }\r\n"
" .left { float: left; position: absolute; }\r\n"
" .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\r\n"
" .tunnel.established { color: #56B734; }\r\n"
" .tunnel.expiring { color: #D3AE3F; }\r\n"
" .tunnel.failed { color: #D33F3F; }\r\n"
" .tunnel.another { color: #434343; }\r\n"
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
" table { width: 100%; border-collapse: collapse; text-align: center; }\r\n"
"</style>\r\n";
const char HTTP_PAGE_TUNNELS[] = "tunnels";
const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels";
const char HTTP_PAGE_TRANSPORTS[] = "transports";
const char HTTP_PAGE_LOCAL_DESTINATIONS[] = "local_destinations";
const char HTTP_PAGE_LOCAL_DESTINATION[] = "local_destination";
const char HTTP_PAGE_SAM_SESSIONS[] = "sam_sessions";
const char HTTP_PAGE_SAM_SESSION[] = "sam_session";
const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels";
const char HTTP_PAGE_JUMPSERVICES[] = "jumpservices";
const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels";
const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels";
const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test";
const char HTTP_COMMAND_LOCAL_DESTINATIONS[] = "local_destinations";
const char HTTP_COMMAND_LOCAL_DESTINATION[] = "local_destination";
const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; const char HTTP_PARAM_BASE32_ADDRESS[] = "b32";
const char HTTP_COMMAND_SAM_SESSIONS[] = "sam_sessions";
const char HTTP_COMMAND_SAM_SESSION[] = "sam_session";
const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels";
const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices=";
const char HTTP_PARAM_ADDRESS[] = "address"; const char HTTP_PARAM_ADDRESS[] = "address";
void HTTPConnection::Terminate () void HTTPConnection::Terminate ()
@ -282,52 +299,53 @@ namespace http {
{ {
std::stringstream s; std::stringstream s;
// Html5 head start // Html5 head start
s << "<!DOCTYPE html>\r\n<html lang=\"en\">"; // TODO: Add support for locale. s <<
s << "<head>\r\n<meta charset=\"utf-8\">\r\n"; // TODO: Find something to parse html/template system. This is horrible. "<!DOCTYPE html>\r\n"
s << "<link rel='shortcut icon' href='" << itoopieFavicon << "'>\r\n"; "<html lang=\"en\">\r\n" /* TODO: Add support for locale */
s << "<title>Purple I2P " << VERSION " Webconsole</title>\r\n"; " <head>\r\n"
s << "<style>\r\n"; " <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
s << "body {font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456;}"; " <link rel='shortcut icon' href='" << itoopieFavicon << "'>\r\n"
s << "a {text-decoration: none; color: #894C84;}"; " <title>Purple I2P " VERSION " Webconsole</title>\r\n"
s << "a:hover {color: #FAFAFA; background: #894C84;}"; << cssStyles <<
s << ".header {font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84;}"; "</head>\r\n";
s << ".wrapper {margin: 0 auto; padding: 1em; max-width: 60em;}"; s <<
s << ".left {float: left; position: absolute;}"; "<body>\r\n"
s << ".right {font-size: 1em; margin-left: 13em; float: left; max-width: 46em; overflow: auto;}"; "<div class=header><b>i2pd</b> webconsole</div>\r\n"
s << ".established_tunnel {color: #56b734;}"; "<div class=wrapper>\r\n"
s << ".expiring_tunnel {color: #d3ae3f;}"; "<div class=left>\r\n"
s << ".failed_tunnel {color: #d33f3f;}"; " <a href=/>Main page</a><br>\r\n<br>\r\n"
s << ".another_tunnel {color: #434343;}"; " <a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << ">Local destinations</a><br>\r\n"
s << "caption {font-size: 1.5em; text-align: center; color: #894C84;}"; " <a href=/?page=" << HTTP_PAGE_TUNNELS << ">Tunnels</a><br>\r\n"
s << "table {width: 100%; border-collapse: collapse; text-align: center;}"; " <a href=/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << ">Transit tunnels</a><br>\r\n"
s << "</style>\r\n</head>\r\n<body>\r\n"; " <a href=/?page=" << HTTP_PAGE_TRANSPORTS << ">Transports</a><br>\r\n"
s << "<div class=header><b>i2pd </b>webconsole</div>"; " <a href=/?page=" << HTTP_PAGE_I2P_TUNNELS << ">I2P tunnels</a><br>\r\n"
s << "<div class=wrapper>"; " <a href=/?page=" << HTTP_PAGE_JUMPSERVICES << "&address=example.i2p>Jump services</a><br>\r\n"
s << "<div class=left>\r\n"; ;
s << "<a href=/>Main page</a><br>\r\n<br>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_LOCAL_DESTINATIONS << ">Local destinations</a><br>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_TUNNELS << ">Tunnels</a><br>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_TRANSIT_TUNNELS << ">Transit tunnels</a><br>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_TRANSPORTS << ">Transports</a><br>\r\n<br>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_I2P_TUNNELS << ">I2P tunnels</a><br>\r\n";
if (i2p::client::context.GetSAMBridge ()) if (i2p::client::context.GetSAMBridge ())
s << "<a href=/?cmd=" << HTTP_COMMAND_SAM_SESSIONS << ">SAM sessions</a><br>\r\n<br>\r\n"; 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 ()) if (i2p::context.AcceptsTunnels ())
s << "<a href=/?cmd=" << HTTP_COMMAND_STOP_ACCEPTING_TUNNELS << ">Stop accepting tunnels</a><br>\r\n<br>\r\n"; s << " <a href=/?cmd=" << HTTP_COMMAND_STOP_ACCEPTING_TUNNELS << ">Stop accepting tunnels</a><br>\r\n";
else else
s << "<a href=/?cmd=" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n<br>\r\n"; s << " <a href=/?cmd=" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n<br>\r\n"; s << "</div>\r\n";
s << "<a href=/?cmd=" << HTTP_COMMAND_JUMPSERVICES << "&address=example.i2p>Jump services</a><br>\r\n<br>\r\n"; s << "<div class=right>";
s << "</div><div class=right>"; if (request.uri.find("page=") != std::string::npos)
if (request.uri.find("cmd=") != std::string::npos) HandlePage (s, request.uri);
else if (request.uri.find("cmd=") != std::string::npos)
HandleCommand (s, request.uri); HandleCommand (s, request.uri);
else else
FillContent (s); ShowStatus (s);
s << "</div></div>\r\n</body>\r\n</html>"; s <<
"</div></div>\r\n"
"</body>\r\n"
"</html>\r\n";
SendReply (s.str ()); SendReply (s.str ());
} }
void HTTPConnection::FillContent (std::stringstream& s) 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 (
@ -396,40 +414,56 @@ 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::HandleCommand (std::stringstream& s, const std::string & uri) void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri)
{ {
std::map<std::string, std::string> params; std::map<std::string, std::string> params;
std::string cmd(""); std::string page("");
URL url; URL url;
url.parse(uri); url.parse(uri);
url.parse_query(params); url.parse_query(params);
cmd = params["cmd"]; page = params["page"];
if (cmd == HTTP_COMMAND_TRANSPORTS) if (page == HTTP_PAGE_TRANSPORTS)
ShowTransports (s); ShowTransports (s);
else if (cmd == HTTP_COMMAND_TUNNELS) else if (page == HTTP_PAGE_TUNNELS)
ShowTunnels (s); ShowTunnels (s);
else if (cmd == HTTP_COMMAND_JUMPSERVICES) else if (page == HTTP_PAGE_JUMPSERVICES)
ShowJumpServices (s, params["address"]); ShowJumpServices (s, params["address"]);
else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS) else if (page == HTTP_PAGE_TRANSIT_TUNNELS)
ShowTransitTunnels (s); ShowTransitTunnels (s);
else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) else if (page == HTTP_PAGE_LOCAL_DESTINATIONS)
StartAcceptingTunnels (s);
else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS)
StopAcceptingTunnels (s);
else if (cmd == HTTP_COMMAND_RUN_PEER_TEST)
RunPeerTest (s);
else if (cmd == HTTP_COMMAND_LOCAL_DESTINATIONS)
ShowLocalDestinations (s); ShowLocalDestinations (s);
else if (cmd == HTTP_COMMAND_LOCAL_DESTINATION) else if (page == HTTP_PAGE_LOCAL_DESTINATION)
ShowLocalDestination (s, params["b32"]); ShowLocalDestination (s, params["b32"]);
else if (cmd == HTTP_COMMAND_SAM_SESSIONS) else if (page == HTTP_PAGE_SAM_SESSIONS)
ShowSAMSessions (s); ShowSAMSessions (s);
else if (cmd == HTTP_COMMAND_SAM_SESSION) else if (page == HTTP_PAGE_SAM_SESSION)
ShowSAMSession (s, params["sam_id"]); ShowSAMSession (s, params["sam_id"]);
else if (cmd == HTTP_COMMAND_I2P_TUNNELS) else if (page == HTTP_PAGE_I2P_TUNNELS)
ShowI2PTunnels (s); 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) void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address)
@ -448,7 +482,7 @@ namespace http {
for (auto& it: i2p::client::context.GetDestinations ()) for (auto& it: i2p::client::context.GetDestinations ())
{ {
auto ident = it.second->GetIdentHash ();; auto ident = it.second->GetIdentHash ();;
s << "<a href=/?cmd=" << HTTP_COMMAND_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">"; s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
} }
} }
@ -548,9 +582,9 @@ namespace http {
it->Print (s); it->Print (s);
auto state = it->GetState (); auto state = it->GetState ();
if (state == i2p::tunnel::eTunnelStateFailed) if (state == i2p::tunnel::eTunnelStateFailed)
s << "<span class=failed_tunnel> " << "Failed</span>"; s << "<span class=\"tunnel failed\"> " << "Failed</span>";
else if (state == i2p::tunnel::eTunnelStateExpiring) else if (state == i2p::tunnel::eTunnelStateExpiring)
s << "<span class=expiring_tunnel> " << "Exp</span>"; s << "<span class=\"tunnel expiring\"> " << "Expiring</span>";
s << " " << (int)it->GetNumSentBytes () << "<br>\r\n"; s << " " << (int)it->GetNumSentBytes () << "<br>\r\n";
s << std::endl; s << std::endl;
} }
@ -560,9 +594,9 @@ namespace http {
it->Print (s); it->Print (s);
auto state = it->GetState (); auto state = it->GetState ();
if (state == i2p::tunnel::eTunnelStateFailed) if (state == i2p::tunnel::eTunnelStateFailed)
s << "<span class=failed_tunnel> " << "Failed</span>"; s << "<span class=\"tunnel failed\"> " << "Failed</span>";
else if (state == i2p::tunnel::eTunnelStateExpiring) else if (state == i2p::tunnel::eTunnelStateExpiring)
s << "<span class=expiring_tunnel> " << "Exp</span>"; s << "<span class=\"tunnel expiring\"> " << "Expiring</span>";
s << " " << (int)it->GetNumReceivedBytes () << "<br>\r\n"; s << " " << (int)it->GetNumReceivedBytes () << "<br>\r\n";
s << std::endl; s << std::endl;
} }
@ -640,7 +674,7 @@ namespace http {
{ {
for (auto& it: sam->GetSessions ()) for (auto& it: sam->GetSessions ())
{ {
s << "<a href=/?cmd=" << HTTP_COMMAND_SAM_SESSION << "&sam_id=" << it.first << ">"; s << "<a href=/?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << ">";
s << it.first << "</a><br>\r\n" << std::endl; s << it.first << "</a><br>\r\n" << std::endl;
} }
} }
@ -656,7 +690,7 @@ namespace http {
if (session) if (session)
{ {
auto& ident = session->localDestination->GetIdentHash(); auto& ident = session->localDestination->GetIdentHash();
s << "<a href=/?cmd=" << HTTP_COMMAND_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">"; s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
s << "<b>Streams:</b><br>\r\n"; s << "<b>Streams:</b><br>\r\n";
for (auto it: session->ListSockets()) for (auto it: session->ListSockets())
@ -688,7 +722,7 @@ namespace http {
for (auto& it: i2p::client::context.GetClientTunnels ()) for (auto& it: i2p::client::context.GetClientTunnels ())
{ {
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<a href=/?cmd=" << HTTP_COMMAND_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">"; s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
s << it.second->GetName () << "</a> ⇐ "; s << it.second->GetName () << "</a> ⇐ ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "<br>\r\n"<< std::endl; s << "<br>\r\n"<< std::endl;
@ -697,7 +731,7 @@ namespace http {
for (auto& it: i2p::client::context.GetServerTunnels ()) for (auto& it: i2p::client::context.GetServerTunnels ())
{ {
auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "<a href=/?cmd=" << HTTP_COMMAND_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">"; s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
s << it.second->GetName () << "</a> ⇒ "; s << it.second->GetName () << "</a> ⇒ ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << ":" << it.second->GetLocalPort (); s << ":" << it.second->GetLocalPort ();

5
HTTPServer.h

@ -29,21 +29,24 @@ namespace http {
void SendError (const std::string& message); void SendError (const std::string& message);
void HandleRequest (const HTTPReq & request); void HandleRequest (const HTTPReq & request);
void HandlePage (std::stringstream& s, const std::string& request);
void HandleCommand (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request);
/* pages */
void ShowJumpServices (std::stringstream& s, const std::string& address); void ShowJumpServices (std::stringstream& s, const std::string& address);
void ShowTransports (std::stringstream& s); void ShowTransports (std::stringstream& s);
void ShowTunnels (std::stringstream& s); void ShowTunnels (std::stringstream& s);
void ShowStatus (std::stringstream& s);
void ShowTransitTunnels (std::stringstream& s); void ShowTransitTunnels (std::stringstream& s);
void ShowLocalDestinations (std::stringstream& s); void ShowLocalDestinations (std::stringstream& s);
void ShowLocalDestination (std::stringstream& s, const std::string& b32); void ShowLocalDestination (std::stringstream& s, const std::string& b32);
void ShowSAMSessions (std::stringstream& s); void ShowSAMSessions (std::stringstream& s);
void ShowSAMSession (std::stringstream& s, const std::string& id); void ShowSAMSession (std::stringstream& s, const std::string& id);
void ShowI2PTunnels (std::stringstream& s); void ShowI2PTunnels (std::stringstream& s);
/* commands */
void StartAcceptingTunnels (std::stringstream& s); void StartAcceptingTunnels (std::stringstream& s);
void StopAcceptingTunnels (std::stringstream& s); void StopAcceptingTunnels (std::stringstream& s);
void RunPeerTest (std::stringstream& s); void RunPeerTest (std::stringstream& s);
void FillContent (std::stringstream& s);
protected: protected:

Loading…
Cancel
Save