Browse Source

Merge pull request #66 from chertov/master

http status code, load host.txt via proxy
pull/70/head
orignal 11 years ago
parent
commit
4cbc7773ac
  1. 15
      AddressBook.cpp
  2. 61
      HTTPServer.cpp
  3. 4
      HTTPServer.h
  4. 1
      Win32/.gitignore
  5. 6
      Win32/i2pd.vcxproj
  6. 81
      Win32/inno_installer.iss
  7. 67
      util.cpp
  8. 10
      util.h

15
AddressBook.cpp

@ -33,18 +33,13 @@ const IdentHash * AddressBook::FindAddress (const std::string& address) @@ -33,18 +33,13 @@ const IdentHash * AddressBook::FindAddress (const std::string& address)
void AddressBook::LoadHostsFromI2P ()
{
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)
{
content = i2p::util::http::httpRequest(url_ss.str());
// TODO: check http errors
if (! boost::starts_with(content, "<html>") && content.size() > 0)
break;
// TODO: hosts link in config
int http_code = i2p::util::http::httpRequestViaI2pProxy("http://udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p/hosts.txt", content);
if (http_code ==200)
if (!boost::starts_with(content, "<html>") && !content.empty()) // TODO: test and remove
break;
std::this_thread::sleep_for(std::chrono::seconds(5));
}

61
HTTPServer.cpp

@ -118,12 +118,26 @@ namespace util @@ -118,12 +118,26 @@ namespace util
} // 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;
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)
{
header& h = headers[i];
@ -311,27 +325,40 @@ namespace util @@ -311,27 +325,40 @@ namespace util
{
i2p::data::IdentHash destination;
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 (!addr)
if (i2p::data::Base32ToByteStream(address.c_str(), address.length() - strlen(".b32.i2p"), (uint8_t *)destination, 32) != 32)
{
LogPrint ("Unknown address ", address);
SendReply ("<html>" + itoopieImage + "<br>Unknown address " + address + "</html>");
LogPrint ("Invalid Base32 address ", address);
SendReply ("<html>" + itoopieImage + "<br>Invalid Base32 address", 400);
return;
}
destination = *addr;
fullAddress = address;
}
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);
SendReply ("<html>" + itoopieImage + "<br>Invalid Base32 address");
return;
auto addr = i2p::data::netdb.FindAddress(address);
if (!addr)
{
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);
@ -342,7 +369,7 @@ namespace util @@ -342,7 +369,7 @@ namespace util
leaseSet = i2p::data::netdb.FindLeaseSet (destination);
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;
}
}
@ -375,13 +402,13 @@ namespace util @@ -375,13 +402,13 @@ namespace util
else
{
if (m_Stream && m_Stream->IsOpen ())
SendReply ("<html>" + itoopieImage + "<br>Not responding</html>");
SendReply ("<html>" + itoopieImage + "<br>Not responding</html>", 504);
else
Terminate ();
}
}
void HTTPConnection::SendReply (const std::string& content)
void HTTPConnection::SendReply (const std::string& content, int status)
{
m_Reply.content = content;
m_Reply.headers.resize(2);
@ -390,7 +417,7 @@ namespace util @@ -390,7 +417,7 @@ namespace util
m_Reply.headers[1].name = "Content-Type";
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::asio::placeholders::error));
}

4
HTTPServer.h

@ -36,7 +36,7 @@ namespace util @@ -36,7 +36,7 @@ namespace util
std::vector<header> headers;
std::string content;
std::vector<boost::asio::const_buffer> to_buffers();
std::vector<boost::asio::const_buffer> to_buffers (int status);
};
public:
@ -53,7 +53,7 @@ namespace util @@ -53,7 +53,7 @@ namespace util
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleWriteReply(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 FillContent (std::stringstream& s);

1
Win32/.gitignore vendored

@ -5,4 +5,5 @@ @@ -5,4 +5,5 @@
!*.vcproj
!*.vcxproj
!*.vcxproj.filters
!*.iss
!.gitignore

6
Win32/i2pd.vcxproj

@ -106,8 +106,9 @@ @@ -106,8 +106,9 @@
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>.\boost;.\cryptopp;$(IncludePath)</IncludePath>
<LibraryPath>.\stage-x86\lib;$(LibraryPath)</LibraryPath>
<IncludePath>./..;$(BOOST);$(CRYPTOPP);$(IncludePath)</IncludePath>
<LibraryPath>$(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\Win32\Output\$(Configuration)\;$(LibraryPath)</LibraryPath>
<SourcePath>./..;$(VC_SourcePath);</SourcePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -134,6 +135,7 @@ @@ -134,6 +135,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>cryptlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

81
Win32/inno_installer.iss

@ -0,0 +1,81 @@ @@ -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

@ -249,13 +249,72 @@ namespace http @@ -249,13 +249,72 @@ namespace http
}
}
std::string url::portstr_ = "80";
unsigned int url::port_ = 80;
std::string url::user_ = "";
std::string url::pass_ = "";
int httpRequestViaI2pProxy(const std::string& address, std::string &content)
{
content = "";
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)
{
portstr_ = "80";
port_ = 80;
user_ = "";
pass_ = "";
parse(url_s);
}

10
util.h

@ -35,16 +35,18 @@ namespace util @@ -35,16 +35,18 @@ namespace util
namespace http
{
std::string httpRequest(const std::string& address);
int httpRequestViaI2pProxy(const std::string& address, std::string &content); // return http code
struct url {
url(const std::string& url_s); // omitted copy, ==, accessors, ...
private:
void parse(const std::string& url_s);
public:
std::string protocol_, host_, path_, query_;
static std::string portstr_;
static unsigned int port_;
static std::string user_;
static std::string pass_;
std::string portstr_;
unsigned int port_;
std::string user_;
std::string pass_;
};
}
}

Loading…
Cancel
Save