mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 02:44:15 +00:00
commit
7ed440ba75
9
Makefile
9
Makefile
@ -7,6 +7,7 @@ I2PD := i2pd
|
|||||||
|
|
||||||
LIB_SRC_DIR := libi2pd
|
LIB_SRC_DIR := libi2pd
|
||||||
LIB_CLIENT_SRC_DIR := libi2pd_client
|
LIB_CLIENT_SRC_DIR := libi2pd_client
|
||||||
|
LANG_SRC_DIR := i18n
|
||||||
DAEMON_SRC_DIR := daemon
|
DAEMON_SRC_DIR := daemon
|
||||||
|
|
||||||
# import source files lists
|
# import source files lists
|
||||||
@ -49,12 +50,13 @@ ifeq ($(USE_MESHNET),yes)
|
|||||||
NEEDED_CXXFLAGS += -DMESHNET
|
NEEDED_CXXFLAGS += -DMESHNET
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR)
|
NEEDED_CXXFLAGS += -MMD -MP -I$(LIB_SRC_DIR) -I$(LIB_CLIENT_SRC_DIR) -I$(LANG_SRC_DIR)
|
||||||
|
|
||||||
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
LIB_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_SRC))
|
||||||
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
LIB_CLIENT_OBJS += $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC))
|
||||||
|
LANG_OBJS += $(patsubst %.cpp,obj/%.o,$(LANG_SRC))
|
||||||
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
DAEMON_OBJS += $(patsubst %.cpp,obj/%.o,$(DAEMON_SRC))
|
||||||
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
|
DEPS += $(LIB_OBJS:.o=.d) $(LIB_CLIENT_OBJS:.o=.d) $(LANG_OBJS:.o=.d) $(DAEMON_OBJS:.o=.d)
|
||||||
|
|
||||||
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
|
all: mk_obj_dir $(ARLIB) $(ARLIB_CLIENT) $(I2PD)
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ mk_obj_dir:
|
|||||||
@mkdir -p obj/Win32
|
@mkdir -p obj/Win32
|
||||||
@mkdir -p obj/$(LIB_SRC_DIR)
|
@mkdir -p obj/$(LIB_SRC_DIR)
|
||||||
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
@mkdir -p obj/$(LIB_CLIENT_SRC_DIR)
|
||||||
|
@mkdir -p obj/$(LANG_SRC_DIR)
|
||||||
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
@mkdir -p obj/$(DAEMON_SRC_DIR)
|
||||||
|
|
||||||
api: mk_obj_dir $(SHLIB) $(ARLIB)
|
api: mk_obj_dir $(SHLIB) $(ARLIB)
|
||||||
@ -82,7 +85,7 @@ obj/%.o: %.cpp
|
|||||||
# '-' is 'ignore if missing' on first run
|
# '-' is 'ignore if missing' on first run
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
$(I2PD): $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
|
$(I2PD): $(LANG_OBJS) $(DAEMON_OBJS) $(ARLIB) $(ARLIB_CLIENT)
|
||||||
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)
|
||||||
|
|
||||||
$(SHLIB): $(LIB_OBJS)
|
$(SHLIB): $(LIB_OBJS)
|
||||||
|
@ -103,6 +103,9 @@ port = 7070
|
|||||||
# auth = true
|
# auth = true
|
||||||
# user = i2pd
|
# user = i2pd
|
||||||
# pass = changeme
|
# pass = changeme
|
||||||
|
## Select webconsole language
|
||||||
|
## Currently supported only english (default) and russian languages
|
||||||
|
# lang = english
|
||||||
|
|
||||||
[httpproxy]
|
[httpproxy]
|
||||||
## Uncomment and set to 'false' to disable HTTP Proxy
|
## Uncomment and set to 'false' to disable HTTP Proxy
|
||||||
|
@ -343,6 +343,13 @@ namespace util
|
|||||||
LogPrint(eLogInfo, "Daemon: using hidden mode");
|
LogPrint(eLogInfo, "Daemon: using hidden mode");
|
||||||
i2p::data::netdb.SetHidden(true);
|
i2p::data::netdb.SetHidden(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
|
||||||
|
if (!httpLang.compare("russian"))
|
||||||
|
i2p::context.SetLanguage (eRussian);
|
||||||
|
else
|
||||||
|
i2p::context.SetLanguage (eEnglish);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ECIESX25519AEADRatchetSession.h"
|
#include "ECIESX25519AEADRatchetSession.h"
|
||||||
|
#include "I18N.h"
|
||||||
|
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
@ -40,7 +41,7 @@
|
|||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace http {
|
namespace http {
|
||||||
const char *itoopieFavicon =
|
const std::string itoopieFavicon =
|
||||||
"data:image/png;base64,"
|
"data:image/png;base64,"
|
||||||
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx"
|
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACx"
|
||||||
"jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0"
|
"jwv8YQUAAAAJcEhZcwAALiIAAC4iAari3ZIAAAAHdElNRQfgCQsUNSZrkhi1AAAAGXRFWHRTb2Z0"
|
||||||
@ -58,49 +59,51 @@ namespace http {
|
|||||||
"JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ"
|
"JHYnlIsfzJjIp9xZKswL5YKBHL+coKJoRDaUSzoozxHVrygQU4JykQADAwAT5b1NHtwZugAAAABJ"
|
||||||
"RU5ErkJggg==";
|
"RU5ErkJggg==";
|
||||||
|
|
||||||
const char *cssStyles =
|
static void GetStyles (std::stringstream& s)
|
||||||
"<style>\r\n"
|
{
|
||||||
" body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n"
|
s << "<style>\r\n"
|
||||||
" a, .slide label { text-decoration: none; color: #894C84; }\r\n"
|
<< " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n"
|
||||||
" a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n"
|
<< " a, .slide label { text-decoration: none; color: #894C84; }\r\n"
|
||||||
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
<< " a:hover, .slide label:hover { color: #FAFAFA; background: #894C84; }\r\n"
|
||||||
" color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n"
|
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
||||||
" .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n"
|
<< " color: initial; padding: 0 5px; border: 1px solid #894C84; }\r\n"
|
||||||
" .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n"
|
<< " .header { font-size: 2.5em; text-align: center; margin: 1em 0; color: #894C84; }\r\n"
|
||||||
" .menu { float: left; } .menu a, .commands a { display: block; }\r\n"
|
<< " .wrapper { margin: 0 auto; padding: 1em; max-width: 58em; }\r\n"
|
||||||
" .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
<< " .menu { float: left; } .menu a, .commands a { display: block; }\r\n"
|
||||||
" .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
<< " .listitem { display: block; font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
||||||
" .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n"
|
<< " .tableitem { font-family: monospace; font-size: 1.2em; white-space: nowrap; }\r\n"
|
||||||
" .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n"
|
<< " .content { float: left; font-size: 1em; margin-left: 4em; max-width: 45em; overflow: auto; }\r\n"
|
||||||
" .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n"
|
<< " .tunnel.established { color: #56B734; } .tunnel.expiring { color: #D3AE3F; }\r\n"
|
||||||
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
<< " .tunnel.failed { color: #D33F3F; } .tunnel.building { color: #434343; }\r\n"
|
||||||
" table { display: table; border-collapse: collapse; text-align: center; }\r\n"
|
<< " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
||||||
" table.extaddr { text-align: left; } table.services { width: 100%; }\r\n"
|
<< " table { display: table; border-collapse: collapse; text-align: center; }\r\n"
|
||||||
" textarea { word-break: break-all; }\r\n"
|
<< " table.extaddr { text-align: left; } table.services { width: 100%; }\r\n"
|
||||||
" .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n"
|
<< " textarea { word-break: break-all; }\r\n"
|
||||||
" .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n"
|
<< " .streamdest { width: 120px; max-width: 240px; overflow: hidden; text-overflow: ellipsis;}\r\n"
|
||||||
" .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
|
<< " .slide div.slidecontent, .slide [type=\"checkbox\"] { display: none; }\r\n"
|
||||||
" .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n"
|
<< " .slide [type=\"checkbox\"]:checked ~ div.slidecontent { display: block; margin-top: 0; padding: 0; }\r\n"
|
||||||
" .enabled:after { color: #56B734; content: \"Enabled\" }\r\n"
|
<< " .disabled:after { color: #D33F3F; content: \"" << tr("Disabled") << "\" }\r\n"
|
||||||
" @media screen and (max-width: 980px) {\r\n" /* adaptive style */
|
<< " .enabled:after { color: #56B734; content: \"" << tr("Enabled") << "\" }\r\n"
|
||||||
" body { padding: 1.5em 0 0 0; }\r\n"
|
<< " @media screen and (max-width: 980px) {\r\n" /* adaptive style */
|
||||||
" .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n"
|
<< " body { padding: 1.5em 0 0 0; }\r\n"
|
||||||
" text-align: center; }\r\n"
|
<< " .menu { width: 100%; display: block; float: none; position: unset; font-size: 16px;\r\n"
|
||||||
" .menu a, .commands a { padding: 2px; }\r\n"
|
<< " text-align: center; }\r\n"
|
||||||
" .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n"
|
<< " .menu a, .commands a { padding: 2px; }\r\n"
|
||||||
" text-align: center; }\r\n"
|
<< " .content { float: none; margin-left: unset; margin-top: 16px; max-width: 100%; width: 100%;\r\n"
|
||||||
" a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n"
|
<< " text-align: center; }\r\n"
|
||||||
" .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n"
|
<< " a, .slide label { /* margin-right: 10px; */ display: block; /* font-size: 18px; */ }\r\n"
|
||||||
" a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
<< " .header { margin: unset; font-size: 1.5em; } small {display: block}\r\n"
|
||||||
" color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n"
|
<< " a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none;\r\n"
|
||||||
" input { width: 35%; text-align: center; padding: 5px;\r\n"
|
<< " color: initial; margin-top: 10px; padding: 6px; border: 1px solid #894c84; width: -webkit-fill-available; }\r\n"
|
||||||
" border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n"
|
<< " input { width: 35%; text-align: center; padding: 5px;\r\n"
|
||||||
" textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n"
|
<< " border: 2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font-size: 18px; }\r\n"
|
||||||
" -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n"
|
<< " textarea { width: -webkit-fill-available; height: auto; padding:5px; border:2px solid #ccc;\r\n"
|
||||||
" button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n"
|
<< " -webkit-border-radius: 5px; border-radius: 5px; font-size: 12px; }\r\n"
|
||||||
" -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
|
<< " button[type=submit] { padding: 5px 15px; background: #ccc; border: 0 none; cursor: pointer;\r\n"
|
||||||
" }\r\n" /* adaptive style */
|
<< " -webkit-border-radius: 5px; border-radius: 5px; position: relative; height: 36px; display: -webkit-inline-box; margin-top: 10px; }\r\n"
|
||||||
"</style>\r\n";
|
<< " }\r\n" /* adaptive style */
|
||||||
|
<< "</style>\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
const char HTTP_PAGE_TUNNELS[] = "tunnels";
|
const char HTTP_PAGE_TUNNELS[] = "tunnels";
|
||||||
const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels";
|
const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels";
|
||||||
@ -135,18 +138,18 @@ namespace http {
|
|||||||
int num;
|
int num;
|
||||||
|
|
||||||
if ((num = seconds / 86400) > 0) {
|
if ((num = seconds / 86400) > 0) {
|
||||||
s << num << " days, ";
|
s << num << " " << tr("days", num) << ", ";
|
||||||
seconds -= num * 86400;
|
seconds -= num * 86400;
|
||||||
}
|
}
|
||||||
if ((num = seconds / 3600) > 0) {
|
if ((num = seconds / 3600) > 0) {
|
||||||
s << num << " hours, ";
|
s << num << " " << tr("hours", num) << ", ";
|
||||||
seconds -= num * 3600;
|
seconds -= num * 3600;
|
||||||
}
|
}
|
||||||
if ((num = seconds / 60) > 0) {
|
if ((num = seconds / 60) > 0) {
|
||||||
s << num << " min, ";
|
s << num << " " << tr("minutes", num) << ", ";
|
||||||
seconds -= num * 60;
|
seconds -= num * 60;
|
||||||
}
|
}
|
||||||
s << seconds << " seconds";
|
s << seconds << " " << tr("seconds", seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowTraffic (std::stringstream& s, uint64_t bytes)
|
static void ShowTraffic (std::stringstream& s, uint64_t bytes)
|
||||||
@ -154,28 +157,35 @@ namespace http {
|
|||||||
s << std::fixed << std::setprecision(2);
|
s << std::fixed << std::setprecision(2);
|
||||||
auto numKBytes = (double) bytes / 1024;
|
auto numKBytes = (double) bytes / 1024;
|
||||||
if (numKBytes < 1024)
|
if (numKBytes < 1024)
|
||||||
s << numKBytes << " KiB";
|
s << numKBytes << " " << tr("KiB");
|
||||||
else if (numKBytes < 1024 * 1024)
|
else if (numKBytes < 1024 * 1024)
|
||||||
s << numKBytes / 1024 << " MiB";
|
s << numKBytes / 1024 << " " << tr("MiB");
|
||||||
else
|
else
|
||||||
s << numKBytes / 1024 / 1024 << " GiB";
|
s << numKBytes / 1024 / 1024 << " " << tr("GiB");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
|
static void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, bool explr, int bytes)
|
||||||
{
|
{
|
||||||
std::string state;
|
std::string state, stateText;
|
||||||
switch (eState) {
|
switch (eState) {
|
||||||
case i2p::tunnel::eTunnelStateBuildReplyReceived :
|
case i2p::tunnel::eTunnelStateBuildReplyReceived :
|
||||||
case i2p::tunnel::eTunnelStatePending : state = "building"; break;
|
case i2p::tunnel::eTunnelStatePending : state = "building"; break;
|
||||||
case i2p::tunnel::eTunnelStateBuildFailed :
|
case i2p::tunnel::eTunnelStateBuildFailed :
|
||||||
case i2p::tunnel::eTunnelStateTestFailed :
|
case i2p::tunnel::eTunnelStateTestFailed :
|
||||||
case i2p::tunnel::eTunnelStateFailed : state = "failed"; break;
|
case i2p::tunnel::eTunnelStateFailed : state = "failed"; break;
|
||||||
case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break;
|
case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break;
|
||||||
case i2p::tunnel::eTunnelStateEstablished : state = "established"; break;
|
case i2p::tunnel::eTunnelStateEstablished : state = "established"; break;
|
||||||
default: state = "unknown"; break;
|
default: state = "unknown"; break;
|
||||||
}
|
}
|
||||||
s << "<span class=\"tunnel " << state << "\"> " << state << ((explr) ? " (exploratory)" : "") << "</span>, ";
|
|
||||||
s << " " << (int) (bytes / 1024) << " KiB\r\n";
|
if (state == "building") stateText = tr("building");
|
||||||
|
else if (state == "failed") stateText = tr("failed");
|
||||||
|
else if (state == "expiring") stateText = tr("expiring");
|
||||||
|
else if (state == "established") stateText = tr("established");
|
||||||
|
else stateText = tr("unknown");
|
||||||
|
|
||||||
|
s << "<span class=\"tunnel " << state << "\"> " << stateText << ((explr) ? " (" + tr("exploratory") + ")" : "") << "</span>, ";
|
||||||
|
s << " " << (int) (bytes / 1024) << " " << tr("KiB") << "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetLogLevel (const std::string& level)
|
static void SetLogLevel (const std::string& level)
|
||||||
@ -191,39 +201,40 @@ namespace http {
|
|||||||
|
|
||||||
static void ShowPageHead (std::stringstream& s)
|
static void ShowPageHead (std::stringstream& s)
|
||||||
{
|
{
|
||||||
std::string webroot;
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
i2p::config::GetOption("http.webroot", webroot);
|
|
||||||
|
// Page language
|
||||||
|
std::string lang, langCode; i2p::config::GetOption("http.lang", lang);
|
||||||
|
if (lang == "russian") langCode = "ru";
|
||||||
|
else langCode = "en";
|
||||||
|
|
||||||
s <<
|
s <<
|
||||||
"<!DOCTYPE html>\r\n"
|
"<!DOCTYPE html>\r\n"
|
||||||
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
"<html lang=\"" << langCode << "\">\r\n"
|
||||||
" <head>\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
|
" <head>\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
|
||||||
#if (!defined(WIN32))
|
|
||||||
" <meta charset=\"UTF-8\">\r\n"
|
" <meta charset=\"UTF-8\">\r\n"
|
||||||
#else
|
|
||||||
" <meta charset=\"windows-1251\">\r\n"
|
|
||||||
#endif
|
|
||||||
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
|
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n"
|
||||||
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
||||||
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
" <title>Purple I2P " VERSION " Webconsole</title>\r\n";
|
||||||
<< cssStyles <<
|
GetStyles(s);
|
||||||
"</head>\r\n";
|
|
||||||
s <<
|
s <<
|
||||||
|
"</head>\r\n"
|
||||||
"<body>\r\n"
|
"<body>\r\n"
|
||||||
"<div class=\"header\"><b>i2pd</b> webconsole</div>\r\n"
|
"<div class=\"header\">" << tr("<b>i2pd</b> webconsole") << "</div>\r\n"
|
||||||
"<div class=\"wrapper\">\r\n"
|
"<div class=\"wrapper\">\r\n"
|
||||||
"<div class=\"menu\">\r\n"
|
"<div class=\"menu\">\r\n"
|
||||||
" <a href=\"" << webroot << "\">Main page</a><br>\r\n"
|
" <a href=\"" << webroot << "\">" << tr("Main page") << "</a><br>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_COMMANDS << "\">" << tr("Router commands") << "</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">" << tr("Local destinations") << "</a>\r\n";
|
||||||
if (i2p::context.IsFloodfill ())
|
if (i2p::context.IsFloodfill ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">LeaseSets</a>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_LEASESETS << "\">" << tr("LeaseSets") << "</a>\r\n";
|
||||||
s <<
|
s <<
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TUNNELS << "\">" << tr("Tunnels") << "</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">" << tr("Transit tunnels") << "</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a>\r\n"
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_TRANSPORTS << "\">" << tr ("Transports") << "</a>\r\n"
|
||||||
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a>\r\n";
|
" <a href=\"" << webroot << "?page=" << HTTP_PAGE_I2P_TUNNELS << "\">" << tr("I2P tunnels") << "</a>\r\n";
|
||||||
if (i2p::client::context.GetSAMBridge ())
|
if (i2p::client::context.GetSAMBridge ())
|
||||||
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a>\r\n";
|
s << " <a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSIONS << "\">" << tr("SAM sessions") << "</a>\r\n";
|
||||||
s <<
|
s <<
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=\"content\">";
|
"<div class=\"content\">";
|
||||||
@ -239,94 +250,94 @@ namespace http {
|
|||||||
|
|
||||||
static void ShowError(std::stringstream& s, const std::string& string)
|
static void ShowError(std::stringstream& s, const std::string& string)
|
||||||
{
|
{
|
||||||
s << "<b>ERROR:</b> " << string << "<br>\r\n";
|
s << "<b>" << tr("ERROR") << ":</b> " << string << "<br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status)
|
static void ShowNetworkStatus (std::stringstream& s, RouterStatus status)
|
||||||
{
|
{
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case eRouterStatusOK: s << "OK"; break;
|
case eRouterStatusOK: s << tr("OK"); break;
|
||||||
case eRouterStatusTesting: s << "Testing"; break;
|
case eRouterStatusTesting: s << tr("Testing"); break;
|
||||||
case eRouterStatusFirewalled: s << "Firewalled"; break;
|
case eRouterStatusFirewalled: s << tr("Firewalled"); break;
|
||||||
case eRouterStatusUnknown: s << "Unknown"; break;
|
case eRouterStatusUnknown: s << tr("Unknown"); break;
|
||||||
case eRouterStatusProxy: s << "Proxy"; break;
|
case eRouterStatusProxy: s << tr("Proxy"); break;
|
||||||
case eRouterStatusMesh: s << "Mesh"; break;
|
case eRouterStatusMesh: s << tr("Mesh"); break;
|
||||||
case eRouterStatusError:
|
case eRouterStatusError:
|
||||||
{
|
{
|
||||||
s << "Error";
|
s << tr("Error");
|
||||||
switch (i2p::context.GetError ())
|
switch (i2p::context.GetError ())
|
||||||
{
|
{
|
||||||
case eRouterErrorClockSkew:
|
case eRouterErrorClockSkew:
|
||||||
s << " - Clock skew";
|
s << " - " << tr("Clock skew");
|
||||||
break;
|
break;
|
||||||
case eRouterErrorOffline:
|
case eRouterErrorOffline:
|
||||||
s << " - Offline";
|
s << " - " << tr("Offline");
|
||||||
break;
|
break;
|
||||||
case eRouterErrorSymmetricNAT:
|
case eRouterErrorSymmetricNAT:
|
||||||
s << " - Symmetric NAT";
|
s << " - " << tr("Symmetric NAT");
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: s << "Unknown";
|
default: s << tr("Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat)
|
void ShowStatus (std::stringstream& s, bool includeHiddenContent, i2p::http::OutputFormatEnum outputFormat)
|
||||||
{
|
{
|
||||||
s << "<b>Uptime:</b> ";
|
s << "<b>" << tr("Uptime") << ":</b> ";
|
||||||
ShowUptime(s, i2p::context.GetUptime ());
|
ShowUptime(s, i2p::context.GetUptime ());
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Network status:</b> ";
|
s << "<b>" << tr("Network status") << ":</b> ";
|
||||||
ShowNetworkStatus (s, i2p::context.GetStatus ());
|
ShowNetworkStatus (s, i2p::context.GetStatus ());
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
if (i2p::context.SupportsV6 ())
|
if (i2p::context.SupportsV6 ())
|
||||||
{
|
{
|
||||||
s << "<b>Network status 6:</b> ";
|
s << "<b>" << tr("Network status v6") << ":</b> ";
|
||||||
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
|
ShowNetworkStatus (s, i2p::context.GetStatusV6 ());
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}
|
}
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (auto remains = Daemon.gracefulShutdownInterval) {
|
if (auto remains = Daemon.gracefulShutdownInterval) {
|
||||||
s << "<b>Stopping in:</b> ";
|
s << "<b>" << tr("Stopping in") << ":</b> ";
|
||||||
ShowUptime(s, remains);
|
ShowUptime(s, remains);
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}
|
}
|
||||||
#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::win32::g_GracefulShutdownEndtime != 0) {
|
if (i2p::win32::g_GracefulShutdownEndtime != 0) {
|
||||||
uint16_t remains = (i2p::win32::g_GracefulShutdownEndtime - GetTickCount()) / 1000;
|
uint16_t remains = (i2p::win32::g_GracefulShutdownEndtime - GetTickCount()) / 1000;
|
||||||
s << "<b>Stopping in:</b> ";
|
s << "<b>" << tr("Stopping in") << ":</b> ";
|
||||||
ShowUptime(s, remains);
|
ShowUptime(s, remains);
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
auto family = i2p::context.GetFamily ();
|
auto family = i2p::context.GetFamily ();
|
||||||
if (family.length () > 0)
|
if (family.length () > 0)
|
||||||
s << "<b>Family:</b> " << family << "<br>\r\n";
|
s << "<b>"<< tr("Family") << ":</b> " << family << "<br>\r\n";
|
||||||
s << "<b>Tunnel creation success rate:</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
|
s << "<b>" << tr("Tunnel creation success rate") << ":</b> " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%<br>\r\n";
|
||||||
s << "<b>Received:</b> ";
|
s << "<b>" << tr("Received") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " KiB/s)<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr("KiB/s") << ")<br>\r\n";
|
||||||
s << "<b>Sent:</b> ";
|
s << "<b>" << tr("Sent") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr("KiB/s") << ")<br>\r\n";
|
||||||
s << "<b>Transit:</b> ";
|
s << "<b>" << tr("Transit") << ":</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr("KiB/s") << ")<br>\r\n";
|
||||||
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
|
s << "<b>" << tr("Data path") << ":</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
|
||||||
s << "<div class='slide'>";
|
s << "<div class='slide'>";
|
||||||
if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
|
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=\"slidecontent\">\r\n";
|
s << "<label for=\"slide-info\">" << tr("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) {
|
if(includeHiddenContent) {
|
||||||
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
|
s << "<b>" << tr("Router Ident") << ":</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
|
||||||
if (!i2p::context.GetRouterInfo().GetProperty("family").empty())
|
if (!i2p::context.GetRouterInfo().GetProperty("family").empty())
|
||||||
s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
|
s << "<b>" << tr("Router Family") << ":</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
|
||||||
s << "<b>Router Caps:</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n";
|
s << "<b>" << tr("Router Caps") << ":</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n";
|
||||||
s << "<b>Version:</b> " VERSION "<br>\r\n";
|
s << "<b>" << tr("Version") << ":</b> " VERSION "<br>\r\n";
|
||||||
s << "<b>Our external address:</b>" << "<br>\r\n<table class=\"extaddr\"><tbody>\r\n";
|
s << "<b>"<< tr("Our external address") << ":</b>" << "<br>\r\n<table class=\"extaddr\"><tbody>\r\n";
|
||||||
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
||||||
{
|
{
|
||||||
s << "<tr>\r\n";
|
s << "<tr>\r\n";
|
||||||
@ -334,7 +345,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
s << "<td>NTCP2";
|
s << "<td>NTCP2";
|
||||||
if (address->host.is_v6 ()) s << "v6";
|
if (address->host.is_v6 ()) s << "v6";
|
||||||
s << "</td><td>supported</td>\r\n</tr>\r\n";
|
s << "</td><td>" << tr("supported") << "</td>\r\n</tr>\r\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (address->transportStyle)
|
switch (address->transportStyle)
|
||||||
@ -356,32 +367,32 @@ namespace http {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
s << "<td>Unknown</td>\r\n";
|
s << "<td>" << tr("Unknown") << "</td>\r\n";
|
||||||
}
|
}
|
||||||
s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n</tr>\r\n";
|
s << "<td>" << address->host.to_string() << ":" << address->port << "</td>\r\n</tr>\r\n";
|
||||||
}
|
}
|
||||||
s << "</tbody></table>\r\n";
|
s << "</tbody></table>\r\n";
|
||||||
}
|
}
|
||||||
s << "</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n";
|
||||||
if(outputFormat==OutputFormatEnum::forQtUi) {
|
if(outputFormat == OutputFormatEnum::forQtUi) {
|
||||||
s << "<br>";
|
s << "<br>";
|
||||||
}
|
}
|
||||||
s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
s << "<b>" << tr("Routers") << ":</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
||||||
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
|
s << "<b>" << tr("Floodfills") << ":</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
|
||||||
s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
|
s << "<b>" << tr("LeaseSets") << ":</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
|
||||||
|
|
||||||
size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels();
|
size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels();
|
||||||
clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels();
|
clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels();
|
||||||
size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels();
|
size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels();
|
||||||
|
|
||||||
s << "<b>Client Tunnels:</b> " << std::to_string(clientTunnelCount) << " ";
|
s << "<b>" << tr("Client Tunnels") << ":</b> " << std::to_string(clientTunnelCount) << " ";
|
||||||
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n<br>\r\n";
|
s << "<b>" << tr("Transit Tunnels") << ":</b> " << std::to_string(transitTunnelCount) << "<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
if(outputFormat==OutputFormatEnum::forWebConsole) {
|
if(outputFormat==OutputFormatEnum::forWebConsole) {
|
||||||
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||||
s << "<table class=\"services\"><caption>Services</caption><tbody>\r\n";
|
s << "<table class=\"services\"><caption>" << tr("Services") << "</caption><tbody>\r\n";
|
||||||
s << "<tr><td>" << "HTTP Proxy" << "</td><td><div class='" << ((i2p::client::context.GetHttpProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
s << "<tr><td>" << "HTTP " << tr("Proxy") << "</td><td><div class='" << ((i2p::client::context.GetHttpProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
s << "<tr><td>" << "SOCKS Proxy" << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
s << "<tr><td>" << "SOCKS " << tr("Proxy") << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
s << "<tr><td>" << "BOB" << "</td><td><div class='" << ((i2p::client::context.GetBOBCommandChannel ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
s << "<tr><td>" << "BOB" << "</td><td><div class='" << ((i2p::client::context.GetBOBCommandChannel ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
s << "<tr><td>" << "SAM" << "</td><td><div class='" << ((i2p::client::context.GetSAMBridge ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
s << "<tr><td>" << "SAM" << "</td><td><div class='" << ((i2p::client::context.GetSAMBridge ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
s << "<tr><td>" << "I2CP" << "</td><td><div class='" << ((i2p::client::context.GetI2CPServer ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
s << "<tr><td>" << "I2CP" << "</td><td><div class='" << ((i2p::client::context.GetI2CPServer ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
@ -393,7 +404,7 @@ namespace http {
|
|||||||
void ShowLocalDestinations (std::stringstream& s)
|
void ShowLocalDestinations (std::stringstream& s)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>Local Destinations:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Local Destinations") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: i2p::client::context.GetDestinations ())
|
for (auto& it: i2p::client::context.GetDestinations ())
|
||||||
{
|
{
|
||||||
auto ident = it.second->GetIdentHash ();
|
auto ident = it.second->GetIdentHash ();
|
||||||
@ -405,7 +416,7 @@ namespace http {
|
|||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
||||||
{
|
{
|
||||||
s << "<br><b>I2CP Local Destinations:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<br><b>I2CP "<< tr("Local Destinations") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: i2cpServer->GetSessions ())
|
for (auto& it: i2cpServer->GetSessions ())
|
||||||
{
|
{
|
||||||
auto dest = it.second->GetDestination ();
|
auto dest = it.second->GetDestination ();
|
||||||
@ -428,7 +439,7 @@ namespace http {
|
|||||||
if (dest->IsEncryptedLeaseSet ())
|
if (dest->IsEncryptedLeaseSet ())
|
||||||
{
|
{
|
||||||
i2p::data::BlindedPublicKey blinded (dest->GetIdentity (), dest->IsPerClientAuth ());
|
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=\"slidecontent\">\r\n";
|
s << "<div class='slide'><label for='slide-b33'><b>" << tr("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 << blinded.ToB33 () << ".b32.i2p<br>\r\n";
|
||||||
s << "</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
@ -437,67 +448,67 @@ namespace http {
|
|||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
auto base32 = dest->GetIdentHash ().ToBase32 ();
|
auto base32 = dest->GetIdentHash ().ToBase32 ();
|
||||||
s << "<div class='slide'><label for='slide-regaddr'><b>Address registration line</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n"
|
s << "<div class='slide'><label for='slide-regaddr'><b>" << tr("Address registration line") << "</b></label>\r\n<input type=\"checkbox\" id=\"slide-regaddr\" />\r\n<div class=\"slidecontent\">\r\n"
|
||||||
"<form method=\"get\" action=\"" << webroot << "\">\r\n"
|
"<form method=\"get\" action=\"" << webroot << "\">\r\n"
|
||||||
" <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n"
|
" <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_GET_REG_STRING << "\">\r\n"
|
||||||
" <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"
|
" <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n"
|
||||||
" <input type=\"hidden\" name=\"b32\" value=\"" << base32 << "\">\r\n"
|
" <input type=\"hidden\" name=\"b32\" value=\"" << base32 << "\">\r\n"
|
||||||
" <b>Domain:</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n"
|
" <b>" << tr("Domain") << ":</b>\r\n<input type=\"text\" maxlength=\"67\" name=\"name\" placeholder=\"domain.i2p\" required>\r\n"
|
||||||
" <button type=\"submit\">Generate</button>\r\n"
|
" <button type=\"submit\">" << tr("Generate") << "</button>\r\n"
|
||||||
"</form>\r\n<small><b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.</small>\r\n</div>\r\n</div>\r\n<br>\r\n";
|
"</form>\r\n<small><b>Note:</b> result string can be used only for registering 2LD domains (example.i2p). For registering subdomains please use i2pd-tools.</small>\r\n</div>\r\n</div>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dest->GetNumRemoteLeaseSets())
|
if(dest->GetNumRemoteLeaseSets())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'><label for='slide-lease'><b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets ()
|
s << "<div class='slide'><label for='slide-lease'><b>" << tr("LeaseSets") << ":</b> <i>" << dest->GetNumRemoteLeaseSets ()
|
||||||
<< "</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 class=\"tableitem\">";
|
<< "</i></label>\r\n<input type=\"checkbox\" id=\"slide-lease\" />\r\n<div class=\"slidecontent\">\r\n<table><thead><th>"<< tr("Address") << "</th><th>" << tr("Type") << "</th><th>" << tr("EncType") << "</th></thead><tbody class=\"tableitem\">";
|
||||||
for(auto& it: dest->GetLeaseSets ())
|
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 << "<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";
|
s << "</tbody></table>\r\n</div>\r\n</div>\r\n<br>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "<b>LeaseSets:</b> <i>0</i><br>\r\n<br>\r\n";
|
s << "<b>" << tr("LeaseSets") << ":</b> <i>0</i><br>\r\n<br>\r\n";
|
||||||
|
|
||||||
auto pool = dest->GetTunnelPool ();
|
auto pool = dest->GetTunnelPool ();
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
s << "<b>Inbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Inbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : pool->GetInboundTunnels ()) {
|
for (auto & it : pool->GetInboundTunnels ()) {
|
||||||
s << "<div class=\"listitem\">";
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
|
||||||
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
|
ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ());
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Outbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Outbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : pool->GetOutboundTunnels ()) {
|
for (auto & it : pool->GetOutboundTunnels ()) {
|
||||||
s << "<div class=\"listitem\">";
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
|
||||||
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
|
ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ());
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
|
|
||||||
s << "<b>Tags</b><br>\r\nIncoming: <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
|
s << "<b>" << tr("Tags") << "</b><br>\r\n" << tr("Incoming") << ": <i>" << dest->GetNumIncomingTags () << "</i><br>\r\n";
|
||||||
if (!dest->GetSessions ().empty ()) {
|
if (!dest->GetSessions ().empty ()) {
|
||||||
std::stringstream tmp_s; uint32_t out_tags = 0;
|
std::stringstream tmp_s; uint32_t out_tags = 0;
|
||||||
for (const auto& it: dest->GetSessions ()) {
|
for (const auto& it: dest->GetSessions ()) {
|
||||||
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.first) << "</td><td>" << it.second->GetNumOutgoingTags () << "</td></tr>\r\n";
|
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 ();
|
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"
|
s << "<div class='slide'><label for='slide-tags'>" << tr("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 class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
<< "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Amount") << "</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "Outgoing: <i>0</i><br>\r\n";
|
s << tr("Outgoing") << ": <i>0</i><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
|
|
||||||
auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags ();
|
auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags ();
|
||||||
if (numECIESx25519Tags > 0) {
|
if (numECIESx25519Tags > 0) {
|
||||||
s << "<b>ECIESx25519</b><br>\r\nIncoming Tags: <i>" << numECIESx25519Tags << "</i><br>\r\n";
|
s << "<b>ECIESx25519</b><br>\r\n" << tr("Incoming Tags") << ": <i>" << numECIESx25519Tags << "</i><br>\r\n";
|
||||||
if (!dest->GetECIESx25519Sessions ().empty ())
|
if (!dest->GetECIESx25519Sessions ().empty ())
|
||||||
{
|
{
|
||||||
std::stringstream tmp_s; uint32_t ecies_sessions = 0;
|
std::stringstream tmp_s; uint32_t ecies_sessions = 0;
|
||||||
@ -505,17 +516,17 @@ namespace http {
|
|||||||
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
|
tmp_s << "<tr><td>" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetDestination ()) << "</td><td>" << it.second->GetState () << "</td></tr>\r\n";
|
||||||
ecies_sessions++;
|
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"
|
s << "<div class='slide'><label for='slide-ecies-sessions'>" << tr("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 class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
<< "<div class=\"slidecontent\">\r\n<table>\r\n<thead><th>" << tr("Destination") << "</th><th>" << tr("Status") << "</th></thead>\r\n<tbody class=\"tableitem\">\r\n" << tmp_s.str () << "</tbody></table>\r\n</div>\r\n</div>\r\n";
|
||||||
} else
|
} else
|
||||||
s << "Tags sessions: <i>0</i><br>\r\n";
|
s << tr("Tags sessions") << ": <i>0</i><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token)
|
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token)
|
||||||
{
|
{
|
||||||
s << "<b>Local Destination:</b><br>\r\n<br>\r\n";
|
s << "<b>" << tr("Local Destination") << ":</b><br>\r\n<br>\r\n";
|
||||||
i2p::data::IdentHash ident;
|
i2p::data::IdentHash ident;
|
||||||
ident.FromBase32 (b32);
|
ident.FromBase32 (b32);
|
||||||
auto dest = i2p::client::context.FindLocalDestination (ident);
|
auto dest = i2p::client::context.FindLocalDestination (ident);
|
||||||
@ -524,7 +535,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
ShowLeaseSetDestination (s, dest, token);
|
ShowLeaseSetDestination (s, dest, token);
|
||||||
// show streams
|
// show streams
|
||||||
s << "<table>\r\n<caption>Streams</caption>\r\n<thead>\r\n<tr>";
|
s << "<table>\r\n<caption>" << tr("Streams") << "</caption>\r\n<thead>\r\n<tr>";
|
||||||
s << "<th style=\"width:25px;\">StreamID</th>";
|
s << "<th style=\"width:25px;\">StreamID</th>";
|
||||||
s << "<th style=\"width:5px;\" \\>"; // Stream closing button column
|
s << "<th style=\"width:5px;\" \\>"; // Stream closing button column
|
||||||
s << "<th class=\"streamdest\">Destination</th>";
|
s << "<th class=\"streamdest\">Destination</th>";
|
||||||
@ -546,7 +557,7 @@ namespace http {
|
|||||||
s << "<td>" << it->GetRecvStreamID () << "</td>";
|
s << "<td>" << it->GetRecvStreamID () << "</td>";
|
||||||
if (it->GetRecvStreamID ()) {
|
if (it->GetRecvStreamID ()) {
|
||||||
s << "<td><a class=\"button\" href=\"/?cmd=" << HTTP_COMMAND_KILLSTREAM << "&b32=" << b32 << "&streamID="
|
s << "<td><a class=\"button\" href=\"/?cmd=" << HTTP_COMMAND_KILLSTREAM << "&b32=" << b32 << "&streamID="
|
||||||
<< it->GetRecvStreamID () << "&token=" << token << "\" title=\"Close stream\"> ✘ </a></td>";
|
<< it->GetRecvStreamID () << "&token=" << token << "\" title=\"" << tr("Close stream") << "\"> ✘ </a></td>";
|
||||||
} else {
|
} else {
|
||||||
s << "<td \\>";
|
s << "<td \\>";
|
||||||
}
|
}
|
||||||
@ -570,22 +581,22 @@ namespace http {
|
|||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
if (i2cpServer)
|
if (i2cpServer)
|
||||||
{
|
{
|
||||||
s << "<b>I2CP Local Destination:</b><br>\r\n<br>\r\n";
|
s << "<b>I2CP " << tr("Local Destination") << ":</b><br>\r\n<br>\r\n";
|
||||||
auto it = i2cpServer->GetSessions ().find (std::stoi (id));
|
auto it = i2cpServer->GetSessions ().find (std::stoi (id));
|
||||||
if (it != i2cpServer->GetSessions ().end ())
|
if (it != i2cpServer->GetSessions ().end ())
|
||||||
ShowLeaseSetDestination (s, it->second->GetDestination (), 0);
|
ShowLeaseSetDestination (s, it->second->GetDestination (), 0);
|
||||||
else
|
else
|
||||||
ShowError(s, "I2CP session not found");
|
ShowError(s, tr("I2CP session not found"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ShowError(s, "I2CP is not enabled");
|
ShowError(s, tr("I2CP is not enabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowLeasesSets(std::stringstream& s)
|
void ShowLeasesSets(std::stringstream& s)
|
||||||
{
|
{
|
||||||
if (i2p::data::netdb.GetNumLeaseSets ())
|
if (i2p::data::netdb.GetNumLeaseSets ())
|
||||||
{
|
{
|
||||||
s << "<b>LeaseSets:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("LeaseSets") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
// for each lease set
|
// for each lease set
|
||||||
i2p::data::netdb.VisitLeaseSets(
|
i2p::data::netdb.VisitLeaseSets(
|
||||||
@ -604,21 +615,21 @@ namespace http {
|
|||||||
s << " expired"; // additional css class for expired
|
s << " expired"; // additional css class for expired
|
||||||
s << "\">\r\n";
|
s << "\">\r\n";
|
||||||
if (!ls->IsValid())
|
if (!ls->IsValid())
|
||||||
s << "<div class=\"invalid\">!! Invalid !! </div>\r\n";
|
s << "<div class=\"invalid\">!! " << tr("Invalid") << " !! </div>\r\n";
|
||||||
s << "<div class=\"slide\"><label for=\"slide" << counter << "\">" << dest.ToBase32() << "</label>\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=\"slidecontent\">\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>" << tr("Store type") << ":</b> " << (int)storeType << "<br>\r\n";
|
||||||
s << "<b>Expires:</b> " << ConvertTime(ls->GetExpirationTime()) << "<br>\r\n";
|
s << "<b>" << tr("Expires") << ":</b> " << ConvertTime(ls->GetExpirationTime()) << "<br>\r\n";
|
||||||
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
if (storeType == i2p::data::NETDB_STORE_TYPE_LEASESET || storeType == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
||||||
{
|
{
|
||||||
// leases information is available
|
// leases information is available
|
||||||
auto leases = ls->GetNonExpiredLeases();
|
auto leases = ls->GetNonExpiredLeases();
|
||||||
s << "<b>Non Expired Leases: " << leases.size() << "</b><br>\r\n";
|
s << "<b>" << tr("Non Expired Leases") << ": " << leases.size() << "</b><br>\r\n";
|
||||||
for ( auto & l : leases )
|
for ( auto & l : leases )
|
||||||
{
|
{
|
||||||
s << "<b>Gateway:</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
|
s << "<b>" << tr("Gateway") << ":</b> " << l->tunnelGateway.ToBase64() << "<br>\r\n";
|
||||||
s << "<b>TunnelID:</b> " << l->tunnelID << "<br>\r\n";
|
s << "<b>" << tr("TunnelID") << ":</b> " << l->tunnelID << "<br>\r\n";
|
||||||
s << "<b>EndDate:</b> " << ConvertTime(l->endDate) << "<br>\r\n";
|
s << "<b>" << tr("EndDate") << ":</b> " << ConvertTime(l->endDate) << "<br>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s << "</div>\r\n</div>\r\n</div>\r\n";
|
s << "</div>\r\n</div>\r\n</div>\r\n";
|
||||||
@ -628,37 +639,37 @@ namespace http {
|
|||||||
}
|
}
|
||||||
else if (!i2p::context.IsFloodfill ())
|
else if (!i2p::context.IsFloodfill ())
|
||||||
{
|
{
|
||||||
s << "<b>LeaseSets:</b> not floodfill.<br>\r\n";
|
s << "<b>" << tr("LeaseSets") << ":</b> " << tr("not floodfill") << ".<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s << "<b>LeaseSets:</b> 0<br>\r\n";
|
s << "<b>" << tr("LeaseSets") << ":</b> 0<br>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowTunnels (std::stringstream& s)
|
void ShowTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<b>Tunnels:</b><br>\r\n";
|
s << "<b>" << tr("Tunnels") << ":</b><br>\r\n";
|
||||||
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n<br>\r\n";
|
s << "<b>" << tr("Queue size") << ":</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
auto ExplPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||||
|
|
||||||
s << "<b>Inbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Inbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) {
|
for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) {
|
||||||
s << "<div class=\"listitem\">";
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
|
||||||
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ());
|
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ());
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
s << "</div>\r\n<br>\r\n";
|
s << "</div>\r\n<br>\r\n";
|
||||||
s << "<b>Outbound tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Outbound tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) {
|
for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) {
|
||||||
s << "<div class=\"listitem\">";
|
s << "<div class=\"listitem\">";
|
||||||
it->Print(s);
|
it->Print(s);
|
||||||
if(it->LatencyIsKnown())
|
if(it->LatencyIsKnown())
|
||||||
s << " ( " << it->GetMeanLatency() << "ms )";
|
s << " ( " << it->GetMeanLatency() << tr("ms") << " )";
|
||||||
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ());
|
ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumSentBytes ());
|
||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
@ -669,30 +680,30 @@ namespace http {
|
|||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
/* commands */
|
/* commands */
|
||||||
s << "<b>Router Commands</b><br>\r\n<br>\r\n<div class=\"commands\">\r\n";
|
s << "<b>" << tr("Router commands") << "</b><br>\r\n<br>\r\n<div class=\"commands\">\r\n";
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">" << tr("Run peer test") << "</a>\r\n";
|
||||||
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
||||||
if (i2p::context.AcceptsTunnels ())
|
if (i2p::context.AcceptsTunnels ())
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">Decline transit tunnels</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_DISABLE_TRANSIT << "&token=" << token << "\">" << tr("Decline transit tunnels") << "</a>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">Accept transit tunnels</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_ENABLE_TRANSIT << "&token=" << token << "\">" << tr("Accept transit tunnels") << "</a>\r\n";
|
||||||
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
#if ((!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) || defined(ANDROID_BINARY))
|
||||||
if (Daemon.gracefulShutdownInterval)
|
if (Daemon.gracefulShutdownInterval)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Start graceful shutdown</a><br>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a><br>\r\n";
|
||||||
#elif defined(WIN32_APP)
|
#elif defined(WIN32_APP)
|
||||||
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">" << tr("Cancel graceful shutdown") << "</a>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">" << tr("Start graceful shutdown") << "</a>\r\n";
|
||||||
#endif
|
#endif
|
||||||
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a>\r\n";
|
s << " <a href=\"" << webroot << "?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">" << tr("Force shutdown") << "</a>\r\n";
|
||||||
s << "</div>";
|
s << "</div>";
|
||||||
|
|
||||||
s << "<br>\r\n<small><b>Note:</b> any action done here are not persistent and not changes your config files.</small>\r\n<br>\r\n";
|
s << "<br>\r\n<small>" << tr("<b>Note:</b> any action done here are not persistent and not changes your config files.") << "</small>\r\n<br>\r\n";
|
||||||
|
|
||||||
s << "<b>Logging level</b><br>\r\n";
|
s << "<b>" << tr("Logging level") << "</b><br>\r\n";
|
||||||
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
|
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=none&token=" << token << "\"> none </a> \r\n";
|
||||||
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </a> \r\n";
|
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=error&token=" << token << "\"> error </a> \r\n";
|
||||||
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \r\n";
|
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=warn&token=" << token << "\"> warn </a> \r\n";
|
||||||
@ -700,12 +711,12 @@ namespace http {
|
|||||||
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
|
s << " <a class=\"button\" href=\"" << webroot << "?cmd=" << HTTP_COMMAND_LOGLEVEL << "&level=debug&token=" << token << "\"> debug </a><br>\r\n<br>\r\n";
|
||||||
|
|
||||||
uint16_t maxTunnels = GetMaxNumTransitTunnels ();
|
uint16_t maxTunnels = GetMaxNumTransitTunnels ();
|
||||||
s << "<b>Transit tunnels limit</b><br>\r\n";
|
s << "<b>" << tr("Transit tunnels limit") << "</b><br>\r\n";
|
||||||
s << "<form method=\"get\" action=\"" << webroot << "\">\r\n";
|
s << "<form method=\"get\" action=\"" << webroot << "\">\r\n";
|
||||||
s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_LIMITTRANSIT << "\">\r\n";
|
s << " <input type=\"hidden\" name=\"cmd\" value=\"" << HTTP_COMMAND_LIMITTRANSIT << "\">\r\n";
|
||||||
s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n";
|
s << " <input type=\"hidden\" name=\"token\" value=\"" << token << "\">\r\n";
|
||||||
s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
|
s << " <input type=\"number\" min=\"0\" max=\"65535\" name=\"limit\" value=\"" << maxTunnels << "\">\r\n";
|
||||||
s << " <button type=\"submit\">Change</button>\r\n";
|
s << " <button type=\"submit\">" << tr("Change") << "</button>\r\n";
|
||||||
s << "</form>\r\n<br>\r\n";
|
s << "</form>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -713,7 +724,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
if(i2p::tunnel::tunnels.CountTransitTunnels())
|
if(i2p::tunnel::tunnels.CountTransitTunnels())
|
||||||
{
|
{
|
||||||
s << "<b>Transit tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Transit tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||||
{
|
{
|
||||||
s << "<div class=\"listitem\">\r\n";
|
s << "<div class=\"listitem\">\r\n";
|
||||||
@ -729,7 +740,7 @@ namespace http {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s << "<b>Transit tunnels:</b> no transit tunnels currently built.<br>\r\n";
|
s << "<b>" << tr("Transit tunnels") << ":</b> " << tr("no transit tunnels currently built") << ".<br>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +789,7 @@ namespace http {
|
|||||||
|
|
||||||
void ShowTransports (std::stringstream& s)
|
void ShowTransports (std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<b>Transports:</b><br>\r\n";
|
s << "<b>" << tr("Transports") << ":</b><br>\r\n";
|
||||||
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server ();
|
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server ();
|
||||||
if (ntcp2Server)
|
if (ntcp2Server)
|
||||||
{
|
{
|
||||||
@ -834,13 +845,13 @@ namespace http {
|
|||||||
auto sam = i2p::client::context.GetSAMBridge ();
|
auto sam = i2p::client::context.GetSAMBridge ();
|
||||||
if (!sam)
|
if (!sam)
|
||||||
{
|
{
|
||||||
ShowError(s, "SAM disabled");
|
ShowError(s, tr("SAM disabled"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sam->GetSessions ().size ())
|
if(sam->GetSessions ().size ())
|
||||||
{
|
{
|
||||||
s << "<b>SAM Sessions:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("SAM sessions") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: sam->GetSessions ())
|
for (auto& it: sam->GetSessions ())
|
||||||
{
|
{
|
||||||
auto& name = it.second->GetLocalDestination ()->GetNickname ();
|
auto& name = it.second->GetLocalDestination ()->GetNickname ();
|
||||||
@ -850,30 +861,30 @@ namespace http {
|
|||||||
s << "</div>\r\n";
|
s << "</div>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>SAM Sessions:</b> no sessions currently running.<br>\r\n";
|
s << "<b>" << tr("SAM sessions") << ":</b> " << tr("no sessions currently running") << ".<br>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowSAMSession (std::stringstream& s, const std::string& id)
|
void ShowSAMSession (std::stringstream& s, const std::string& id)
|
||||||
{
|
{
|
||||||
auto sam = i2p::client::context.GetSAMBridge ();
|
auto sam = i2p::client::context.GetSAMBridge ();
|
||||||
if (!sam) {
|
if (!sam) {
|
||||||
ShowError(s, "SAM disabled");
|
ShowError(s, tr("SAM disabled"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto session = sam->FindSession (id);
|
auto session = sam->FindSession (id);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
ShowError(s, "SAM session not found");
|
ShowError(s, tr("SAM session not found"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>SAM Session:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("SAM Session") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
auto& ident = session->GetLocalDestination ()->GetIdentHash();
|
auto& ident = session->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a></div>\r\n";
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a></div>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Streams:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Streams") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (const auto& it: sam->ListSockets(id))
|
for (const auto& it: sam->ListSockets(id))
|
||||||
{
|
{
|
||||||
s << "<div class=\"listitem\">";
|
s << "<div class=\"listitem\">";
|
||||||
@ -882,7 +893,7 @@ namespace http {
|
|||||||
case i2p::client::eSAMSocketTypeSession : s << "session"; break;
|
case i2p::client::eSAMSocketTypeSession : s << "session"; break;
|
||||||
case i2p::client::eSAMSocketTypeStream : s << "stream"; break;
|
case i2p::client::eSAMSocketTypeStream : s << "stream"; break;
|
||||||
case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break;
|
case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break;
|
||||||
case i2p::client::eSAMSocketTypeForward : s << "forward"; break;
|
case i2p::client::eSAMSocketTypeForward : s << "forward"; break;
|
||||||
default: s << "unknown"; break;
|
default: s << "unknown"; break;
|
||||||
}
|
}
|
||||||
s << " [" << it->GetSocket ().remote_endpoint() << "]";
|
s << " [" << it->GetSocket ().remote_endpoint() << "]";
|
||||||
@ -894,7 +905,7 @@ namespace http {
|
|||||||
void ShowI2PTunnels (std::stringstream& s)
|
void ShowI2PTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||||
s << "<b>Client Tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
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();
|
||||||
@ -908,7 +919,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << "HTTP Proxy" << "</a> ⇐ ";
|
s << "HTTP " << tr("Proxy") << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "</div>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
@ -917,7 +928,7 @@ namespace http {
|
|||||||
{
|
{
|
||||||
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << "SOCKS Proxy" << "</a> ⇐ ";
|
s << "SOCKS " << tr("Proxy") << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "</div>\r\n"<< std::endl;
|
s << "</div>\r\n"<< std::endl;
|
||||||
}
|
}
|
||||||
@ -925,7 +936,7 @@ namespace http {
|
|||||||
|
|
||||||
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
|
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
|
||||||
if (!serverTunnels.empty ()) {
|
if (!serverTunnels.empty ()) {
|
||||||
s << "<br>\r\n<b>Server Tunnels:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<br>\r\n<b>" << tr("Server Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: serverTunnels)
|
for (auto& it: serverTunnels)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
@ -941,7 +952,7 @@ namespace http {
|
|||||||
auto& clientForwards = i2p::client::context.GetClientForwards ();
|
auto& clientForwards = i2p::client::context.GetClientForwards ();
|
||||||
if (!clientForwards.empty ())
|
if (!clientForwards.empty ())
|
||||||
{
|
{
|
||||||
s << "<br>\r\n<b>Client Forwards:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<br>\r\n<b>" << tr("Client Forwards") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: clientForwards)
|
for (auto& it: clientForwards)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
@ -955,7 +966,7 @@ namespace http {
|
|||||||
auto& serverForwards = i2p::client::context.GetServerForwards ();
|
auto& serverForwards = i2p::client::context.GetServerForwards ();
|
||||||
if (!serverForwards.empty ())
|
if (!serverForwards.empty ())
|
||||||
{
|
{
|
||||||
s << "<br>\r\n<b>Server Forwards:</b><br>\r\n<div class=\"list\">\r\n";
|
s << "<br>\r\n<b>" << tr("Server Forwards") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||||
for (auto& it: serverForwards)
|
for (auto& it: serverForwards)
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
@ -1087,7 +1098,7 @@ namespace http {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Html5 head start
|
// HTML head start
|
||||||
ShowPageHead (s);
|
ShowPageHead (s);
|
||||||
if (req.uri.find("page=") != std::string::npos) {
|
if (req.uri.find("page=") != std::string::npos) {
|
||||||
HandlePage (req, res, s);
|
HandlePage (req, res, s);
|
||||||
@ -1161,7 +1172,7 @@ namespace http {
|
|||||||
ShowLeasesSets(s);
|
ShowLeasesSets(s);
|
||||||
else {
|
else {
|
||||||
res.code = 400;
|
res.code = 400;
|
||||||
ShowError(s, "Unknown page: " + page);
|
ShowError(s, tr("Unknown page") + ": " + page);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1180,7 +1191,7 @@ namespace http {
|
|||||||
|
|
||||||
if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ())
|
if (token.empty () || m_Tokens.find (std::stoi (token)) == m_Tokens.end ())
|
||||||
{
|
{
|
||||||
ShowError(s, "Invalid token");
|
ShowError(s, tr("Invalid token"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1238,18 +1249,18 @@ namespace http {
|
|||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
if(dest->DeleteStream (streamID))
|
if(dest->DeleteStream (streamID))
|
||||||
s << "<b>SUCCESS</b>: Stream closed<br>\r\n<br>\r\n";
|
s << "<b>" << tr("SUCCESS") << "</b>: " << tr("Stream closed") << "<br>\r\n<br>\r\n";
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Stream not found or already was closed<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Stream not found or already was closed") << "<br>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Destination not found<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Destination not found") << "<br>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: StreamID can be null<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("StreamID can't be null") << "<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">Return to destination page</a><br>\r\n";
|
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a><br>\r\n";
|
||||||
s << "<p>You will be redirected back in 5 seconds</b>";
|
s << "<p>" << tr("You will be redirected back in 5 seconds") << "</b>";
|
||||||
redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32;
|
redirect = "5; url=" + webroot + "?page=local_destination&b32=" + b32;
|
||||||
res.add_header("Refresh", redirect.c_str());
|
res.add_header("Refresh", redirect.c_str());
|
||||||
return;
|
return;
|
||||||
@ -1260,9 +1271,9 @@ namespace http {
|
|||||||
if (limit > 0 && limit <= 65535)
|
if (limit > 0 && limit <= 65535)
|
||||||
SetMaxNumTransitTunnels (limit);
|
SetMaxNumTransitTunnels (limit);
|
||||||
else {
|
else {
|
||||||
s << "<b>ERROR</b>: Transit tunnels count must not exceed 65535\r\n<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Transit tunnels count must not exceed 65535") << "\r\n<br>\r\n<br>\r\n";
|
||||||
s << "<a href=\"" << webroot << "?page=commands\">Back to commands list</a>\r\n<br>\r\n";
|
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a>\r\n<br>\r\n";
|
||||||
s << "<p>You will be redirected back in 5 seconds</b>";
|
s << "<p>" << tr("You will be redirected back in 5 seconds") << "</b>";
|
||||||
res.add_header("Refresh", redirect.c_str());
|
res.add_header("Refresh", redirect.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1295,37 +1306,37 @@ namespace http {
|
|||||||
auto len = i2p::data::ByteStreamToBase64 (signature, signatureLen, sig, signatureLen*2);
|
auto len = i2p::data::ByteStreamToBase64 (signature, signatureLen, sig, signatureLen*2);
|
||||||
sig[len] = 0;
|
sig[len] = 0;
|
||||||
out << "#!sig=" << sig;
|
out << "#!sig=" << sig;
|
||||||
s << "<b>SUCCESS</b>:<br>\r\n<form action=\"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/add\" method=\"post\" rel=\"noreferrer\" target=\"_blank\">\r\n"
|
s << "<b>" << tr("SUCCESS") << "</b>:<br>\r\n<form action=\"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/add\" method=\"post\" rel=\"noreferrer\" target=\"_blank\">\r\n"
|
||||||
"<textarea readonly name=\"record\" cols=\"80\" rows=\"10\">" << out.str () << "</textarea>\r\n<br>\r\n<br>\r\n"
|
"<textarea readonly name=\"record\" cols=\"80\" rows=\"10\">" << out.str () << "</textarea>\r\n<br>\r\n<br>\r\n"
|
||||||
"<b>Register at reg.i2p:</b>\r\n<br>\r\n"
|
"<b>" << tr("Register at reg.i2p") << ":</b>\r\n<br>\r\n"
|
||||||
"<b>Description:</b>\r\n<input type=\"text\" maxlength=\"64\" name=\"desc\" placeholder=\"A bit information about service on domain\">\r\n"
|
"<b>" << tr("Description") << ":</b>\r\n<input type=\"text\" maxlength=\"64\" name=\"desc\" placeholder=\"" << tr("A bit information about service on domain") << "\">\r\n"
|
||||||
"<input type=\"submit\" value=\"Submit\">\r\n"
|
"<input type=\"submit\" value=\"" << tr("Submit") << "\">\r\n"
|
||||||
"</form>\r\n<br>\r\n";
|
"</form>\r\n<br>\r\n";
|
||||||
delete[] signature;
|
delete[] signature;
|
||||||
delete[] sig;
|
delete[] sig;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Domain can't end with .b32.i2p\r\n<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Domain can't end with .b32.i2p") << "\r\n<br>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Domain must end with .i2p\r\n<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Domain must end with .i2p") << "\r\n<br>\r\n<br>\r\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
s << "<b>ERROR</b>: Such destination is not found\r\n<br>\r\n<br>\r\n";
|
s << "<b>" << tr("ERROR") << "</b>: " << tr("Such destination is not found") << "\r\n<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">Return to destination page</a>\r\n";
|
s << "<a href=\"" << webroot << "?page=local_destination&b32=" << b32 << "\">" << tr("Return to destination page") << "</a>\r\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res.code = 400;
|
res.code = 400;
|
||||||
ShowError(s, "Unknown command: " + cmd);
|
ShowError(s, tr("Unknown command") + ": " + cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s << "<b>SUCCESS</b>: Command accepted<br><br>\r\n";
|
s << "<b>" << tr("SUCCESS") << "</b>: " << tr("Command accepted") << "<br><br>\r\n";
|
||||||
s << "<a href=\"" << webroot << "?page=commands\">Back to commands list</a><br>\r\n";
|
s << "<a href=\"" << webroot << "?page=commands\">" << tr("Back to commands list") << "</a><br>\r\n";
|
||||||
s << "<p>You will be redirected in 5 seconds</b>";
|
s << "<p>" << tr("You will be redirected in 5 seconds") << "</b>";
|
||||||
res.add_header("Refresh", redirect.c_str());
|
res.add_header("Refresh", redirect.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,4 +19,6 @@ LIB_CLIENT_SRC = $(wildcard $(LIB_CLIENT_SRC_DIR)/*.cpp)
|
|||||||
#DAEMON_SRC = \
|
#DAEMON_SRC = \
|
||||||
# HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
|
# HTTPServer.cpp I2PControl.cpp UPnP.cpp Daemon.cpp i2pd.cpp
|
||||||
|
|
||||||
|
LANG_SRC = $(wildcard $(LANG_SRC_DIR)/*.cpp)
|
||||||
|
|
||||||
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
|
DAEMON_SRC = $(wildcard $(DAEMON_SRC_DIR)/*.cpp)
|
||||||
|
56
i18n/English.cpp
Normal file
56
i18n/English.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Russian localization file
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace i18n {
|
||||||
|
namespace english { // language
|
||||||
|
|
||||||
|
// See for language plural forms here:
|
||||||
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
|
int plural (int n) {
|
||||||
|
return n != 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> strings
|
||||||
|
{
|
||||||
|
{"Enabled", "Enabled"},
|
||||||
|
{"Disabled", "Disabled"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
|
{
|
||||||
|
{"days", {"day", "days"}},
|
||||||
|
{"hours", {"hour", "hours"}},
|
||||||
|
{"minutes", {"minute", "minutes"}},
|
||||||
|
{"seconds", {"second", "seconds"}}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetString (std::string arg)
|
||||||
|
{
|
||||||
|
auto it = strings.find(arg);
|
||||||
|
if (it == strings.end())
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetPlural (std::string arg, int n)
|
||||||
|
{
|
||||||
|
auto it = plurals.find(arg);
|
||||||
|
if (it == plurals.end())
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
int form = plural(n);
|
||||||
|
return it->second[form];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // language
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
48
i18n/I18N.h
Normal file
48
i18n/I18N.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __I18N_H__
|
||||||
|
#define __I18N_H__
|
||||||
|
|
||||||
|
#include "RouterContext.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace i18n {
|
||||||
|
|
||||||
|
inline std::string translate (std::string arg)
|
||||||
|
{
|
||||||
|
switch (i2p::context.GetLanguage ())
|
||||||
|
{
|
||||||
|
case eEnglish: return i2p::i18n::english::GetString (arg);
|
||||||
|
case eRussian: return i2p::i18n::russian::GetString (arg);
|
||||||
|
default: return arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename inttype>
|
||||||
|
std::string translate (std::string arg, inttype&& n)
|
||||||
|
{
|
||||||
|
switch (i2p::context.GetLanguage ())
|
||||||
|
{
|
||||||
|
case eEnglish: return i2p::i18n::english::GetPlural (arg, (int) n);
|
||||||
|
case eRussian: return i2p::i18n::russian::GetPlural (arg, (int) n);
|
||||||
|
default: return arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
||||||
|
|
||||||
|
template<typename... TArgs>
|
||||||
|
std::string tr (TArgs&&... args)
|
||||||
|
{
|
||||||
|
return i2p::i18n::translate(std::forward<TArgs>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __I18N_H__
|
34
i18n/I18N_langs.h
Normal file
34
i18n/I18N_langs.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __I18N_LANGS_H__
|
||||||
|
#define __I18N_LANGS_H__
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
|
||||||
|
enum Lang {
|
||||||
|
eEnglish = 0,
|
||||||
|
eRussian
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace i18n {
|
||||||
|
|
||||||
|
namespace english {
|
||||||
|
std::string GetString (std::string arg);
|
||||||
|
std::string GetPlural (std::string arg, int n);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace russian {
|
||||||
|
std::string GetString (std::string arg);
|
||||||
|
std::string GetPlural (std::string arg, int n);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
||||||
|
|
||||||
|
#endif // __I18N_LANGS_H__
|
247
i18n/Russian.cpp
Normal file
247
i18n/Russian.cpp
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Russian localization file
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace i18n {
|
||||||
|
namespace russian { // language
|
||||||
|
|
||||||
|
// See for language plural forms here:
|
||||||
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
|
int plural (int n) {
|
||||||
|
return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> strings
|
||||||
|
{
|
||||||
|
// HTTP Proxy
|
||||||
|
{"Proxy error", "Ошибка прокси"},
|
||||||
|
{"Proxy info", "Информация прокси"},
|
||||||
|
{"Proxy error: Host not found", "Ошибка прокси: Адрес не найден"},
|
||||||
|
{"Remote host not found in router's addressbook", "Запрошенный адрес не найден в адресной книге роутера"},
|
||||||
|
{"You may try to find this host on jump services below", "Вы можете попробовать найти адрес на джамп сервисах ниже"},
|
||||||
|
{"Invalid request", "Некорректный запрос"},
|
||||||
|
{"Proxy unable to parse your request", "Прокси не может разобрать ваш запрос"},
|
||||||
|
{"addresshelper is not supported", "addresshelper не поддерживается"},
|
||||||
|
{"Host", "Адрес"},
|
||||||
|
{"added to router's addressbook from helper", "добавлен в адресную книгу роутера через хелпер"},
|
||||||
|
{"already in router's addressbook", "уже а адресной книге роутера"},
|
||||||
|
{"Click", "Нажмите"},
|
||||||
|
{"here", "здесь"},
|
||||||
|
{"to proceed", "чтобы продолжить"},
|
||||||
|
{"to update record", "чтобы обновить запись"},
|
||||||
|
{"Addresshelper found", "Найден addresshelper"},
|
||||||
|
{"invalid request uri", "некорректный URI запроса"},
|
||||||
|
{"Can't detect destination host from request", "Не удалось определить адрес назначения из запроса"},
|
||||||
|
{"Outproxy failure", "Ошибка внешнего прокси"},
|
||||||
|
{"bad outproxy settings", "некорректные настройки внешнего прокси"},
|
||||||
|
{"not inside I2P network, but outproxy is not enabled", "не в I2P сети, но внешний прокси не включен"},
|
||||||
|
{"unknown outproxy url", "неизвестный URL внешнего прокси"},
|
||||||
|
{"cannot resolve upstream proxy", "не удается определить внешний прокси"},
|
||||||
|
{"hostname too long", "имя хоста слишком длинное"},
|
||||||
|
{"cannot connect to upstream socks proxy", "не удается подключиться к вышестоящему SOCKS прокси"},
|
||||||
|
{"Cannot negotiate with socks proxy", "Не удается договориться с вышестоящим SOCKS прокси"},
|
||||||
|
{"CONNECT error", "Ошибка CONNECT запроса"},
|
||||||
|
{"Failed to Connect", "Не удалось подключиться"},
|
||||||
|
{"socks proxy error", "ошибка SOCKS прокси"},
|
||||||
|
{"failed to send request to upstream", "не удалось отправить запрос вышестоящему прокси"},
|
||||||
|
{"No Reply From socks proxy", "Нет ответа от SOCKS прокси сервера"},
|
||||||
|
{"cannot connect", "не удалось подключиться"},
|
||||||
|
{"http out proxy not implemented", "поддержка внешнего HTTP прокси сервера не реализована"},
|
||||||
|
{"cannot connect to upstream http proxy", "не удалось подключиться к вышестоящему HTTP прокси серверу"},
|
||||||
|
{"Host is down", "Адрес недоступен"},
|
||||||
|
{"Can't create connection to requested host, it may be down. Please try again later.",
|
||||||
|
"Не удалось установить соединение к запрошенному адресу, возможно он не в сети. Попробуйте повторить запрос позже."},
|
||||||
|
|
||||||
|
// Webconsole //
|
||||||
|
// cssStyles
|
||||||
|
{"Disabled", "Выключено"},
|
||||||
|
{"Enabled", "Включено"},
|
||||||
|
// ShowTraffic
|
||||||
|
{"KiB", "КиБ"},
|
||||||
|
{"MiB", "МиБ"},
|
||||||
|
{"GiB", "ГиБ"},
|
||||||
|
// ShowTunnelDetails
|
||||||
|
{"building", "строится"},
|
||||||
|
{"failed", "неудачный"},
|
||||||
|
{"expiring", "истекает"},
|
||||||
|
{"established", "работает"},
|
||||||
|
{"exploratory", "исследовательский"},
|
||||||
|
{"unknown", "неизвестно"},
|
||||||
|
{"<b>i2pd</b> webconsole", "Веб-консоль <b>i2pd</b>"},
|
||||||
|
// ShowPageHead
|
||||||
|
{"Main page", "Главная"},
|
||||||
|
{"Router commands", "Команды роутера"},
|
||||||
|
{"Local destinations", "Локальные назнач."},
|
||||||
|
{"LeaseSets", "Лизсеты"},
|
||||||
|
{"Tunnels", "Туннели"},
|
||||||
|
{"Transit tunnels", "Транзит. туннели"},
|
||||||
|
{"Transports", "Транспорты"},
|
||||||
|
{"I2P tunnels", "I2P туннели"},
|
||||||
|
{"SAM sessions", "SAM сессии"},
|
||||||
|
// Network Status
|
||||||
|
{"OK", "OK"},
|
||||||
|
{"Testing", "Тестирование"},
|
||||||
|
{"Firewalled", "Файрвол"},
|
||||||
|
{"Unknown", "Неизвестно"},
|
||||||
|
{"Proxy", "Прокси"},
|
||||||
|
{"Mesh", "MESH-сеть"},
|
||||||
|
{"Error", "Ошибка"},
|
||||||
|
{"Clock skew", "Не точное время"},
|
||||||
|
{"Offline", "Оффлайн"},
|
||||||
|
{"Symmetric NAT", "Симметричный NAT"},
|
||||||
|
// Status
|
||||||
|
{"Uptime", "В сети"},
|
||||||
|
{"Network status", "Сетевой статус"},
|
||||||
|
{"Network status v6", "Сетевой статус v6"},
|
||||||
|
{"Stopping in", "Остановка через"},
|
||||||
|
{"Family", "Семейство"},
|
||||||
|
{"Tunnel creation success rate", "Успешно построенных туннелей"},
|
||||||
|
{"Received", "Получено"},
|
||||||
|
{"Sent", "Отправлено"},
|
||||||
|
{"Transit", "Транзит"},
|
||||||
|
{"KiB/s", "КиБ/с"},
|
||||||
|
{"Data path", "Путь к данным"},
|
||||||
|
{"Hidden content. Press on text to see.", "Скрытый контент. Нажмите на текст чтобы отобразить."},
|
||||||
|
{"Router Ident", "Идентификатор роутера"},
|
||||||
|
{"Router Family", "Семейство роутера"},
|
||||||
|
{"Router Caps", "Флаги роутера"},
|
||||||
|
{"Version", "Версия"},
|
||||||
|
{"Our external address", "Наш внешний адрес"},
|
||||||
|
{"supported", "поддерживается"},
|
||||||
|
{"Routers", "Роутеры"},
|
||||||
|
{"Floodfills", "Флудфилы"},
|
||||||
|
{"LeaseSets", "Лизсеты"},
|
||||||
|
{"Client Tunnels", "Клиентские туннели"},
|
||||||
|
{"Transit Tunnels", "Транзитные туннели"},
|
||||||
|
{"Services", "Сервисы"},
|
||||||
|
// ShowLocalDestinations
|
||||||
|
{"Local Destinations", "Локальные назначения"},
|
||||||
|
// ShowLeaseSetDestination
|
||||||
|
{"Encrypted B33 address", "Шифрованные B33 адреса"},
|
||||||
|
{"Address registration line", "Строка регистрации адреса"},
|
||||||
|
{"Domain", "Домен"},
|
||||||
|
{"Generate", "Сгенерировать"},
|
||||||
|
{"Address", "Адрес"},
|
||||||
|
{"Type", "Тип"},
|
||||||
|
{"EncType", "ТипШифр"},
|
||||||
|
{"Inbound tunnels", "Входящие туннели"},
|
||||||
|
{"Outbound tunnels", "Исходящие туннели"},
|
||||||
|
{"ms", "мс"}, // milliseconds
|
||||||
|
{"Tags", "Теги"},
|
||||||
|
{"Incoming", "Входящие"},
|
||||||
|
{"Outgoing", "Исходящие"},
|
||||||
|
{"Destination", "Назначение"},
|
||||||
|
{"Amount", "Количество"},
|
||||||
|
{"Incoming Tags", "Входящие Теги"},
|
||||||
|
{"Tags sessions", "Сессии Тегов"},
|
||||||
|
{"Status", "Статус"},
|
||||||
|
// ShowLocalDestination
|
||||||
|
{"Local Destination", "Локальное назначение"},
|
||||||
|
{"Streams", "Стримы"},
|
||||||
|
{"Close stream", "Закрыть стрим"},
|
||||||
|
// ShowI2CPLocalDestination
|
||||||
|
{"I2CP session not found", "I2CP сессия не найдена"},
|
||||||
|
{"I2CP is not enabled", "I2CP не включен"},
|
||||||
|
// ShowLeasesSets
|
||||||
|
{"Invalid", "Некорректный"},
|
||||||
|
{"Store type", "Тип хранилища"},
|
||||||
|
{"Expires", "Истекает"},
|
||||||
|
{"Non Expired Leases", "Не истекшие Lease-ы"},
|
||||||
|
{"Gateway", "Шлюз"},
|
||||||
|
{"TunnelID", "ID туннеля"},
|
||||||
|
{"EndDate", "Заканчивается"},
|
||||||
|
{"not floodfill", "не флудфил"},
|
||||||
|
// ShowTunnels
|
||||||
|
{"Queue size", "Размер очереди"},
|
||||||
|
// ShowCommands
|
||||||
|
{"Run peer test", "Запустить тестирование"},
|
||||||
|
{"Decline transit tunnels", "Отклонять транзитные туннели"},
|
||||||
|
{"Accept transit tunnels", "Принимать транзитные туннели"},
|
||||||
|
{"Cancel graceful shutdown", "Отменить плавную остановку"},
|
||||||
|
{"Start graceful shutdown", "Запустить плавную остановку"},
|
||||||
|
{"Force shutdown", "Принудительная остановка"},
|
||||||
|
{"<b>Note:</b> any action done here are not persistent and not changes your config files.",
|
||||||
|
"<b>Примечание:</b> любое действие произведенное здесь не является постоянным и не изменяет ваши конфигурационные файлы."},
|
||||||
|
{"Logging level", "Уровень логирования"},
|
||||||
|
{"Transit tunnels limit", "Лимит транзитных туннелей"},
|
||||||
|
{"Change", "Изменить"},
|
||||||
|
// ShowTransitTunnels
|
||||||
|
{"no transit tunnels currently built", "нет построенных транзитных туннелей"},
|
||||||
|
// ShowSAMSessions/ShowSAMSession
|
||||||
|
{"SAM disabled", "SAM выключен"},
|
||||||
|
{"SAM session not found", "SAM сессия не найдена"},
|
||||||
|
{"no sessions currently running", "нет запущенных сессий"},
|
||||||
|
{"SAM Session", "SAM сессия"},
|
||||||
|
// ShowI2PTunnels
|
||||||
|
{"Server Tunnels", "Серверные туннели"},
|
||||||
|
{"Client Forwards", "Клиентские переадресации"},
|
||||||
|
{"Server Forwards", "Серверные переадресации"},
|
||||||
|
// HandlePage
|
||||||
|
{"Unknown page", "Неизвестная страница"},
|
||||||
|
// HandleCommand, ShowError
|
||||||
|
{"Invalid token", "Неверный токен"},
|
||||||
|
{"SUCCESS", "УСПЕШНО"},
|
||||||
|
{"ERROR", "ОШИБКА"},
|
||||||
|
{"Unknown command", "Неизвестная команда"},
|
||||||
|
{"Command accepted", "Команда принята"},
|
||||||
|
{"Back to commands list", "Вернуться к списку команд"},
|
||||||
|
{"You will be redirected in 5 seconds", "Вы будете переадресованы через 5 секунд"},
|
||||||
|
// HTTP_COMMAND_KILLSTREAM
|
||||||
|
{"Stream closed", "Стрим закрыт"},
|
||||||
|
{"Stream not found or already was closed", "Стрим не найден или уже закрыт"},
|
||||||
|
{"Destination not found", "Точка назначения не найдена"},
|
||||||
|
{"StreamID can't be null", "StreamID не может быть пустым"},
|
||||||
|
{"Return to destination page", "Вернуться на страницу точки назначения"},
|
||||||
|
{"You will be redirected back in 5 seconds", "Вы будете переадресованы назад через 5 секунд"},
|
||||||
|
// HTTP_COMMAND_LIMITTRANSIT
|
||||||
|
{"Transit tunnels count must not exceed 65535", "Число транзитных туннелей не должно превышать 65535"},
|
||||||
|
// HTTP_COMMAND_GET_REG_STRING
|
||||||
|
{"Register at reg.i2p", "Зарегистрировать на reg.i2p"},
|
||||||
|
{"Description", "Описание"},
|
||||||
|
{"A bit information about service on domain", "Немного информации о сервисе на домене"},
|
||||||
|
{"Submit", "Отправить"},
|
||||||
|
{"Domain can't end with .b32.i2p", "Домен не может заканчиваться на .b32.i2p"},
|
||||||
|
{"Domain must end with .i2p", "Домен должен заканчиваться на .i2p"},
|
||||||
|
{"Such destination is not found", "Такая точка назначения не найдена"},
|
||||||
|
{"", ""},
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
|
{
|
||||||
|
// ShowUptime
|
||||||
|
{"days", {"день", "дня", "дней"}},
|
||||||
|
{"hours", {"час", "часа", "часов"}},
|
||||||
|
{"minutes", {"минуту", "минуты", "минут"}},
|
||||||
|
{"seconds", {"секунду", "секунды", "секунд"}},
|
||||||
|
{"", {"", ""}},
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetString (std::string arg)
|
||||||
|
{
|
||||||
|
auto it = strings.find(arg);
|
||||||
|
if (it == strings.end())
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetPlural (std::string arg, int n)
|
||||||
|
{
|
||||||
|
auto it = plurals.find(arg);
|
||||||
|
if (it == plurals.end())
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
int form = plural(n);
|
||||||
|
return it->second[form];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // language
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
@ -93,6 +93,7 @@ namespace config {
|
|||||||
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
||||||
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
||||||
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
|
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
|
||||||
|
("http.lang", value<std::string>()->default_value("english"), "WebUI language (default: english )")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description httpproxy("HTTP Proxy options");
|
options_description httpproxy("HTTP Proxy options");
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <codecvt>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
@ -41,16 +42,28 @@ namespace fs {
|
|||||||
return dataDir;
|
return dataDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string GetUTF8DataDir () {
|
||||||
|
#ifdef _WIN32
|
||||||
|
boost::filesystem::wpath path (dataDir);
|
||||||
|
auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) ); // convert path to UTF-8
|
||||||
|
auto dataDirUTF8 = path.string();
|
||||||
|
boost::filesystem::path::imbue(loc); // Return locale settings back
|
||||||
|
return dataDirUTF8;
|
||||||
|
#else
|
||||||
|
return dataDir; // linux, osx, android uses UTF-8 by default
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
||||||
if (cmdline_param != "") {
|
if (cmdline_param != "") {
|
||||||
dataDir = cmdline_param;
|
dataDir = cmdline_param;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char localAppData[MAX_PATH];
|
wchar_t localAppData[MAX_PATH];
|
||||||
|
|
||||||
// check executable directory first
|
// check executable directory first
|
||||||
if(!GetModuleFileName(NULL, localAppData, MAX_PATH))
|
if(!GetModuleFileNameW(NULL, localAppData, MAX_PATH))
|
||||||
{
|
{
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
MessageBox(NULL, TEXT("Unable to get application path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
||||||
@ -61,14 +74,15 @@ namespace fs {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto execPath = boost::filesystem::path(localAppData).parent_path();
|
auto execPath = boost::filesystem::wpath(localAppData).parent_path();
|
||||||
|
|
||||||
// if config file exists in .exe's folder use it
|
// if config file exists in .exe's folder use it
|
||||||
if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
|
if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string
|
||||||
dataDir = execPath.string ();
|
|
||||||
else // otherwise %appdata%
|
|
||||||
{
|
{
|
||||||
if(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
|
dataDir = execPath.string ();
|
||||||
|
} else // otherwise %appdata%
|
||||||
|
{
|
||||||
|
if(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, localAppData) != S_OK)
|
||||||
{
|
{
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
MessageBox(NULL, TEXT("Unable to get AppData path!"), TEXT("I2Pd: error"), MB_ICONERROR | MB_OK);
|
||||||
@ -78,7 +92,9 @@ namespace fs {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dataDir = std::string(localAppData) + "\\" + appName;
|
{
|
||||||
|
dataDir = boost::filesystem::wpath(localAppData).string() + "\\" + appName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -75,6 +75,9 @@ namespace fs {
|
|||||||
/** @brief Returns datadir path */
|
/** @brief Returns datadir path */
|
||||||
const std::string & GetDataDir();
|
const std::string & GetDataDir();
|
||||||
|
|
||||||
|
/** @brief Returns datadir path in UTF-8 encoding */
|
||||||
|
const std::string GetUTF8DataDir();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set datadir either from cmdline option or using autodetection
|
* @brief Set datadir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||||
|
@ -187,6 +187,8 @@ namespace http
|
|||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
for (const auto& it : tokens) {
|
for (const auto& it : tokens) {
|
||||||
|
if (!it.length()) // empty
|
||||||
|
continue;
|
||||||
std::size_t eq = it.find ('=');
|
std::size_t eq = it.find ('=');
|
||||||
if (eq != std::string::npos) {
|
if (eq != std::string::npos) {
|
||||||
auto e = std::pair<std::string, std::string>(it.substr(0, eq), it.substr(eq + 1));
|
auto e = std::pair<std::string, std::string>(it.substr(0, eq), it.substr(eq + 1));
|
||||||
|
@ -29,7 +29,7 @@ namespace i2p
|
|||||||
RouterContext::RouterContext ():
|
RouterContext::RouterContext ():
|
||||||
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
||||||
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
||||||
m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID)
|
m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID), m_Language (eEnglish)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,6 +916,11 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::SetLanguage (Lang language)
|
||||||
|
{
|
||||||
|
m_Language = language;
|
||||||
|
}
|
||||||
|
|
||||||
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
|
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
|
||||||
{
|
{
|
||||||
if (!m_StaticKeys)
|
if (!m_StaticKeys)
|
||||||
|
@ -18,13 +18,14 @@
|
|||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
#include "Garlic.h"
|
#include "Garlic.h"
|
||||||
|
#include "I18N_langs.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace garlic
|
namespace garlic
|
||||||
{
|
{
|
||||||
class RouterIncomingRatchetSession;
|
class RouterIncomingRatchetSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char ROUTER_INFO[] = "router.info";
|
const char ROUTER_INFO[] = "router.info";
|
||||||
const char ROUTER_KEYS[] = "router.keys";
|
const char ROUTER_KEYS[] = "router.keys";
|
||||||
@ -39,7 +40,7 @@ namespace garlic
|
|||||||
eRouterStatusError = 3,
|
eRouterStatusError = 3,
|
||||||
eRouterStatusUnknown = 4,
|
eRouterStatusUnknown = 4,
|
||||||
eRouterStatusProxy = 5,
|
eRouterStatusProxy = 5,
|
||||||
eRouterStatusMesh = 6
|
eRouterStatusMesh = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RouterError
|
enum RouterError
|
||||||
@ -49,7 +50,7 @@ namespace garlic
|
|||||||
eRouterErrorOffline = 2,
|
eRouterErrorOffline = 2,
|
||||||
eRouterErrorSymmetricNAT = 3
|
eRouterErrorSymmetricNAT = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
class RouterContext: public i2p::garlic::GarlicDestination
|
class RouterContext: public i2p::garlic::GarlicDestination
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -144,6 +145,10 @@ namespace garlic
|
|||||||
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
|
// i18n
|
||||||
|
Lang GetLanguage () const { return m_Language; };
|
||||||
|
void SetLanguage (Lang language);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// implements GarlicDestination
|
// implements GarlicDestination
|
||||||
@ -178,6 +183,9 @@ namespace garlic
|
|||||||
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
||||||
// for ECIESx25519
|
// for ECIESx25519
|
||||||
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState;
|
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState;
|
||||||
|
|
||||||
|
// i18n
|
||||||
|
Lang m_Language;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RouterContext context;
|
extern RouterContext context;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "I2PTunnel.h"
|
#include "I2PTunnel.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "HTTP.h"
|
#include "HTTP.h"
|
||||||
|
#include "I18N.h"
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace proxy {
|
namespace proxy {
|
||||||
@ -71,8 +72,8 @@ namespace proxy {
|
|||||||
void SentHTTPFailed(const boost::system::error_code & ecode);
|
void SentHTTPFailed(const boost::system::error_code & ecode);
|
||||||
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
|
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
|
||||||
/* error helpers */
|
/* error helpers */
|
||||||
void GenericProxyError(const char *title, const char *description);
|
void GenericProxyError(const std::string& title, const std::string& description);
|
||||||
void GenericProxyInfo(const char *title, const char *description);
|
void GenericProxyInfo(const std::string& title, const std::string& description);
|
||||||
void HostNotFound(std::string & host);
|
void HostNotFound(std::string & host);
|
||||||
void SendProxyError(std::string & content);
|
void SendProxyError(std::string & content);
|
||||||
|
|
||||||
@ -151,17 +152,17 @@ namespace proxy {
|
|||||||
Done(shared_from_this());
|
Done(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::GenericProxyError(const char *title, const char *description) {
|
void HTTPReqHandler::GenericProxyError(const std::string& title, const std::string& description) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "<h1>Proxy error: " << title << "</h1>\r\n";
|
ss << "<h1>" << tr("Proxy error") << ": " << title << "</h1>\r\n";
|
||||||
ss << "<p>" << description << "</p>\r\n";
|
ss << "<p>" << description << "</p>\r\n";
|
||||||
std::string content = ss.str();
|
std::string content = ss.str();
|
||||||
SendProxyError(content);
|
SendProxyError(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::GenericProxyInfo(const char *title, const char *description) {
|
void HTTPReqHandler::GenericProxyInfo(const std::string& title, const std::string& description) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "<h1>Proxy info: " << title << "</h1>\r\n";
|
ss << "<h1>" << tr("Proxy info") << ": " << title << "</h1>\r\n";
|
||||||
ss << "<p>" << description << "</p>\r\n";
|
ss << "<p>" << description << "</p>\r\n";
|
||||||
std::string content = ss.str();
|
std::string content = ss.str();
|
||||||
SendProxyError(content);
|
SendProxyError(content);
|
||||||
@ -169,9 +170,9 @@ namespace proxy {
|
|||||||
|
|
||||||
void HTTPReqHandler::HostNotFound(std::string & host) {
|
void HTTPReqHandler::HostNotFound(std::string & host) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "<h1>Proxy error: Host not found</h1>\r\n"
|
ss << "<h1>" << tr("Proxy error: Host not found") << "</h1>\r\n"
|
||||||
<< "<p>Remote host not found in router's addressbook</p>\r\n"
|
<< "<p>" << tr("Remote host not found in router's addressbook") << "</p>\r\n"
|
||||||
<< "<p>You may try to find this host on jump services below:</p>\r\n"
|
<< "<p>" << tr("You may try to find this host on jump services below") << ":</p>\r\n"
|
||||||
<< "<ul>\r\n";
|
<< "<ul>\r\n";
|
||||||
for (const auto& js : jumpservices) {
|
for (const auto& js : jumpservices) {
|
||||||
ss << " <li><a href=\"" << js.second << host << "\">" << js.first << "</a></li>\r\n";
|
ss << " <li><a href=\"" << js.second << host << "\">" << js.first << "</a></li>\r\n";
|
||||||
@ -216,6 +217,7 @@ namespace proxy {
|
|||||||
b64 = i2p::http::UrlDecode(value);
|
b64 = i2p::http::UrlDecode(value);
|
||||||
// if we need update exists, request formed with update param
|
// if we need update exists, request formed with update param
|
||||||
if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; }
|
if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; }
|
||||||
|
if (pos != 0 && url.query[pos-1] == '&') { pos--; len++; } // if helper is not only one query option
|
||||||
url.query.replace(pos, len, "");
|
url.query.replace(pos, len, "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -268,7 +270,7 @@ namespace proxy {
|
|||||||
|
|
||||||
if (m_req_len < 0) {
|
if (m_req_len < 0) {
|
||||||
LogPrint(eLogError, "HTTPProxy: unable to parse request");
|
LogPrint(eLogError, "HTTPProxy: unable to parse request");
|
||||||
GenericProxyError("Invalid request", "Proxy unable to parse your request");
|
GenericProxyError(tr("Invalid request"), tr("Proxy unable to parse your request"));
|
||||||
return true; /* parse error */
|
return true; /* parse error */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +285,7 @@ namespace proxy {
|
|||||||
if (!m_Addresshelper)
|
if (!m_Addresshelper)
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "HTTPProxy: addresshelper request rejected");
|
LogPrint(eLogWarning, "HTTPProxy: addresshelper request rejected");
|
||||||
GenericProxyError("Invalid request", "addresshelper is not supported");
|
GenericProxyError(tr("Invalid request"), tr("addresshelper is not supported"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm)
|
if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm)
|
||||||
@ -292,17 +294,19 @@ namespace proxy {
|
|||||||
LogPrint (eLogInfo, "HTTPProxy: added address from addresshelper for ", m_RequestURL.host);
|
LogPrint (eLogInfo, "HTTPProxy: added address from addresshelper for ", m_RequestURL.host);
|
||||||
std::string full_url = m_RequestURL.to_string();
|
std::string full_url = m_RequestURL.to_string();
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Host " << m_RequestURL.host << " added to router's addressbook from helper. "
|
ss << tr("Host") <<" " << m_RequestURL.host << " " << tr("added to router's addressbook from helper") << ". ";
|
||||||
<< "Click <a href=\"" << full_url << "\">here</a> to proceed.";
|
ss << tr("Click") << " <a href=\"" << full_url << "\">" << tr("here") << "</a> " << tr("to proceed") << ".";
|
||||||
GenericProxyInfo("Addresshelper found", ss.str().c_str());
|
GenericProxyInfo(tr("Addresshelper found"), ss.str());
|
||||||
return true; /* request processed */
|
return true; /* request processed */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
std::string full_url = m_RequestURL.to_string();
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Host " << m_RequestURL.host << " <font color=red>already in router's addressbook</font>. "
|
ss << tr("Host") << " " << m_RequestURL.host << " <font color=red>" << tr("already in router's addressbook") << "</font>. ";
|
||||||
<< "Click <a href=\"" << m_RequestURL.query << "?i2paddresshelper=" << jump << "&update=true\">here</a> to update record.";
|
ss << tr("Click") << " <a href=\"" << full_url << (full_url.find('?') != std::string::npos ? "&i2paddresshelper=" : "?i2paddresshelper=");
|
||||||
GenericProxyInfo("Addresshelper found", ss.str().c_str());
|
ss << jump << "&update=true\">" << tr("here") << "</a> " << tr("to update record") << ".";
|
||||||
|
GenericProxyInfo(tr("Addresshelper found"), ss.str());
|
||||||
return true; /* request processed */
|
return true; /* request processed */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,7 +319,7 @@ namespace proxy {
|
|||||||
auto pos = uri.find(":");
|
auto pos = uri.find(":");
|
||||||
if(pos == std::string::npos || pos == uri.size() - 1)
|
if(pos == std::string::npos || pos == uri.size() - 1)
|
||||||
{
|
{
|
||||||
GenericProxyError("Invalid Request", "invalid request uri");
|
GenericProxyError(tr("Invalid Request"), tr("invalid request uri"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -358,7 +362,7 @@ namespace proxy {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* relative url and missing 'Host' header */
|
/* relative url and missing 'Host' header */
|
||||||
GenericProxyError("Invalid request", "Can't detect destination host from request");
|
GenericProxyError(tr("Invalid request"), tr("Can't detect destination host from request"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,11 +379,11 @@ namespace proxy {
|
|||||||
if(m_ProxyURL.parse(m_OutproxyUrl))
|
if(m_ProxyURL.parse(m_OutproxyUrl))
|
||||||
ForwardToUpstreamProxy();
|
ForwardToUpstreamProxy();
|
||||||
else
|
else
|
||||||
GenericProxyError("Outproxy failure", "bad outproxy settings");
|
GenericProxyError(tr("Outproxy failure"), tr("bad outproxy settings"));
|
||||||
} else {
|
} else {
|
||||||
LogPrint (eLogWarning, "HTTPProxy: outproxy failure for ", dest_host, ": no outproxy enabled");
|
LogPrint (eLogWarning, "HTTPProxy: outproxy failure for ", dest_host, ": no outproxy enabled");
|
||||||
std::string message = "Host " + dest_host + " not inside I2P network, but outproxy is not enabled";
|
std::stringstream ss; ss << tr("Host") << " " << dest_host << " " << tr("not inside I2P network, but outproxy is not enabled");
|
||||||
GenericProxyError("Outproxy failure", message.c_str());
|
GenericProxyError(tr("Outproxy failure"), ss.str());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -467,13 +471,13 @@ namespace proxy {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unknown type, complain
|
// unknown type, complain
|
||||||
GenericProxyError("unknown outproxy url", m_ProxyURL.to_string().c_str());
|
GenericProxyError(tr("unknown outproxy url"), m_ProxyURL.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler)
|
void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler)
|
||||||
{
|
{
|
||||||
if(ec) GenericProxyError("cannot resolve upstream proxy", ec.message().c_str());
|
if(ec) GenericProxyError(tr("cannot resolve upstream proxy"), ec.message());
|
||||||
else handler(*it);
|
else handler(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +485,7 @@ namespace proxy {
|
|||||||
{
|
{
|
||||||
if(!ec) {
|
if(!ec) {
|
||||||
if(m_RequestURL.host.size() > 255) {
|
if(m_RequestURL.host.size() > 255) {
|
||||||
GenericProxyError("hostname too long", m_RequestURL.host.c_str());
|
GenericProxyError(tr("hostname too long"), m_RequestURL.host);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t port = m_RequestURL.port;
|
uint16_t port = m_RequestURL.port;
|
||||||
@ -508,13 +512,13 @@ namespace proxy {
|
|||||||
reqsize += host.size();
|
reqsize += host.size();
|
||||||
m_socks_buf[++reqsize] = 0;
|
m_socks_buf[++reqsize] = 0;
|
||||||
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2));
|
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_socks_buf, reqsize), boost::asio::transfer_all(), std::bind(&HTTPReqHandler::HandleSocksProxySendHandshake, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
} else GenericProxyError("cannot connect to upstream socks proxy", ec.message().c_str());
|
} else GenericProxyError(tr("cannot connect to upstream socks proxy"), ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred)
|
void HTTPReqHandler::HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "HTTPProxy: upstream socks handshake sent");
|
LogPrint(eLogDebug, "HTTPProxy: upstream socks handshake sent");
|
||||||
if(ec) GenericProxyError("Cannot negotiate with socks proxy", ec.message().c_str());
|
if(ec) GenericProxyError(tr("Cannot negotiate with socks proxy"), ec.message());
|
||||||
else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2));
|
else m_proxysock->async_read_some(boost::asio::buffer(m_socks_buf, 8), std::bind(&HTTPReqHandler::HandleSocksProxyReply, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,7 +560,7 @@ namespace proxy {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GenericProxyError("CONNECT error", "Failed to Connect");
|
GenericProxyError(tr("CONNECT error"), tr("Failed to Connect"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,7 +571,7 @@ namespace proxy {
|
|||||||
m_send_buf = m_ClientResponse.to_string();
|
m_send_buf = m_ClientResponse.to_string();
|
||||||
boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred)
|
boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred)
|
||||||
{
|
{
|
||||||
if(ec) GenericProxyError("socks proxy error", ec.message().c_str());
|
if(ec) GenericProxyError(tr("socks proxy error"), ec.message());
|
||||||
else HandoverToUpstreamProxy();
|
else HandoverToUpstreamProxy();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -575,7 +579,7 @@ namespace proxy {
|
|||||||
LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes");
|
LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes");
|
||||||
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred)
|
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred)
|
||||||
{
|
{
|
||||||
if(ec) GenericProxyError("failed to send request to upstream", ec.message().c_str());
|
if(ec) GenericProxyError(tr("failed to send request to upstream"), ec.message());
|
||||||
else HandoverToUpstreamProxy();
|
else HandoverToUpstreamProxy();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -593,18 +597,18 @@ namespace proxy {
|
|||||||
ss << "error code: ";
|
ss << "error code: ";
|
||||||
ss << (int) m_socks_buf[1];
|
ss << (int) m_socks_buf[1];
|
||||||
std::string msg = ss.str();
|
std::string msg = ss.str();
|
||||||
GenericProxyError("Socks Proxy error", msg.c_str());
|
GenericProxyError(tr("socks proxy error"), msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else GenericProxyError("No Reply From socks proxy", ec.message().c_str());
|
else GenericProxyError(tr("No Reply From socks proxy"), ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec)
|
void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec)
|
||||||
{
|
{
|
||||||
if(!ec) {
|
if(!ec) {
|
||||||
LogPrint(eLogDebug, "HTTPProxy: connected to http upstream");
|
LogPrint(eLogDebug, "HTTPProxy: connected to http upstream");
|
||||||
GenericProxyError("cannot connect", "http out proxy not implemented");
|
GenericProxyError(tr("cannot connect"), tr("http out proxy not implemented"));
|
||||||
} else GenericProxyError("cannot connect to upstream http proxy", ec.message().c_str());
|
} else GenericProxyError(tr("cannot connect to upstream http proxy"), ec.message());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* will be called after some data received from client */
|
/* will be called after some data received from client */
|
||||||
@ -637,7 +641,7 @@ namespace proxy {
|
|||||||
{
|
{
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
|
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
|
||||||
GenericProxyError("Host is down", "Can't create connection to requested host, it may be down. Please try again later.");
|
GenericProxyError(tr("Host is down"), tr("Can't create connection to requested host, it may be down. Please try again later."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Kill())
|
if (Kill())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user