|
|
|
@ -139,20 +139,23 @@ namespace client
@@ -139,20 +139,23 @@ namespace client
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
WriteToStream (m_Buffer, bytes_transferred); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void I2PTunnelConnection::WriteToStream (const uint8_t * buf, size_t len) |
|
|
|
|
{ |
|
|
|
|
if (m_Stream) |
|
|
|
|
{ |
|
|
|
|
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 (); |
|
|
|
|
}); |
|
|
|
|
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) |
|
|
|
@ -302,7 +305,8 @@ namespace client
@@ -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
@@ -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): |
|
|
|
|