mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-13 12:56:38 +01:00
Merge pull request #66 from chertov/master
http status code, load host.txt via proxy
This commit is contained in:
commit
4cbc7773ac
8 changed files with 212 additions and 45 deletions
|
@ -33,18 +33,13 @@ const IdentHash * AddressBook::FindAddress (const std::string& address)
|
||||||
void AddressBook::LoadHostsFromI2P ()
|
void AddressBook::LoadHostsFromI2P ()
|
||||||
{
|
{
|
||||||
std::string content;
|
std::string content;
|
||||||
|
|
||||||
std::stringstream url_ss;
|
|
||||||
// TODO: hosts link in config
|
|
||||||
// TODO: url download via HTTPProxy
|
|
||||||
url_ss << "http://127.0.0.1:" << i2p::util::config::GetArg("-httpport", 7070) << "/udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna/hosts.txt";
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
content = i2p::util::http::httpRequest(url_ss.str());
|
// TODO: hosts link in config
|
||||||
|
int http_code = i2p::util::http::httpRequestViaI2pProxy("http://udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p/hosts.txt", content);
|
||||||
// TODO: check http errors
|
if (http_code ==200)
|
||||||
if (! boost::starts_with(content, "<html>") && content.size() > 0)
|
if (!boost::starts_with(content, "<html>") && !content.empty()) // TODO: test and remove
|
||||||
break;
|
break;
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,12 +118,26 @@ namespace util
|
||||||
|
|
||||||
} // namespace misc_strings
|
} // namespace misc_strings
|
||||||
|
|
||||||
std::vector<boost::asio::const_buffer> HTTPConnection::reply::to_buffers()
|
std::vector<boost::asio::const_buffer> HTTPConnection::reply::to_buffers(int status)
|
||||||
{
|
{
|
||||||
std::vector<boost::asio::const_buffer> buffers;
|
std::vector<boost::asio::const_buffer> buffers;
|
||||||
if (headers.size () > 0)
|
if (headers.size () > 0)
|
||||||
{
|
{
|
||||||
buffers.push_back (boost::asio::buffer ("HTTP/1.0 200 OK\r\n")); // always OK
|
switch (status)
|
||||||
|
{
|
||||||
|
case 105: buffers.push_back(boost::asio::buffer("HTTP/1.0 105 Name Not Resolved\r\n")); break;
|
||||||
|
case 200: buffers.push_back(boost::asio::buffer("HTTP/1.0 200 OK\r\n")); break;
|
||||||
|
case 400: buffers.push_back(boost::asio::buffer("HTTP/1.0 400 Bad Request\r\n")); break;
|
||||||
|
case 404: buffers.push_back(boost::asio::buffer("HTTP/1.0 404 Not Found\r\n")); break;
|
||||||
|
case 408: buffers.push_back(boost::asio::buffer("HTTP/1.0 408 Request Timeout\r\n")); break;
|
||||||
|
case 500: buffers.push_back(boost::asio::buffer("HTTP/1.0 500 Internal Server Error\r\n")); break;
|
||||||
|
case 502: buffers.push_back(boost::asio::buffer("HTTP/1.0 502 Bad Gateway\r\n")); break;
|
||||||
|
case 503: buffers.push_back(boost::asio::buffer("HTTP/1.0 503 Not Implemented\r\n")); break;
|
||||||
|
case 504: buffers.push_back(boost::asio::buffer("HTTP/1.0 504 Gateway Timeout\r\n")); break;
|
||||||
|
default:
|
||||||
|
buffers.push_back(boost::asio::buffer("HTTP/1.0 200 OK\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < headers.size(); ++i)
|
for (std::size_t i = 0; i < headers.size(); ++i)
|
||||||
{
|
{
|
||||||
header& h = headers[i];
|
header& h = headers[i];
|
||||||
|
@ -311,27 +325,40 @@ namespace util
|
||||||
{
|
{
|
||||||
i2p::data::IdentHash destination;
|
i2p::data::IdentHash destination;
|
||||||
std::string fullAddress;
|
std::string fullAddress;
|
||||||
if (address.find (".i2p") != std::string::npos)
|
if (address.find(".b32.i2p") != std::string::npos)
|
||||||
{
|
{
|
||||||
auto addr = i2p::data::netdb.FindAddress(address);
|
if (i2p::data::Base32ToByteStream(address.c_str(), address.length() - strlen(".b32.i2p"), (uint8_t *)destination, 32) != 32)
|
||||||
if (!addr)
|
|
||||||
{
|
{
|
||||||
LogPrint ("Unknown address ", address);
|
LogPrint ("Invalid Base32 address ", address);
|
||||||
SendReply ("<html>" + itoopieImage + "<br>Unknown address " + address + "</html>");
|
SendReply ("<html>" + itoopieImage + "<br>Invalid Base32 address", 400);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
destination = *addr;
|
|
||||||
fullAddress = address;
|
fullAddress = address;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (i2p::data::Base32ToByteStream (address.c_str (), address.length (), (uint8_t *)destination, 32) != 32)
|
if (address.find(".i2p") != std::string::npos)
|
||||||
{
|
{
|
||||||
LogPrint ("Invalid Base32 address ", address);
|
auto addr = i2p::data::netdb.FindAddress(address);
|
||||||
SendReply ("<html>" + itoopieImage + "<br>Invalid Base32 address");
|
if (!addr)
|
||||||
return;
|
{
|
||||||
|
LogPrint ("Unknown address ", address);
|
||||||
|
SendReply ("<html>" + itoopieImage + "<br>Unknown address " + address + "</html>", 105);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
destination = *addr;
|
||||||
|
fullAddress = address;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i2p::data::Base32ToByteStream(address.c_str(), address.length(), (uint8_t *)destination, 32) != 32)
|
||||||
|
{
|
||||||
|
LogPrint("Invalid Base32 address ", address);
|
||||||
|
SendReply("<html>" + itoopieImage + "<br>Invalid Base32 address", 400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fullAddress = address + ".b32.i2p";
|
||||||
}
|
}
|
||||||
fullAddress = address + ".b32.i2p";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto leaseSet = i2p::data::netdb.FindLeaseSet (destination);
|
auto leaseSet = i2p::data::netdb.FindLeaseSet (destination);
|
||||||
|
@ -342,7 +369,7 @@ namespace util
|
||||||
leaseSet = i2p::data::netdb.FindLeaseSet (destination);
|
leaseSet = i2p::data::netdb.FindLeaseSet (destination);
|
||||||
if (!leaseSet || !leaseSet->HasNonExpiredLeases ()) // still no LeaseSet
|
if (!leaseSet || !leaseSet->HasNonExpiredLeases ()) // still no LeaseSet
|
||||||
{
|
{
|
||||||
SendReply (leaseSet ? "<html>" + itoopieImage + "<br>Leases expired</html>" : "<html>" + itoopieImage + "LeaseSet not found</html>");
|
SendReply (leaseSet ? "<html>" + itoopieImage + "<br>Leases expired</html>" : "<html>" + itoopieImage + "LeaseSet not found</html>", 504);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,13 +402,13 @@ namespace util
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_Stream && m_Stream->IsOpen ())
|
if (m_Stream && m_Stream->IsOpen ())
|
||||||
SendReply ("<html>" + itoopieImage + "<br>Not responding</html>");
|
SendReply ("<html>" + itoopieImage + "<br>Not responding</html>", 504);
|
||||||
else
|
else
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPConnection::SendReply (const std::string& content)
|
void HTTPConnection::SendReply (const std::string& content, int status)
|
||||||
{
|
{
|
||||||
m_Reply.content = content;
|
m_Reply.content = content;
|
||||||
m_Reply.headers.resize(2);
|
m_Reply.headers.resize(2);
|
||||||
|
@ -390,7 +417,7 @@ namespace util
|
||||||
m_Reply.headers[1].name = "Content-Type";
|
m_Reply.headers[1].name = "Content-Type";
|
||||||
m_Reply.headers[1].value = "text/html";
|
m_Reply.headers[1].value = "text/html";
|
||||||
|
|
||||||
boost::asio::async_write (*m_Socket, m_Reply.to_buffers(),
|
boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status),
|
||||||
boost::bind (&HTTPConnection::HandleWriteReply, this,
|
boost::bind (&HTTPConnection::HandleWriteReply, this,
|
||||||
boost::asio::placeholders::error));
|
boost::asio::placeholders::error));
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace util
|
||||||
std::vector<header> headers;
|
std::vector<header> headers;
|
||||||
std::string content;
|
std::string content;
|
||||||
|
|
||||||
std::vector<boost::asio::const_buffer> to_buffers();
|
std::vector<boost::asio::const_buffer> to_buffers (int status);
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -53,7 +53,7 @@ namespace util
|
||||||
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||||
void HandleWriteReply(const boost::system::error_code& ecode);
|
void HandleWriteReply(const boost::system::error_code& ecode);
|
||||||
void HandleWrite (const boost::system::error_code& ecode);
|
void HandleWrite (const boost::system::error_code& ecode);
|
||||||
void SendReply (const std::string& content);
|
void SendReply (const std::string& content, int status = 200);
|
||||||
|
|
||||||
void HandleRequest ();
|
void HandleRequest ();
|
||||||
void FillContent (std::stringstream& s);
|
void FillContent (std::stringstream& s);
|
||||||
|
|
1
Win32/.gitignore
vendored
1
Win32/.gitignore
vendored
|
@ -5,4 +5,5 @@
|
||||||
!*.vcproj
|
!*.vcproj
|
||||||
!*.vcxproj
|
!*.vcxproj
|
||||||
!*.vcxproj.filters
|
!*.vcxproj.filters
|
||||||
|
!*.iss
|
||||||
!.gitignore
|
!.gitignore
|
|
@ -106,8 +106,9 @@
|
||||||
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<IncludePath>.\boost;.\cryptopp;$(IncludePath)</IncludePath>
|
<IncludePath>./..;$(BOOST);$(CRYPTOPP);$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>.\stage-x86\lib;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\Win32\Output\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
||||||
|
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -134,6 +135,7 @@
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
81
Win32/inno_installer.iss
Normal file
81
Win32/inno_installer.iss
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
|
||||||
|
#define I2Pd_AppName "i2pd"
|
||||||
|
#define I2Pd_ver "0.1"
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
AppName={#I2Pd_AppName}
|
||||||
|
AppVersion={#I2Pd_ver}
|
||||||
|
DefaultDirName={pf}\I2Pd
|
||||||
|
DefaultGroupName=I2Pd
|
||||||
|
UninstallDisplayIcon={app}\I2Pd.exe
|
||||||
|
Compression=lzma2
|
||||||
|
SolidCompression=yes
|
||||||
|
OutputDir=.
|
||||||
|
LicenseFile=.\..\LICENSE
|
||||||
|
OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver}
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "i2pd.exe"; DestDir: "{app}"
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe"
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
|
||||||
|
var
|
||||||
|
DefaultTop,
|
||||||
|
DefaultLeft,
|
||||||
|
DefaultHeight,
|
||||||
|
DefaultBackTop,
|
||||||
|
DefaultNextTop,
|
||||||
|
DefaultCancelTop,
|
||||||
|
DefaultBevelTop,
|
||||||
|
DefaultOuterHeight: Integer;
|
||||||
|
|
||||||
|
const
|
||||||
|
LicenseHeight = 400;
|
||||||
|
|
||||||
|
procedure InitializeWizard();
|
||||||
|
begin
|
||||||
|
DefaultTop := WizardForm.Top;
|
||||||
|
DefaultLeft := WizardForm.Left;
|
||||||
|
DefaultHeight := WizardForm.Height;
|
||||||
|
DefaultBackTop := WizardForm.BackButton.Top;
|
||||||
|
DefaultNextTop := WizardForm.NextButton.Top;
|
||||||
|
DefaultCancelTop := WizardForm.CancelButton.Top;
|
||||||
|
DefaultBevelTop := WizardForm.Bevel.Top;
|
||||||
|
DefaultOuterHeight := WizardForm.OuterNotebook.Height;
|
||||||
|
|
||||||
|
WizardForm.InnerPage.Height := WizardForm.InnerPage.Height + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.InnerNotebook.Height := WizardForm.InnerNotebook.Height + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.LicensePage.Height := WizardForm.LicensePage.Height + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.LicenseMemo.Height := WizardForm.LicenseMemo.Height + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.LicenseNotAcceptedRadio.Top := WizardForm.LicenseNotAcceptedRadio.Top + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.LicenseAcceptedRadio.Top := WizardForm.LicenseAcceptedRadio.Top + (LicenseHeight - DefaultHeight);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CurPageChanged(CurPageID: Integer);
|
||||||
|
begin
|
||||||
|
if CurPageID = wpLicense then
|
||||||
|
begin
|
||||||
|
WizardForm.Top := DefaultTop - (LicenseHeight - DefaultHeight) div 2;
|
||||||
|
WizardForm.Height := LicenseHeight;
|
||||||
|
WizardForm.OuterNotebook.Height := WizardForm.OuterNotebook.Height + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.CancelButton.Top := DefaultCancelTop + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.NextButton.Top := DefaultNextTop + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.BackButton.Top := DefaultBackTop + (LicenseHeight - DefaultHeight);
|
||||||
|
WizardForm.Bevel.Top := DefaultBevelTop + (LicenseHeight - DefaultHeight);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
WizardForm.Top := DefaultTop;
|
||||||
|
WizardForm.Left := DefaultLeft;
|
||||||
|
WizardForm.Height := DefaultHeight;
|
||||||
|
WizardForm.OuterNotebook.Height := DefaultOuterHeight;
|
||||||
|
WizardForm.CancelButton.Top := DefaultCancelTop;
|
||||||
|
WizardForm.NextButton.Top := DefaultNextTop;
|
||||||
|
WizardForm.BackButton.Top := DefaultBackTop;
|
||||||
|
WizardForm.Bevel.Top := DefaultBevelTop;
|
||||||
|
end;
|
||||||
|
end;
|
67
util.cpp
67
util.cpp
|
@ -249,13 +249,72 @@ namespace http
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string url::portstr_ = "80";
|
int httpRequestViaI2pProxy(const std::string& address, std::string &content)
|
||||||
unsigned int url::port_ = 80;
|
{
|
||||||
std::string url::user_ = "";
|
content = "";
|
||||||
std::string url::pass_ = "";
|
try
|
||||||
|
{
|
||||||
|
boost::asio::ip::tcp::iostream site;
|
||||||
|
// please don't uncomment following line because it's not compatible with boost 1.46
|
||||||
|
// 1.46 is default boost for Ubuntu 12.04 LTS
|
||||||
|
//site.expires_from_now (boost::posix_time::seconds(30));
|
||||||
|
{
|
||||||
|
std::stringstream ss; ss << i2p::util::config::GetArg("-httpproxyport", 4446);
|
||||||
|
site.connect("127.0.0.1", ss.str());
|
||||||
|
}
|
||||||
|
if (site)
|
||||||
|
{
|
||||||
|
i2p::util::http::url u(address);
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "GET " << address << " HTTP/1.0" << std::endl;
|
||||||
|
ss << "Host: " << u.host_ << std::endl;
|
||||||
|
ss << "Accept: */*" << std::endl;
|
||||||
|
ss << "User - Agent: Wget / 1.11.4" << std::endl;
|
||||||
|
ss << "Connection: close" << std::endl;
|
||||||
|
ss << std::endl;
|
||||||
|
site << ss.str();
|
||||||
|
|
||||||
|
// read response
|
||||||
|
std::string version, statusMessage;
|
||||||
|
site >> version; // HTTP version
|
||||||
|
int status;
|
||||||
|
site >> status; // status
|
||||||
|
std::getline(site, statusMessage);
|
||||||
|
if (status == 200) // OK
|
||||||
|
{
|
||||||
|
std::string header;
|
||||||
|
while (std::getline(site, header) && header != "\r"){}
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << site.rdbuf();
|
||||||
|
content = ss.str();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint("HTTP response ", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint("Can't connect to proxy");
|
||||||
|
return 408;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& ex)
|
||||||
|
{
|
||||||
|
LogPrint("Failed to download ", address, " : ", ex.what());
|
||||||
|
return 408;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
url::url(const std::string& url_s)
|
url::url(const std::string& url_s)
|
||||||
{
|
{
|
||||||
|
portstr_ = "80";
|
||||||
|
port_ = 80;
|
||||||
|
user_ = "";
|
||||||
|
pass_ = "";
|
||||||
|
|
||||||
parse(url_s);
|
parse(url_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
util.h
10
util.h
|
@ -35,16 +35,18 @@ namespace util
|
||||||
namespace http
|
namespace http
|
||||||
{
|
{
|
||||||
std::string httpRequest(const std::string& address);
|
std::string httpRequest(const std::string& address);
|
||||||
|
int httpRequestViaI2pProxy(const std::string& address, std::string &content); // return http code
|
||||||
|
|
||||||
struct url {
|
struct url {
|
||||||
url(const std::string& url_s); // omitted copy, ==, accessors, ...
|
url(const std::string& url_s); // omitted copy, ==, accessors, ...
|
||||||
private:
|
private:
|
||||||
void parse(const std::string& url_s);
|
void parse(const std::string& url_s);
|
||||||
public:
|
public:
|
||||||
std::string protocol_, host_, path_, query_;
|
std::string protocol_, host_, path_, query_;
|
||||||
static std::string portstr_;
|
std::string portstr_;
|
||||||
static unsigned int port_;
|
unsigned int port_;
|
||||||
static std::string user_;
|
std::string user_;
|
||||||
static std::string pass_;
|
std::string pass_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue