@ -63,23 +63,40 @@ namespace http {
@@ -63,23 +63,40 @@ namespace http {
" body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; } \r \n "
" a, .slide label { text-decoration: none; color: #894C84; } \r \n "
" a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; } \r \n "
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; color: initial; padding: 0 5px; } \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 "
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; \r \n "
" color: initial; padding: 0 5px; border: 1px solid #894C84; } \r \n "
" .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; } \r \n "
" .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; } \r \n "
" .menu { float: left; } .menu a { display: block; padding: 2px; } \r \n "
" .content { float: left; font-size: 1em; margin-left: 4em; 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.building { color: #434343; } \r \n "
" caption { font-size: 1.5em; text-align: center; color: #894C84; } \r \n "
" table { display: table; border-collapse: collapse; text-align: center; } \r \n "
" table.extaddr { text-align: left; } \r \n table.services { width: 100%; } "
" table.extaddr { text-align: left; } table.services { width: 100%; } \r \n "
" .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;} \r \n "
" .slide div.content, .slide [type='checkbox' ] { display: none; } \r \n "
" .slide [type='checkbox']:checked ~ div. content { display: block; margin-top: 0; padding: 0; } \r \n "
" .slide div.slidecontent, .slide [type= \" checkbox \" ] { display: none; } \r \n "
" .slide [type= \" checkbox \" ]:checked ~ div.slide content { display: block; margin-top: 0; padding: 0; }\r \n "
" .disabled:after { color: #D33F3F; content: \" Disabled \" } \r \n "
" .enabled:after { color: #56B734; content: \" Enabled \" } \r \n "
" @media screen and (max-width: 980px) { \r \n " /* adaptive style */
" .menu { width: 100%; display: block; float: none; position: unset; font-size: 24px; \r \n "
" text-align: center; } \r \n "
" .content { float: none; margin: 0; margin-top: 16px; max-width: 100%; width: 100%; font-size: 1.2em; \r \n "
" text-align: center; line-height: 28px; } \r \n "
" a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ } \r \n "
" .header { margin: 0.5em 0; } small {display: block} \r \n "
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; \r \n "
" color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; } \r \n "
" input { width: 35%; height: 50px; text-align: center; /* margin-top: 15px; */ padding: 5px; \r \n "
" border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 35px; } \r \n "
" textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc; \r \n "
" -webkit-border-radius: 5px; border-radius: 5px; font-size: 22px; } \r \n "
" button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer; \r \n "
" -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 50px; display: -webkit-inline-box; margin-top: 25px; } \r \n "
" } \r \n " /* adaptive style */
" </style> \r \n " ;
const char HTTP_PAGE_TUNNELS [ ] = " tunnels " ;
@ -181,30 +198,31 @@ namespace http {
@@ -181,30 +198,31 @@ namespace http {
# else
" <meta charset= \" windows-1251 \" > \r \n "
# endif
" <meta name= \" viewport \" content= \" width=device-width, initial-scale=1.0 \" > \r \n "
" <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= \" " < < webroot < < " \" >Main page</a><br> \r \n <br> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_COMMANDS < < " \" >Router commands</a><br> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_LOCAL_DESTINATIONS < < " \" >Local destinations</a><br> \r \n " ;
" <div class= \" header \" ><b>i2pd</b> webconsole</div> \r \n "
" <div class= \" wrapper \" > \r \n "
" <div class= \" menu \" > \r \n "
" <a href= \" " < < webroot < < " \" >Main page</a><br> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_COMMANDS < < " \" >Router commands</a> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_LOCAL_DESTINATIONS < < " \" >Local destinations</a> \r \n " ;
if ( i2p : : context . IsFloodfill ( ) )
s < < " <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_LEASESETS < < " \" >LeaseSets</a><br> \r \n " ;
s < < " <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_LEASESETS < < " \" >LeaseSets</a> \r \n " ;
s < <
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_TUNNELS < < " \" >Tunnels</a><br> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_TRANSIT_TUNNELS < < " \" >Transit tunnels</a><br> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_TRANSPORTS < < " \" >Transports</a><br> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_I2P_TUNNELS < < " \" >I2P tunnels</a><br> \r \n " ;
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_TUNNELS < < " \" >Tunnels</a> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_TRANSIT_TUNNELS < < " \" >Transit tunnels</a> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_TRANSPORTS < < " \" >Transports</a> \r \n "
" <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_I2P_TUNNELS < < " \" >I2P tunnels</a> \r \n " ;
if ( i2p : : client : : context . GetSAMBridge ( ) )
s < < " <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_SAM_SESSIONS < < " \" >SAM sessions</a><br> \r \n " ;
s < < " <a href= \" " < < webroot < < " ?page= " < < HTTP_PAGE_SAM_SESSIONS < < " \" >SAM sessions</a> \r \n " ;
s < <
" </div> \r \n "
" <div class=right > " ;
" <div class= \" content \" > " ;
}
static void ShowPageTail ( std : : stringstream & s )
@ -266,7 +284,7 @@ namespace http {
@@ -266,7 +284,7 @@ namespace http {
s < < " <b>Data path:</b> " < < i2p : : fs : : GetDataDir ( ) < < " <br> \r \n " ;
s < < " <div class='slide'> " ;
if ( ( outputFormat = = OutputFormatEnum : : forWebConsole ) | | ! includeHiddenContent ) {
s < < " <label for='slide-info' >Hidden content. Press on text to see.</label> \r \n <input type='checkbox' id='slide-info'/> \r \n <div class='content' > \r \n " ;
s < < " <label for= \" slide-info \" >Hidden content. Press on text to see.</label> \r \n <input type= \" checkbox \" id= \" slide-info \" /> \r \n <div class= \" slidecontent \" > \r \n " ;
}
if ( includeHiddenContent ) {
s < < " <b>Router Ident:</b> " < < i2p : : context . GetRouterInfo ( ) . GetIdentHashBase64 ( ) < < " <br> \r \n " ;
@ -373,7 +391,7 @@ namespace http {
@@ -373,7 +391,7 @@ namespace http {
if ( dest - > IsEncryptedLeaseSet ( ) )
{
i2p : : data : : BlindedPublicKey blinded ( dest - > GetIdentity ( ) , dest - > IsPerClientAuth ( ) ) ;
s < < " <div class='slide'><label for='slide-b33'><b>Encrypted B33 address:</b></label> \r \n <input type='checkbox' id='slide-b33'/> \r \n <div class='content' > \r \n " ;
s < < " <div class='slide'><label for='slide-b33'><b>Encrypted B33 address:</b></label> \r \n <input type= \" checkbox \" id= \" slide-b33 \" /> \r \n <div class= \" slidecontent \" > \r \n " ;
s < < blinded . ToB33 ( ) < < " .b32.i2p<br> \r \n " ;
s < < " </div> \r \n </div> \r \n " ;
}
@ -381,7 +399,7 @@ namespace http {
@@ -381,7 +399,7 @@ namespace http {
if ( dest - > GetNumRemoteLeaseSets ( ) )
{
s < < " <div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i> " < < dest - > GetNumRemoteLeaseSets ( )
< < " </i></label> \r \n <input type='checkbox' id='slide-lease'/> \r \n <div class='content' > \r \n <table><thead><th>Address</th><th>Type</th><th>EncType</th></thead><tbody> " ;
< < " </i></label> \r \n <input type= \" checkbox \" id= \" slide-lease \" /> \r \n <div class= \" slidecontent \" > \r \n <table><thead><th>Address</th><th>Type</th><th>EncType</th></thead><tbody> " ;
for ( auto & it : dest - > GetLeaseSets ( ) )
s < < " <tr><td> " < < it . first . ToBase32 ( ) < < " </td><td> " < < ( int ) it . second - > GetStoreType ( ) < < " </td><td> " < < ( int ) it . second - > GetEncryptionType ( ) < < " </td></tr> \r \n " ;
s < < " </tbody></table> \r \n </div> \r \n </div> \r \n <br> \r \n " ;
@ -415,8 +433,8 @@ namespace http {
@@ -415,8 +433,8 @@ namespace http {
tmp_s < < " <tr><td> " < < i2p : : client : : context . GetAddressBook ( ) . ToAddress ( it . first ) < < " </td><td> " < < it . second - > GetNumOutgoingTags ( ) < < " </td></tr> \r \n " ;
out_tags + = it . second - > GetNumOutgoingTags ( ) ;
}
s < < " <div class='slide'><label for='slide-tags'>Outgoing: <i> " < < out_tags < < " </i></label> \r \n <input type='checkbox' id='slide-tags' /> \r \n "
< < " <div class='content'> \r \n <table><tbody> <thead><th>Destination</th><th>Amount</th></thead> \r \n " < < tmp_s . str ( ) < < " </tbody></table> \r \n </div> \r \n </div> \r \n " ;
s < < " <div class='slide'><label for='slide-tags'>Outgoing: <i> " < < out_tags < < " </i></label> \r \n <input type= \" checkbox \" id= \" slide-tags \" />\r \n "
< < " <div class= \" slidecontent \" > \r \n <table> \r \n <thead><th>Destination</th><th>Amount</th></thead> \r \n <tbody > \r \n " < < tmp_s . str ( ) < < " </tbody></table> \r \n </div> \r \n </div> \r \n " ;
} else
s < < " Outgoing: <i>0</i><br> \r \n " ;
s < < " <br> \r \n " ;
@ -431,8 +449,8 @@ namespace http {
@@ -431,8 +449,8 @@ namespace http {
tmp_s < < " <tr><td> " < < i2p : : client : : context . GetAddressBook ( ) . ToAddress ( it . second - > GetDestination ( ) ) < < " </td><td> " < < it . second - > GetState ( ) < < " </td></tr> \r \n " ;
ecies_sessions + + ;
}
s < < " <div class='slide'><label for='slide-ecies-sessions'>Tags sessions: <i> " < < ecies_sessions < < " </i></label> \r \n <input type='checkbox' id='slide-ecies-sessions' /> \r \n "
< < " <div class='content'> \r \n <table><tbody> <thead><th>Destination</th><th>Status</th></thead> \r \n " < < tmp_s . str ( ) < < " </tbody></table> \r \n </div> \r \n </div> \r \n " ;
s < < " <div class='slide'><label for='slide-ecies-sessions'>Tags sessions: <i> " < < ecies_sessions < < " </i></label> \r \n <input type= \" checkbox \" id= \" slide-ecies-sessions \" />\r \n "
< < " <div class= \" slidecontent \" > \r \n <table> \r \n <thead><th>Destination</th><th>Status</th></thead> \r \n <tbody > \r \n " < < tmp_s . str ( ) < < " </tbody></table> \r \n </div> \r \n </div> \r \n " ;
} else
s < < " Tags sessions: <i>0</i><br> \r \n " ;
s < < " <br> \r \n " ;
@ -531,7 +549,7 @@ namespace http {
@@ -531,7 +549,7 @@ namespace http {
if ( ! ls - > IsValid ( ) )
s < < " <div class='invalid'>!! Invalid !! </div> \r \n " ;
s < < " <div class='slide'><label for='slide " < < counter < < " '> " < < dest . ToBase32 ( ) < < " </label> \r \n " ;
s < < " <input type='checkbox' id=' slide " < < ( counter + + ) < < " '/> \r \n <div class='content' >\r \n " ;
s < < " <input type= \" checkbox \" id= \" slide " < < ( counter + + ) < < " \" /> \r \n <div class= \" slidecontent \" > \r \n " ;
s < < " <b>Store type:</b> " < < ( int ) storeType < < " <br> \r \n " ;
s < < " <b>Expires:</b> " < < ConvertTime ( ls - > GetExpirationTime ( ) ) < < " <br> \r \n " ;
if ( storeType = = i2p : : data : : NETDB_STORE_TYPE_LEASESET | | storeType = = i2p : : data : : NETDB_STORE_TYPE_STANDARD_LEASESET2 )
@ -682,13 +700,13 @@ namespace http {
@@ -682,13 +700,13 @@ namespace http {
if ( ! tmp_s . str ( ) . empty ( ) )
{
s < < " <div class='slide'><label for='slide_ " < < boost : : algorithm : : to_lower_copy ( name ) < < " '><b> " < < name
< < " </b> ( " < < cnt < < " )</label> \r \n <input type='checkbox' id=' slide_ " < < boost : : algorithm : : to_lower_copy ( name ) < < " '/> \r \n <div class='content' >"
< < " </b> ( " < < cnt < < " )</label> \r \n <input type= \" checkbox \" id= \" slide_ " < < boost : : algorithm : : to_lower_copy ( name ) < < " \" /> \r \n <div class= \" slidecontent \" > "
< < tmp_s . str ( ) < < " </div> \r \n </div> \r \n " ;
}
if ( ! tmp_s6 . str ( ) . empty ( ) )
{
s < < " <div class='slide'><label for='slide_ " < < boost : : algorithm : : to_lower_copy ( name ) < < " v6'><b> " < < name
< < " v6</b> ( " < < cnt6 < < " )</label> \r \n <input type='checkbox' id=' slide_ " < < boost : : algorithm : : to_lower_copy ( name ) < < " v6'/> \r \n <div class='content' > "
< < " v6</b> ( " < < cnt6 < < " )</label> \r \n <input type= \" checkbox \" id= \" slide_ " < < boost : : algorithm : : to_lower_copy ( name ) < < " v6 \" /> \r \n <div class= \" slidecontent \" > "
< < tmp_s6 . str ( ) < < " </div> \r \n </div> \r \n " ;
}
}
@ -716,7 +734,7 @@ namespace http {
@@ -716,7 +734,7 @@ namespace http {
auto sessions = ssuServer - > GetSessions ( ) ;
if ( ! sessions . empty ( ) )
{
s < < " <div class='slide'><label for='slide_ssu'><b>SSU</b> ( " < < ( int ) sessions . size ( ) < < " )</label> \r \n <input type='checkbox' id='slide_ssu'/> \r \n <div class='content' > " ;
s < < " <div class='slide'><label for='slide_ssu'><b>SSU</b> ( " < < ( int ) sessions . size ( ) < < " )</label> \r \n <input type= \" checkbox \" id= \" slide_ssu \" /> \r \n <div class= \" slidecontent \" > " ;
for ( const auto & it : sessions )
{
auto endpoint = it . second - > GetRemoteEndpoint ( ) ;
@ -733,7 +751,7 @@ namespace http {
@@ -733,7 +751,7 @@ namespace http {
auto sessions6 = ssuServer - > GetSessionsV6 ( ) ;
if ( ! sessions6 . empty ( ) )
{
s < < " <div class='slide'><label for='slide_ssuv6'><b>SSUv6</b> ( " < < ( int ) sessions6 . size ( ) < < " )</label> \r \n <input type='checkbox' id='slide_ssuv6'/> \r \n <div class='content' > " ;
s < < " <div class='slide'><label for='slide_ssuv6'><b>SSUv6</b> ( " < < ( int ) sessions6 . size ( ) < < " )</label> \r \n <input type= \" checkbox \" id= \" slide_ssuv6 \" /> \r \n <div class= \" slidecontent \" > " ;
for ( const auto & it : sessions6 )
{
auto endpoint = it . second - > GetRemoteEndpoint ( ) ;