Browse Source

always send Connection: close, strip out Keep-Alive for server HTTP tunnel

pull/1763/head
orignal 3 years ago
parent
commit
6ecab66b0e
  1. 71
      libi2pd_client/I2PTunnel.cpp
  2. 7
      libi2pd_client/I2PTunnel.h

71
libi2pd_client/I2PTunnel.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2021, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -337,45 +337,38 @@ namespace client
I2PTunnelConnection::Write (buf, len); I2PTunnelConnection::Write (buf, len);
else else
{ {
m_InHeader.clear (); auto headerLen = m_ClientRequest.parse ((const char *)buf, len);
m_InHeader.write ((const char *)buf, len); if (!headerLen) return; // request is not complete, wait for next portion
std::string line; if (headerLen < 0)
bool endOfHeader = false;
while (!endOfHeader)
{
std::getline(m_InHeader, line);
if (!m_InHeader.fail ())
{
if (line == "\r") endOfHeader = true;
else
{
if (m_Host.length () > 0 && !line.compare(0, 5, "Host:"))
m_OutHeader << "Host: " << m_Host << "\r\n"; // override host
else
m_OutHeader << line << "\n";
}
}
else
break;
}
if (endOfHeader)
{ {
// add X-I2P fields LogPrint (eLogError, "I2PTunnel: Can't parse HTTP request");
if (m_From) Terminate ();
{ return;
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_ClientRequest.RemoveHeader ("Keep-Alive");
} auto h = m_ClientRequest.GetHeader ("Connection");
if (h.empty ())
m_OutHeader << "\r\n"; // end of header m_ClientRequest.AddHeader ("Connection", "close");
m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header else if (h != "close")
m_InHeader.str (""); {
m_From = nullptr; // Upgrade or upgrade ?
m_HeaderSent = true; auto x = h.find("pgrade");
I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); if (x == std::string::npos || !x || std::tolower(h[x - 1]) != 'u')
} m_ClientRequest.UpdateHeader("Connection", "close");
}
if (!m_Host.empty ())
m_ClientRequest.UpdateHeader ("Host", m_Host);
m_ClientRequest.AddHeader (X_I2P_DEST_B32, context.GetAddressBook ().ToAddress(m_From->GetIdentHash ()));
m_ClientRequest.AddHeader (X_I2P_DEST_HASH, m_From->GetIdentHash ().ToBase64 ());
m_ClientRequest.AddHeader (X_I2P_DEST_B64, m_From->ToBase64 ());
m_RequestSendBuffer = m_ClientRequest.to_string ();
if ((size_t)headerLen < len)
m_RequestSendBuffer.append ((const char *)(buf + headerLen), len - headerLen); // data right after header
m_From = nullptr;
m_HeaderSent = true;
I2PTunnelConnection::Write ((uint8_t *)m_RequestSendBuffer.c_str (), m_RequestSendBuffer.length ());
} }
} }

7
libi2pd_client/I2PTunnel.h

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2021, The PurpleI2P Project * Copyright (c) 2013-2022, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -20,6 +20,7 @@
#include "Destination.h" #include "Destination.h"
#include "Datagram.h" #include "Datagram.h"
#include "Streaming.h" #include "Streaming.h"
#include "HTTP.h"
#include "I2PService.h" #include "I2PService.h"
#include "AddressBook.h" #include "AddressBook.h"
@ -110,7 +111,9 @@ namespace client
private: private:
std::string m_Host; std::string m_Host;
std::stringstream m_InHeader, m_OutHeader; i2p::http::HTTPReq m_ClientRequest;
std::string m_RequestSendBuffer;
std::stringstream m_InHeader, m_OutHeader; // for responses
bool m_HeaderSent, m_ResponseHeaderSent; bool m_HeaderSent, m_ResponseHeaderSent;
std::shared_ptr<const i2p::data::IdentityEx> m_From; std::shared_ptr<const i2p::data::IdentityEx> m_From;
}; };

Loading…
Cancel
Save