|
|
|
@ -139,22 +139,25 @@ namespace client
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (m_Stream)
|
|
|
|
|
{
|
|
|
|
|
auto s = shared_from_this ();
|
|
|
|
|
m_Stream->AsyncSend (m_Buffer, bytes_transferred,
|
|
|
|
|
[s](const boost::system::error_code& ecode)
|
|
|
|
|
{
|
|
|
|
|
if (!ecode)
|
|
|
|
|
s->Receive ();
|
|
|
|
|
else
|
|
|
|
|
s->Terminate ();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
WriteToStream (m_Buffer, bytes_transferred);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void I2PTunnelConnection::WriteToStream (const uint8_t * buf, size_t len)
|
|
|
|
|
{
|
|
|
|
|
if (m_Stream)
|
|
|
|
|
{
|
|
|
|
|
auto s = shared_from_this ();
|
|
|
|
|
m_Stream->AsyncSend (buf, len,
|
|
|
|
|
[s](const boost::system::error_code& ecode)
|
|
|
|
|
{
|
|
|
|
|
if (!ecode)
|
|
|
|
|
s->Receive ();
|
|
|
|
|
else
|
|
|
|
|
s->Terminate ();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void I2PTunnelConnection::HandleWrite (const boost::system::error_code& ecode)
|
|
|
|
|
{
|
|
|
|
|
if (ecode)
|
|
|
|
@ -302,7 +305,8 @@ namespace client
|
|
|
|
|
I2PServerTunnelConnectionHTTP::I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
|
|
|
|
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
|
|
|
|
const boost::asio::ip::tcp::endpoint& target, const std::string& host):
|
|
|
|
|
I2PTunnelConnection (owner, stream, socket, target), m_Host (host), m_HeaderSent (false), m_From (stream->GetRemoteIdentity ())
|
|
|
|
|
I2PTunnelConnection (owner, stream, socket, target), m_Host (host),
|
|
|
|
|
m_HeaderSent (false), m_ResponseHeaderSent (false), m_From (stream->GetRemoteIdentity ())
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -333,25 +337,75 @@ namespace client
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// add X-I2P fields
|
|
|
|
|
if (m_From)
|
|
|
|
|
{
|
|
|
|
|
m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n";
|
|
|
|
|
m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n";
|
|
|
|
|
m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (endOfHeader)
|
|
|
|
|
{
|
|
|
|
|
// add X-I2P fields
|
|
|
|
|
if (m_From)
|
|
|
|
|
{
|
|
|
|
|
m_OutHeader << X_I2P_DEST_B32 << ": " << context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()) << "\r\n";
|
|
|
|
|
m_OutHeader << X_I2P_DEST_HASH << ": " << m_From->GetIdentHash ().ToBase64 () << "\r\n";
|
|
|
|
|
m_OutHeader << X_I2P_DEST_B64 << ": " << m_From->ToBase64 () << "\r\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_OutHeader << "\r\n"; // end of header
|
|
|
|
|
m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header
|
|
|
|
|
m_InHeader.str ("");
|
|
|
|
|
m_From = nullptr;
|
|
|
|
|
m_HeaderSent = true;
|
|
|
|
|
I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void I2PServerTunnelConnectionHTTP::WriteToStream (const uint8_t * buf, size_t len)
|
|
|
|
|
{
|
|
|
|
|
if (m_ResponseHeaderSent)
|
|
|
|
|
I2PTunnelConnection::WriteToStream (buf, len);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_InHeader.clear ();
|
|
|
|
|
if (m_InHeader.str ().empty ()) m_OutHeader.str (""); // start of response
|
|
|
|
|
m_InHeader.write ((const char *)buf, len);
|
|
|
|
|
std::string line;
|
|
|
|
|
bool endOfHeader = false;
|
|
|
|
|
while (!endOfHeader)
|
|
|
|
|
{
|
|
|
|
|
std::getline(m_InHeader, line);
|
|
|
|
|
if (!m_InHeader.fail ())
|
|
|
|
|
{
|
|
|
|
|
if (line == "\r") endOfHeader = true;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (line.find ("Server:") != std::string::npos) continue; // exclude "Server:"
|
|
|
|
|
if (line.find ("Date:") != std::string::npos) continue; // exclude "Date""
|
|
|
|
|
if (line[0] == 'X')
|
|
|
|
|
{
|
|
|
|
|
if (line.find ("X-Runtime:") != std::string::npos) continue; // exclude "X-Runtime:"
|
|
|
|
|
if (line.find ("X-Powered-By:") != std::string::npos) continue; // exclude "X-Powered-By:"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_OutHeader << line << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (endOfHeader)
|
|
|
|
|
{
|
|
|
|
|
m_OutHeader << "\r\n"; // end of header
|
|
|
|
|
m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header
|
|
|
|
|
m_InHeader.str ("");
|
|
|
|
|
m_ResponseHeaderSent = true;
|
|
|
|
|
I2PTunnelConnection::WriteToStream ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ());
|
|
|
|
|
m_OutHeader.str ("");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Receive ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
I2PTunnelConnectionIRC::I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
|
|
|
|
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
|
|
|
|
const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass):
|
|
|
|
|