Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
HTTPProxy: rewrite to fix uncovered bugs
Browse files Browse the repository at this point in the history
Rewrite to fix bugs uncovered by unit-tests.

Refs #835 + #838
  • Loading branch information
coneiric committed Mar 19, 2018
1 parent 19f755f commit 22f9202
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 51 deletions.
78 changes: 40 additions & 38 deletions src/client/proxy/http.cc
Original file line number Diff line number Diff line change
Expand Up @@ -430,20 +430,18 @@ bool HTTPMessage::HandleJumpService()
// TODO(anonimal): add support for remaining services /
// rewrite this function

// Perform sanity check again to:
// - ensure valid jump service request
std::size_t const pos = IsJumpServiceRequest();
if (!pos)
// Ensure valid jump service request
if (!IsJumpServiceRequest())
{
LOG(error) << "HTTPProxyHandler: not a valid jump service request";
// Jump service parameter not found in URL, so just return
return false;
}

if (m_Address.empty())
if (m_Address.empty() || m_Query.empty())
ParseURL();

if (!ExtractBase64Destination(pos))
std::size_t const pos = m_URL.find(m_Query);
if (!ExtractBase64Destination())
{
LOG(error) << "HTTPProxyHandler: unable to process base64 destination for "
<< m_Address;
Expand All @@ -457,48 +455,53 @@ bool HTTPMessage::HandleJumpService()
return true;
}

std::size_t HTTPMessage::IsJumpServiceRequest() const
bool HTTPMessage::IsJumpServiceRequest()
{
std::size_t pos = 0;
std::size_t const pos1 = m_URL.rfind(m_JumpService.at(0));
std::size_t const pos2 = m_URL.rfind(m_JumpService.at(1));
if (pos1 == std::string::npos)
try
{
if (pos2 == std::string::npos)
return 0; // Not a jump service
else
pos = pos2;
std::vector<std::string> const helper_ident = ParseJumpServiceQuery();
for (const auto& helper : m_JumpService)
if (helper_ident[0] == helper)
return true;
}
else
catch (...)
{
if (pos2 == std::string::npos)
pos = pos1;
else if (pos1 > pos2)
pos = pos1;
else
pos = pos2;
m_Exception.Dispatch(__func__);
}

// final sanity check
if (pos && pos != std::string::npos)
return pos;

return 0;
return false;
}

bool HTTPMessage::ExtractBase64Destination(std::size_t const pos)
bool HTTPMessage::ExtractBase64Destination()
{
std::size_t const base64_size = pos + m_JumpService.at(0).size();
if (pos && base64_size < m_URL.size())
try
{
std::string const base64 = m_URL.substr(base64_size);
m_Base64Destination = boost::network::uri::decoded(base64);
return true;
std::vector<std::string> const helper_ident = ParseJumpServiceQuery();
if (!helper_ident[1].empty())
{
m_Base64Destination = boost::network::uri::decoded(helper_ident[1]);
return true;
}
LOG(error) << "HTTPProxyHandler: empty base64 destination";
return false;
}
catch (...)
{
m_Exception.Dispatch(__func__);
}

return false;
}

std::vector<std::string> const HTTPMessage::ParseJumpServiceQuery()
{
if (m_Query.empty())
ParseURL();
std::vector<std::string> helper_ident{""};
boost::split(helper_ident, m_Query, boost::is_any_of("="));
if (helper_ident.size() != 2)
throw std::length_error("HTTPProxyHandler: invalid number of jump service parameters");
return helper_ident;
}

bool HTTPMessage::SaveJumpServiceAddress()
{
try
Expand All @@ -519,8 +522,7 @@ bool HTTPMessage::SaveJumpServiceAddress()
}
catch (...)
{
core::Exception ex;
ex.Dispatch(__func__);
m_Exception.Dispatch(__func__);
return false;
}

Expand Down
27 changes: 14 additions & 13 deletions src/client/proxy/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,8 @@ class HTTPMessage : public std::enable_shared_from_this<HTTPMessage>{

/// @var m_JumpService
/// @brief Address helpers for base64 jump service
const std::array<std::string, 4> m_JumpService {
{
"?i2paddresshelper=",
"&i2paddresshelper=",
"?kovrijumpservice=",
"&kovrijumpservice=",
}
};
const std::vector<std::string> m_JumpService{"i2paddresshelper",
"kovrijumpservice"};
HTTPResponse m_ErrorResponse;
HTTPMessage():m_Port(0), m_ErrorResponse(HTTPResponseCodes::status_t::ok) {
}
Expand Down Expand Up @@ -247,18 +241,25 @@ class HTTPMessage : public std::enable_shared_from_this<HTTPMessage>{
/// and sets corresponding member variables
void ParseURL();

/// @brief Checks if request is a valid jump service request
/// @return Index of jump service helper sub-string, 0 indicates failure
std::size_t IsJumpServiceRequest() const;
/// @brief Parse jump service parameters from request
/// @return Jump service parameters
std::vector<std::string> const ParseJumpServiceQuery();

/// @brief Checks if request is a jump service request
/// @return True if current request is a valid jump service request
bool IsJumpServiceRequest();

/// @brief Extracts & url-decodes base64 destination from URL
/// @param pos Index of jump service helper sub-string in URL
/// @return True on success
bool ExtractBase64Destination(std::size_t const pos);
bool ExtractBase64Destination();

/// @brief Saves found address in address book
/// @return True on success
bool SaveJumpServiceAddress();

/// @var m_Exception
/// @brief Exception dispatcher
kovri::core::Exception m_Exception;
};
/// @class HTTPProxyServer
/// setup asio service
Expand Down

0 comments on commit 22f9202

Please sign in to comment.