mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 11:04:00 +01:00
add graceful shutdown in webconsole for windows
add stop graceful shutdown menu item add reload menu item
This commit is contained in:
parent
5e0d4163a2
commit
dd4f066e95
|
@ -14,99 +14,99 @@
|
|||
|
||||
namespace i2p
|
||||
{
|
||||
namespace util
|
||||
namespace util
|
||||
{
|
||||
bool DaemonWin32::init(int argc, char* argv[])
|
||||
{
|
||||
bool DaemonWin32::init(int argc, char* argv[])
|
||||
setlocale(LC_CTYPE, "");
|
||||
SetConsoleCP(1251);
|
||||
SetConsoleOutputCP(1251);
|
||||
setlocale(LC_ALL, "Russian");
|
||||
|
||||
if (!Daemon_Singleton::init(argc, argv))
|
||||
return false;
|
||||
|
||||
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
|
||||
if (serviceControl == "install")
|
||||
{
|
||||
setlocale(LC_CTYPE, "");
|
||||
SetConsoleCP(1251);
|
||||
SetConsoleOutputCP(1251);
|
||||
setlocale(LC_ALL, "Russian");
|
||||
|
||||
if (!Daemon_Singleton::init(argc, argv))
|
||||
return false;
|
||||
|
||||
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
|
||||
if (serviceControl == "install")
|
||||
{
|
||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
||||
InstallService(
|
||||
SERVICE_NAME, // Name of service
|
||||
SERVICE_DISPLAY_NAME, // Name to display
|
||||
SERVICE_START_TYPE, // Service start type
|
||||
SERVICE_DEPENDENCIES, // Dependencies
|
||||
SERVICE_ACCOUNT, // Service running account
|
||||
SERVICE_PASSWORD // Password of the account
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else if (serviceControl == "remove")
|
||||
{
|
||||
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
|
||||
UninstallService(SERVICE_NAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isDaemon)
|
||||
{
|
||||
LogPrint(eLogDebug, "Daemon: running as service");
|
||||
I2PService service(SERVICE_NAME);
|
||||
if (!I2PService::Run(service))
|
||||
{
|
||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
LogPrint(eLogDebug, "Daemon: running as user");
|
||||
return true;
|
||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
||||
InstallService(
|
||||
SERVICE_NAME, // Name of service
|
||||
SERVICE_DISPLAY_NAME, // Name to display
|
||||
SERVICE_START_TYPE, // Service start type
|
||||
SERVICE_DEPENDENCIES, // Dependencies
|
||||
SERVICE_ACCOUNT, // Service running account
|
||||
SERVICE_PASSWORD // Password of the account
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else if (serviceControl == "remove")
|
||||
{
|
||||
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
|
||||
UninstallService(SERVICE_NAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DaemonWin32::start()
|
||||
if (isDaemon)
|
||||
{
|
||||
setlocale(LC_CTYPE, "");
|
||||
SetConsoleCP(1251);
|
||||
SetConsoleOutputCP(1251);
|
||||
setlocale(LC_ALL, "Russian");
|
||||
#ifdef WIN32_APP
|
||||
if (!i2p::win32::StartWin32App ()) return false;
|
||||
LogPrint(eLogDebug, "Daemon: running as service");
|
||||
I2PService service(SERVICE_NAME);
|
||||
if (!I2PService::Run(service))
|
||||
{
|
||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
LogPrint(eLogDebug, "Daemon: running as user");
|
||||
return true;
|
||||
}
|
||||
|
||||
// override log
|
||||
i2p::config::SetOption("log", std::string ("file"));
|
||||
bool DaemonWin32::start()
|
||||
{
|
||||
setlocale(LC_CTYPE, "");
|
||||
SetConsoleCP(1251);
|
||||
SetConsoleOutputCP(1251);
|
||||
setlocale(LC_ALL, "Russian");
|
||||
#ifdef WIN32_APP
|
||||
if (!i2p::win32::StartWin32App ()) return false;
|
||||
|
||||
// override log
|
||||
i2p::config::SetOption("log", std::string ("file"));
|
||||
#endif
|
||||
bool ret = Daemon_Singleton::start();
|
||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
||||
{
|
||||
// TODO: find out where this garbage to console comes from
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
|
||||
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
|
||||
}
|
||||
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
|
||||
if (insomnia)
|
||||
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DaemonWin32::stop()
|
||||
bool ret = Daemon_Singleton::start();
|
||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
||||
{
|
||||
// TODO: find out where this garbage to console comes from
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
|
||||
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
|
||||
}
|
||||
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
|
||||
if (insomnia)
|
||||
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DaemonWin32::stop()
|
||||
{
|
||||
#ifdef WIN32_APP
|
||||
i2p::win32::StopWin32App ();
|
||||
i2p::win32::StopWin32App ();
|
||||
#endif
|
||||
return Daemon_Singleton::stop();
|
||||
}
|
||||
return Daemon_Singleton::stop();
|
||||
}
|
||||
|
||||
void DaemonWin32::run ()
|
||||
{
|
||||
void DaemonWin32::run ()
|
||||
{
|
||||
#ifdef WIN32_APP
|
||||
i2p::win32::RunWin32App ();
|
||||
i2p::win32::RunWin32App ();
|
||||
#else
|
||||
while (running)
|
||||
while (running)
|
||||
{
|
||||
std::this_thread::sleep_for (std::chrono::seconds(1));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "Tunnel.h"
|
||||
#include "version.h"
|
||||
#include "resource.h"
|
||||
#include "Daemon.h"
|
||||
#include "Win32App.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -21,6 +22,8 @@
|
|||
#define ID_CONSOLE 2002
|
||||
#define ID_APP 2003
|
||||
#define ID_GRACEFUL_SHUTDOWN 2004
|
||||
#define ID_STOP_GRACEFUL_SHUTDOWN 2005
|
||||
#define ID_RELOAD 2006
|
||||
|
||||
#define ID_TRAY_ICON 2050
|
||||
#define WM_TRAYICON (WM_USER + 1)
|
||||
|
@ -39,7 +42,11 @@ namespace win32
|
|||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs");
|
||||
if (!i2p::util::DaemonWin32::Instance ().isGraceful)
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown");
|
||||
else
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "&Stop graceful shutdown");
|
||||
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
|
||||
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
|
||||
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
|
||||
|
@ -68,7 +75,7 @@ namespace win32
|
|||
nid.uCallbackMessage = WM_TRAYICON;
|
||||
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
|
||||
strcpy (nid.szTip, "i2pd");
|
||||
strcpy (nid.szInfo, "i2pd is running");
|
||||
strcpy (nid.szInfo, "i2pd is starting");
|
||||
Shell_NotifyIcon(NIM_ADD, &nid );
|
||||
}
|
||||
|
||||
|
@ -120,6 +127,7 @@ namespace win32
|
|||
|
||||
static void PrintMainWindowText (std::stringstream& s)
|
||||
{
|
||||
s << "\n";
|
||||
s << "Status: ";
|
||||
switch (i2p::context.GetStatus())
|
||||
{
|
||||
|
@ -153,6 +161,7 @@ namespace win32
|
|||
s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; ";
|
||||
s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; ";
|
||||
s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n";
|
||||
s << "\n";
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -192,6 +201,22 @@ namespace win32
|
|||
{
|
||||
i2p::context.SetAcceptsTunnels (false);
|
||||
SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes
|
||||
i2p::util::DaemonWin32::Instance ().isGraceful = true;
|
||||
return 0;
|
||||
}
|
||||
case ID_STOP_GRACEFUL_SHUTDOWN:
|
||||
{
|
||||
i2p::context.SetAcceptsTunnels (true);
|
||||
KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER);
|
||||
i2p::util::DaemonWin32::Instance ().isGraceful = false;
|
||||
return 0;
|
||||
}
|
||||
case ID_RELOAD:
|
||||
{
|
||||
i2p::client::context.ReloadConfig();
|
||||
std::stringstream text;
|
||||
text << "I2Pd reloading configs...";
|
||||
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
|
||||
return 0;
|
||||
}
|
||||
case ID_CONSOLE:
|
||||
|
@ -322,7 +347,7 @@ namespace win32
|
|||
wclx.lpszClassName = I2PD_WIN32_CLASSNAME;
|
||||
RegisterClassEx (&wclx);
|
||||
// create new window
|
||||
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 180, NULL, NULL, hInst, NULL))
|
||||
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL))
|
||||
{
|
||||
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
|
||||
return false;
|
||||
|
@ -353,5 +378,14 @@ namespace win32
|
|||
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0);
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
bool StopGracefulShutdown ()
|
||||
{
|
||||
HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd"));
|
||||
if (hWnd)
|
||||
PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0);
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,11 @@ namespace i2p
|
|||
{
|
||||
namespace win32
|
||||
{
|
||||
bool StartWin32App ();
|
||||
void StopWin32App ();
|
||||
int RunWin32App ();
|
||||
bool GracefulShutdown ();
|
||||
bool StartWin32App ();
|
||||
void StopWin32App ();
|
||||
int RunWin32App ();
|
||||
bool GracefulShutdown ();
|
||||
bool StopGracefulShutdown ();
|
||||
}
|
||||
}
|
||||
#endif // WIN32APP_H__
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
namespace i2p
|
||||
{
|
||||
namespace util
|
||||
namespace util
|
||||
{
|
||||
class Daemon_Singleton_Private;
|
||||
class Daemon_Singleton
|
||||
{
|
||||
class Daemon_Singleton_Private;
|
||||
class Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
virtual bool init(int argc, char* argv[]);
|
||||
virtual bool start();
|
||||
|
@ -29,40 +29,38 @@ namespace i2p
|
|||
// d-pointer for httpServer, httpProxy, etc.
|
||||
class Daemon_Singleton_Private;
|
||||
Daemon_Singleton_Private &d;
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(QT_GUI_LIB) // check if QT
|
||||
#define Daemon i2p::util::DaemonQT::Instance()
|
||||
// dummy, invoked from RunQT
|
||||
class DaemonQT: public i2p::util::Daemon_Singleton
|
||||
class DaemonQT: public i2p::util::Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
|
||||
static DaemonQT& Instance()
|
||||
{
|
||||
static DaemonQT instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#elif defined(ANDROID)
|
||||
#define Daemon i2p::util::DaemonAndroid::Instance()
|
||||
// dummy, invoked from android/jni/DaemonAndroid.*
|
||||
class DaemonAndroid: public i2p::util::Daemon_Singleton
|
||||
class DaemonAndroid: public i2p::util::Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
|
||||
static DaemonAndroid& Instance()
|
||||
{
|
||||
static DaemonAndroid instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#define Daemon i2p::util::DaemonWin32::Instance()
|
||||
class DaemonWin32 : public Daemon_Singleton
|
||||
{
|
||||
class DaemonWin32 : public Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
static DaemonWin32& Instance()
|
||||
{
|
||||
|
@ -74,34 +72,36 @@ namespace i2p
|
|||
bool start();
|
||||
bool stop();
|
||||
void run ();
|
||||
};
|
||||
|
||||
bool isGraceful;
|
||||
|
||||
DaemonWin32 ():isGraceful(false) {}
|
||||
};
|
||||
|
||||
#else
|
||||
#define Daemon i2p::util::DaemonLinux::Instance()
|
||||
class DaemonLinux : public Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
static DaemonLinux& Instance()
|
||||
{
|
||||
static DaemonLinux instance;
|
||||
return instance;
|
||||
}
|
||||
class DaemonLinux : public Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
static DaemonLinux& Instance()
|
||||
{
|
||||
static DaemonLinux instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
void run ();
|
||||
bool start();
|
||||
bool stop();
|
||||
void run ();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string pidfile;
|
||||
int pidFH;
|
||||
|
||||
std::string pidfile;
|
||||
int pidFH;
|
||||
|
||||
public:
|
||||
|
||||
int gracefulShutdownInterval; // in seconds
|
||||
|
||||
};
|
||||
public:
|
||||
int gracefulShutdownInterval; // in seconds
|
||||
};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DAEMON_H__
|
||||
|
|
|
@ -58,9 +58,9 @@ namespace http {
|
|||
" .left { float: left; position: absolute; }\r\n"
|
||||
" .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\r\n"
|
||||
" .tunnel.established { color: #56B734; }\r\n"
|
||||
" .tunnel.expiring { color: #D3AE3F; }\r\n"
|
||||
" .tunnel.failed { color: #D33F3F; }\r\n"
|
||||
" .tunnel.another { color: #434343; }\r\n"
|
||||
" .tunnel.expiring { color: #D3AE3F; }\r\n"
|
||||
" .tunnel.failed { color: #D33F3F; }\r\n"
|
||||
" .tunnel.another { color: #434343; }\r\n"
|
||||
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
||||
" table { width: 100%; border-collapse: collapse; text-align: center; }\r\n"
|
||||
" .private { background: black; color: black; } .private:hover { background: black; color: white } \r\n"
|
||||
|
@ -125,11 +125,11 @@ namespace http {
|
|||
std::string state;
|
||||
switch (eState) {
|
||||
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::eTunnelStateTestFailed :
|
||||
case i2p::tunnel::eTunnelStateFailed : state = "failed"; break;
|
||||
case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break;
|
||||
case i2p::tunnel::eTunnelStateFailed : state = "failed"; break;
|
||||
case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break;
|
||||
case i2p::tunnel::eTunnelStateEstablished : state = "established"; break;
|
||||
default: state = "unknown"; break;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ namespace http {
|
|||
s << "<b>ERROR:</b> " << string << "<br>\r\n";
|
||||
}
|
||||
|
||||
void ShowStatus (std::stringstream& s, bool includeHiddenContent)
|
||||
void ShowStatus (std::stringstream& s, bool includeHiddenContent)
|
||||
{
|
||||
s << "<b>Uptime:</b> ";
|
||||
ShowUptime(s, i2p::context.GetUptime ());
|
||||
|
@ -233,35 +233,35 @@ namespace http {
|
|||
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
|
||||
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
|
||||
s << "<div class='slide'\r\n><label for='slide1'>Hidden content. Press on text to see.</label>\r\n<input type='checkbox' id='slide1'/>\r\n<p class='content'>\r\n";
|
||||
if(includeHiddenContent) {
|
||||
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
|
||||
s << "<b>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>Our external address:</b>" << "<br>\r\n" ;
|
||||
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
||||
{
|
||||
switch (address->transportStyle)
|
||||
{
|
||||
case i2p::data::RouterInfo::eTransportNTCP:
|
||||
if (address->host.is_v6 ())
|
||||
s << "NTCP6 ";
|
||||
else
|
||||
s << "NTCP ";
|
||||
break;
|
||||
case i2p::data::RouterInfo::eTransportSSU:
|
||||
if (address->host.is_v6 ())
|
||||
s << "SSU6 ";
|
||||
else
|
||||
s << "SSU ";
|
||||
break;
|
||||
default:
|
||||
s << "Unknown ";
|
||||
}
|
||||
s << address->host.to_string() << ":" << address->port << "<br>\r\n";
|
||||
}
|
||||
}
|
||||
s << "</p>\r\n</div>\r\n";
|
||||
s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
||||
if(includeHiddenContent) {
|
||||
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
|
||||
s << "<b>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>Our external address:</b>" << "<br>\r\n" ;
|
||||
for (const auto& address : i2p::context.GetRouterInfo().GetAddresses())
|
||||
{
|
||||
switch (address->transportStyle)
|
||||
{
|
||||
case i2p::data::RouterInfo::eTransportNTCP:
|
||||
if (address->host.is_v6 ())
|
||||
s << "NTCP6 ";
|
||||
else
|
||||
s << "NTCP ";
|
||||
break;
|
||||
case i2p::data::RouterInfo::eTransportSSU:
|
||||
if (address->host.is_v6 ())
|
||||
s << "SSU6 ";
|
||||
else
|
||||
s << "SSU ";
|
||||
break;
|
||||
default:
|
||||
s << "Unknown ";
|
||||
}
|
||||
s << address->host.to_string() << ":" << address->port << "<br>\r\n";
|
||||
}
|
||||
}
|
||||
s << "</p>\r\n</div>\r\n";
|
||||
s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
||||
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
|
||||
s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
|
||||
|
||||
|
@ -273,7 +273,7 @@ namespace http {
|
|||
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n";
|
||||
}
|
||||
|
||||
void ShowLocalDestinations (std::stringstream& s)
|
||||
void ShowLocalDestinations (std::stringstream& s)
|
||||
{
|
||||
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n";
|
||||
for (auto& it: i2p::client::context.GetDestinations ())
|
||||
|
@ -341,7 +341,7 @@ namespace http {
|
|||
s << "<br>" << std::endl;
|
||||
}
|
||||
|
||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32)
|
||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32)
|
||||
{
|
||||
s << "<b>Local Destination:</b><br>\r\n<br>\r\n";
|
||||
i2p::data::IdentHash ident;
|
||||
|
@ -378,12 +378,12 @@ namespace http {
|
|||
s << "<td>" << it->GetWindowSize () << "</td>";
|
||||
s << "<td>" << (int)it->GetStatus () << "</td>";
|
||||
s << "</tr><br>\r\n" << std::endl;
|
||||
}
|
||||
}
|
||||
s << "</table>";
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
|
||||
static void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id)
|
||||
{
|
||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||
if (i2cpServer)
|
||||
|
@ -399,7 +399,7 @@ namespace http {
|
|||
ShowError(s, "I2CP is not enabled");
|
||||
}
|
||||
|
||||
void ShowLeasesSets(std::stringstream& s)
|
||||
void ShowLeasesSets(std::stringstream& s)
|
||||
{
|
||||
s << "<div id='leasesets'><b>LeaseSets (click on to show info):</b></div><br>\r\n";
|
||||
int counter = 1;
|
||||
|
@ -432,7 +432,7 @@ namespace http {
|
|||
// end for each lease set
|
||||
}
|
||||
|
||||
void ShowTunnels (std::stringstream& s)
|
||||
void ShowTunnels (std::stringstream& s)
|
||||
{
|
||||
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n";
|
||||
|
||||
|
@ -454,7 +454,7 @@ namespace http {
|
|||
s << "<br>\r\n";
|
||||
}
|
||||
|
||||
static void ShowCommands (std::stringstream& s, uint32_t token)
|
||||
static void ShowCommands (std::stringstream& s, uint32_t token)
|
||||
{
|
||||
/* commands */
|
||||
s << "<b>Router Commands</b><br>\r\n";
|
||||
|
@ -469,14 +469,16 @@ namespace http {
|
|||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
||||
else
|
||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Start graceful shutdown</a><br>\r\n";
|
||||
#endif
|
||||
#ifdef WIN32_APP
|
||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
||||
#elif defined(WIN32_APP)
|
||||
if (i2p::util::DaemonWin32::Instance().isGraceful)
|
||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "&token=" << token << "\">Cancel graceful shutdown</a><br>";
|
||||
else
|
||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "&token=" << token << "\">Graceful shutdown</a><br>\r\n";
|
||||
#endif
|
||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "&token=" << token << "\">Force shutdown</a><br>\r\n";
|
||||
}
|
||||
|
||||
void ShowTransitTunnels (std::stringstream& s)
|
||||
void ShowTransitTunnels (std::stringstream& s)
|
||||
{
|
||||
s << "<b>Transit tunnels:</b><br>\r\n<br>\r\n";
|
||||
for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ())
|
||||
|
@ -491,7 +493,7 @@ namespace http {
|
|||
}
|
||||
}
|
||||
|
||||
void ShowTransports (std::stringstream& s)
|
||||
void ShowTransports (std::stringstream& s)
|
||||
{
|
||||
s << "<b>Transports:</b><br>\r\n<br>\r\n";
|
||||
auto ntcpServer = i2p::transport::transports.GetNTCPServer ();
|
||||
|
@ -577,7 +579,7 @@ namespace http {
|
|||
}
|
||||
}
|
||||
|
||||
void ShowSAMSessions (std::stringstream& s)
|
||||
void ShowSAMSessions (std::stringstream& s)
|
||||
{
|
||||
auto sam = i2p::client::context.GetSAMBridge ();
|
||||
if (!sam) {
|
||||
|
@ -624,7 +626,7 @@ namespace http {
|
|||
}
|
||||
}
|
||||
|
||||
void ShowI2PTunnels (std::stringstream& s)
|
||||
void ShowI2PTunnels (std::stringstream& s)
|
||||
{
|
||||
s << "<b>Client Tunnels:</b><br>\r\n<br>\r\n";
|
||||
for (auto& it: i2p::client::context.GetClientTunnels ())
|
||||
|
@ -756,8 +758,8 @@ namespace http {
|
|||
}
|
||||
/* method #2: 'Authorization' header sent */
|
||||
auto provided = req.GetHeader ("Authorization");
|
||||
if (provided.length () > 0)
|
||||
{
|
||||
if (provided.length () > 0)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
std::string expected = user + ":" + pass;
|
||||
|
@ -802,7 +804,7 @@ namespace http {
|
|||
} else if (req.uri.find("cmd=") != std::string::npos) {
|
||||
HandleCommand (req, res, s);
|
||||
} else {
|
||||
ShowStatus (s, true);
|
||||
ShowStatus (s, true);
|
||||
res.add_header("Refresh", "10");
|
||||
}
|
||||
ShowPageTail (s);
|
||||
|
@ -814,7 +816,7 @@ namespace http {
|
|||
|
||||
std::map<uint32_t, uint32_t> HTTPConnection::m_Tokens;
|
||||
void HTTPConnection::HandlePage (const HTTPReq& req, HTTPRes& res, std::stringstream& s)
|
||||
{
|
||||
{
|
||||
std::map<std::string, std::string> params;
|
||||
std::string page("");
|
||||
URL url;
|
||||
|
@ -864,7 +866,7 @@ namespace http {
|
|||
ShowError(s, "Unknown page: " + page);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPConnection::HandleCommand (const HTTPReq& req, HTTPRes& res, std::stringstream& s)
|
||||
{
|
||||
|
@ -894,14 +896,15 @@ namespace http {
|
|||
i2p::context.SetAcceptsTunnels (false);
|
||||
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
|
||||
Daemon.gracefulShutdownInterval = 10*60;
|
||||
#endif
|
||||
#ifdef WIN32_APP
|
||||
#elif defined(WIN32_APP)
|
||||
i2p::win32::GracefulShutdown ();
|
||||
#endif
|
||||
} else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) {
|
||||
i2p::context.SetAcceptsTunnels (true);
|
||||
#if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID))
|
||||
Daemon.gracefulShutdownInterval = 0;
|
||||
#elif defined(WIN32_APP)
|
||||
i2p::win32::StopGracefulShutdown ();
|
||||
#endif
|
||||
} else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) {
|
||||
Daemon.running = false;
|
||||
|
@ -940,7 +943,7 @@ namespace http {
|
|||
|
||||
void HTTPServer::Start ()
|
||||
{
|
||||
bool needAuth; i2p::config::GetOption("http.auth", needAuth);
|
||||
bool needAuth; i2p::config::GetOption("http.auth", needAuth);
|
||||
std::string user; i2p::config::GetOption("http.user", user);
|
||||
std::string pass; i2p::config::GetOption("http.pass", pass);
|
||||
/* generate pass if needed */
|
||||
|
|
Loading…
Reference in a new issue