diff --git a/AddressBook.cpp b/AddressBook.cpp index cbb1825a..6a5bb6e8 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -3,11 +3,16 @@ #include #include #include +#include +#include #include +#include #include "base64.h" #include "util.h" #include "Identity.h" #include "Log.h" +#include "NetDb.h" +#include "ClientContext.h" #include "AddressBook.h" namespace i2p @@ -309,6 +314,68 @@ namespace client m_IsLoaded = true; } + AddressBookSubscription::AddressBookSubscription (AddressBook& book, const std::string& link): + m_Book (book), m_Link (link) + { + } + + void AddressBookSubscription::CheckSubscription () + { + std::thread load_hosts(&AddressBookSubscription::Request, this); + load_hosts.detach(); + } + + void AddressBookSubscription::Request () + { + // must be run in separate thread + i2p::util::http::url u (m_Link); + i2p::data::IdentHash ident; + if (m_Book.GetIdentHash (u.host_, ident)) + { + auto leaseSet = i2p::data::netdb.FindLeaseSet (ident); + if (!leaseSet) + { + i2p::data::netdb.RequestDestination (ident, true, i2p::client::context.GetSharedLocalDestination ()->GetTunnelPool ()); + std::this_thread::sleep_for (std::chrono::seconds (5)); // wait for 5 seconds + leaseSet = i2p::data::netdb.FindLeaseSet (ident); + } + if (leaseSet) + { + std::stringstream request, response; + request << "GET " << u.path_ << " HTTP/1.0\r\nHost: " << u.host_ + << "\r\nAccept: */*\r\n" << "User-Agent: Wget/1.11.4\r\n" << "Connection: close\r\n\r\n"; + + auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (*leaseSet, u.port_); + stream->Send ((uint8_t *)request.str ().c_str (), request.str ().length ()); + + uint8_t buf[4095]; + bool end = false; + while (!end) + { + std::condition_variable newDataReceived; + std::mutex newDataReceivedMutex; + stream->AsyncReceive (boost::asio::buffer (buf, 4096), + [&](const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + if (!ecode) + response.write ((char *)buf, bytes_transferred); + else + end = true; + newDataReceived.notify_one (); + }, + 30); // wait for 30 seconds + std::unique_lock l(newDataReceivedMutex); + newDataReceived.wait (l); + if (!end) + end = !stream->IsOpen (); + } + } + else + LogPrint (eLogError, "Address ", u.host_, " not found"); + } + else + LogPrint (eLogError, "Can't resolve ", u.host_); + } } } diff --git a/AddressBook.h b/AddressBook.h index 1a8f7cec..44f62770 100644 --- a/AddressBook.h +++ b/AddressBook.h @@ -51,6 +51,23 @@ namespace client AddressBookStorage * m_Storage; bool m_IsLoaded, m_IsDowloading; }; + + class AddressBookSubscription + { + public: + + AddressBookSubscription (AddressBook& book, const std::string& link); + void CheckSubscription (); + + private: + + void Request (); + + private: + + AddressBook& m_Book; + std::string m_Link; + }; } }