From e96ffd41894f2ece8f694b57c922b61d698f228a Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 21 Oct 2014 14:28:56 -0400 Subject: [PATCH] don't block HTTP server/proxy for 10 seconds anymore --- HTTPServer.cpp | 40 +++++++++++++++++++++++++--------------- HTTPServer.h | 9 +++++++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 93cfb528..06ed3e74 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -852,32 +852,42 @@ namespace util return; } - SendToDestination (destination, buf, len); - } - - void HTTPConnection::SendToDestination (const i2p::data::IdentHash& destination, const char * buf, size_t len) - { auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination); - if (!leaseSet || !leaseSet->HasNonExpiredLeases ()) + if (leaseSet && leaseSet->HasNonExpiredLeases ()) + SendToDestination (leaseSet, buf, len); + else { i2p::data::netdb.RequestDestination (destination, true, i2p::client::context.GetSharedLocalDestination ()->GetTunnelPool ()); - std::this_thread::sleep_for (std::chrono::seconds(10)); // wait for 10 seconds - leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination); - if (!leaseSet || !leaseSet->HasNonExpiredLeases ()) // still no LeaseSet - { + m_Timer.expires_from_now (boost::posix_time::seconds(HTTP_DESTINATION_REQUEST_TIMEOUT)); + m_Timer.async_wait (boost::bind (&HTTPConnection::HandleDestinationRequestTimeout, + this, boost::asio::placeholders::error, destination, buf, len)); + } + } + + void HTTPConnection::HandleDestinationRequestTimeout (const boost::system::error_code& ecode, i2p::data::IdentHash destination, const char * buf, size_t len) + { + if (ecode != boost::asio::error::operation_aborted) + { + auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination); + if (leaseSet && leaseSet->HasNonExpiredLeases ()) + SendToDestination (leaseSet, buf, len); + else + // still no LeaseSet SendReply (leaseSet ? "" + itoopieImage + "
Leases expired" : "" + itoopieImage + "LeaseSet not found", 504); - return; - } } + } + + void HTTPConnection::SendToDestination (const i2p::data::LeaseSet * remote, const char * buf, size_t len) + { if (!m_Stream) - m_Stream = i2p::client::context.GetSharedLocalDestination ()->CreateNewOutgoingStream (*leaseSet); + m_Stream = i2p::client::context.GetSharedLocalDestination ()->CreateNewOutgoingStream (*remote); if (m_Stream) { m_Stream->Send ((uint8_t *)buf, len); AsyncStreamReceive (); } - } - + } + void HTTPConnection::AsyncStreamReceive () { if (m_Stream) diff --git a/HTTPServer.h b/HTTPServer.h index 7559b975..30545639 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -5,6 +5,7 @@ #include #include #include +#include "LeaseSet.h" #include "Streaming.h" namespace i2p @@ -12,6 +13,7 @@ namespace i2p namespace util { const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; + const int HTTP_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds class HTTPConnection { protected: @@ -43,7 +45,8 @@ namespace util public: HTTPConnection (boost::asio::ip::tcp::socket * socket): - m_Socket (socket), m_Stream (nullptr), m_BufferLen (0) { Receive (); }; + m_Socket (socket), m_Timer (socket->get_io_service ()), + m_Stream (nullptr), m_BufferLen (0) { Receive (); }; virtual ~HTTPConnection() { delete m_Socket; } private: @@ -74,6 +77,7 @@ namespace util protected: boost::asio::ip::tcp::socket * m_Socket; + boost::asio::deadline_timer m_Timer; i2p::stream::Stream * m_Stream; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1], m_StreamBuffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; @@ -85,7 +89,8 @@ namespace util virtual void RunRequest (); void HandleDestinationRequest(const std::string& address, const std::string& uri); void SendToAddress (const std::string& address, const char * buf, size_t len); - void SendToDestination (const i2p::data::IdentHash& destination, const char * buf, size_t len); + void HandleDestinationRequestTimeout (const boost::system::error_code& ecode, i2p::data::IdentHash destination, const char * buf, size_t len); + void SendToDestination (const i2p::data::LeaseSet * remote, const char * buf, size_t len); public: