Added 404 page to the webui.

This commit is contained in:
EinMByte 2015-09-18 11:52:09 +02:00
parent dbade8b569
commit c741382fc9
6 changed files with 81 additions and 20 deletions

View File

@ -94,26 +94,41 @@ void HTTPConnection::HandleWriteReply(const boost::system::error_code& e)
} }
} }
void HTTPConnection::HandleRequest() void HTTPConnection::Send404Reply()
{
try {
const std::string error_page = "404.html";
m_Reply = i2p::util::http::Response(404, GetFileContents(error_page, true));
m_Reply.setHeader("Content-Type", i2p::util::http::getMimeType(error_page));
} catch(const std::runtime_error&) {
// Failed to load 404.html, assume the webui is incorrectly installed
m_Reply = i2p::util::http::Response(404,
"<!DOCTYPE HTML><html>"
"<head><title>Error: 404 - webui not installed</title></head><body>"
"<p>It looks like your webui installation is broken.</p>"
"<p>Run the following command to (re)install it:</p>"
"<pre>./i2pd --install /path/to/webui</pre>"
"<p>The webui folder should come with the binaries.</p>"
"</body></html>"
);
}
SendReply();
}
std::string HTTPConnection::GetFileContents(const std::string& filename, bool preprocess) const
{ {
boost::system::error_code e; boost::system::error_code e;
std::string uri = m_Request.getUri(); // Use canonical to avoid .. or . in path
if(uri == "/")
uri = "index.html";
// Use canonical to avoid .. or . in path
const boost::filesystem::path address = boost::filesystem::canonical( const boost::filesystem::path address = boost::filesystem::canonical(
i2p::util::filesystem::GetWebuiDataDir() / uri, e i2p::util::filesystem::GetWebuiDataDir() / filename, e
); );
const std::string address_str = address.string(); const std::string address_str = address.string();
std::ifstream ifs(address_str); std::ifstream ifs(address_str);
if(e || !ifs || !isAllowed(address_str)) { if(e || !ifs || !isAllowed(address_str))
m_Reply = i2p::util::http::Response(404, ""); throw std::runtime_error("Cannot load " + address_str + ".");
return SendReply();
}
std::string str; std::string str;
ifs.seekg(0, ifs.end); ifs.seekg(0, ifs.end);
@ -122,11 +137,27 @@ void HTTPConnection::HandleRequest()
ifs.read(&str[0], str.size()); ifs.read(&str[0], str.size());
ifs.close(); ifs.close();
str = i2p::util::http::preprocessContent(str, address.parent_path().string()); if(preprocess)
m_Reply = i2p::util::http::Response(200, str); return i2p::util::http::preprocessContent(str, address.parent_path().string());
else
return str;
}
m_Reply.setHeader("Content-Type", i2p::util::http::getMimeType(address_str)); void HTTPConnection::HandleRequest()
SendReply(); {
std::string uri = m_Request.getUri();
if(uri == "/")
uri = "index.html";
try {
m_Reply = i2p::util::http::Response(200, GetFileContents(uri, true));
m_Reply.setHeader("Content-Type", i2p::util::http::getMimeType(uri));
SendReply();
} catch(const std::runtime_error&) {
// Cannot open the file for some reason, send 404
Send404Reply();
}
} }
void HTTPConnection::HandleI2PControlRequest() void HTTPConnection::HandleI2PControlRequest()
@ -138,7 +169,7 @@ void HTTPConnection::HandleI2PControlRequest()
SendReply(); SendReply();
} }
bool HTTPConnection::isAllowed(const std::string& address) bool HTTPConnection::isAllowed(const std::string& address) const
{ {
const std::size_t pos_dot = address.find_last_of('.'); const std::size_t pos_dot = address.find_last_of('.');
const std::size_t pos_slash = address.find_last_of('/'); const std::size_t pos_slash = address.find_last_of('/');

View File

@ -32,11 +32,18 @@ private:
void HandleWriteReply(const boost::system::error_code& ecode); void HandleWriteReply(const boost::system::error_code& ecode);
void SendReply(); void SendReply();
void Send404Reply();
/*
* @throw std::runtime_error when the file is not accessible
*/
std::string GetFileContents(const std::string& filename, bool preprocess) const;
void HandleRequest(); void HandleRequest();
void HandleI2PControlRequest(); void HandleI2PControlRequest();
void ExtractParams(const std::string& str, std::map<std::string, std::string>& params); void ExtractParams(const std::string& str, std::map<std::string, std::string>& params);
bool isAllowed(const std::string& address); bool isAllowed(const std::string& address) const;
private: private:
boost::asio::ip::tcp::socket* m_Socket; boost::asio::ip::tcp::socket* m_Socket;
char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1];

24
webui/404.html Normal file
View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>404 - Page not found</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="header">
<h1>404 - Page not found</h1>
</div>
<div class="content">
<h2 class="content-subhead">The page you were looking for could not be found.</h2>
</div>
<!--#include virtual="menu.html" -->
<!--#include virtual="footer.html" -->
</body>
</html>

View File

@ -5,7 +5,6 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/main.css"> <link rel="stylesheet" href="css/main.css">
<script type="text/javascript" src="javascript/I2PControl.js"></script>
</head> </head>
<body> <body>

View File

@ -8,7 +8,7 @@
<a href="netdb.html" class="menu-link">Network Database</a> <a href="netdb.html" class="menu-link">Network Database</a>
</li> </li>
<li class="menu-item"> <li class="menu-item">
<a href="#/config" class="menu-link">Configure</a> <a href="config.html" class="menu-link">Configure</a>
</li> </li>
<li class="menu-item"> <li class="menu-item">
<a href="help.html" class="menu-link">Help</a> <a href="help.html" class="menu-link">Help</a>

View File

@ -19,7 +19,7 @@ function updateNetDbInfo(result, session) {
"leasesets" : result["i2p.router.netdb.leasesets"], "leasesets" : result["i2p.router.netdb.leasesets"],
}); });
window.setTimeout(function() { requestNetDbInfo(session); }, 5000); window.setTimeout(function() { requestNetDbInfo(session); }, 10000);
} }
function requestNetDbInfo(session) { function requestNetDbInfo(session) {