From bff3d8f5c1660d199f3fd80b92e6e9a5553f098d Mon Sep 17 00:00:00 2001 From: Mikal Villa Date: Wed, 16 Jul 2014 18:41:40 +0200 Subject: [PATCH] Prepare support for POST/PUT --- HTTPServer.cpp | 112 +++++++++++++++++++++++++++---------------------- HTTPServer.h | 26 ++++++------ 2 files changed, 75 insertions(+), 63 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 038f6321..98ac5950 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -13,7 +13,7 @@ namespace i2p namespace util { - const std::string HTTPConnection::itoopieImage = + const std::string HTTPConnection::itoopieImage = "\"\""; - - namespace misc_strings + + namespace misc_strings { const char name_value_separator[] = { ':', ' ' }; @@ -146,7 +146,7 @@ namespace util buffers.push_back(boost::asio::buffer(misc_strings::crlf)); } buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - } + } buffers.push_back(boost::asio::buffer(content)); return buffers; } @@ -154,9 +154,9 @@ namespace util void HTTPConnection::Terminate () { if (m_Stream) - { + { m_Stream->Close (); - DeleteStream (m_Stream); + DeleteStream (m_Stream); } m_Socket->close (); delete this; @@ -193,11 +193,11 @@ namespace util { b32 = address.substr (1, pos - 1); // excluding leading '/' to next '/' uri = address.substr (pos); // rest of line - } + } - HandleDestinationRequest (b32, uri); - } - else + HandleDestinationRequest (b32, uri); + } + else HandleRequest (); } @@ -209,10 +209,10 @@ namespace util char * http = strstr (get, "HTTP"); if (http) return std::string (get + 4, http - get - 5); - } + } return ""; - } - + } + void HTTPConnection::HandleWriteReply (const boost::system::error_code& ecode) { Terminate (); @@ -233,7 +233,7 @@ namespace util FillContent (s); s << ""; SendReply (s.str ()); - } + } void HTTPConnection::FillContent (std::stringstream& s) { @@ -241,7 +241,7 @@ namespace util s << "Our external address:" << "
"; for (auto& address : i2p::context.GetRouterInfo().GetAddresses()) { - switch (address.transportStyle) + switch (address.transportStyle) { case i2p::data::RouterInfo::eTransportNTCP: s << "NTCP  "; @@ -257,31 +257,31 @@ namespace util s << "
Routers: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
"; - + s << "

Tunnels

"; for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ()) - { + { it->GetTunnelConfig ()->Print (s); if (it->GetTunnelPool () && !it->GetTunnelPool ()->IsExploratory ()) s << " " << "Pool"; if (it->IsFailed ()) s << " " << "Failed"; s << " " << (int)it->GetNumSentBytes () << "
"; - } + } for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) - { + { it.second->GetTunnelConfig ()->Print (s); if (it.second->GetTunnelPool () && !it.second->GetTunnelPool ()->IsExploratory ()) s << " " << "Pool"; if (it.second->IsFailed ()) s << " " << "Failed"; s << " " << (int)it.second->GetNumReceivedBytes () << "
"; - } - + } + s << "

Transit tunnels

"; for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) - { + { if (dynamic_cast(it.second)) s << it.second->GetTunnelID () << "-->"; else if (dynamic_cast(it.second)) @@ -289,23 +289,23 @@ namespace util else s << "-->" << it.second->GetTunnelID () << "-->"; s << " " << it.second->GetNumTransmittedBytes () << "
"; - } + } s << "

Transports

"; s << "NTCP
"; for (auto it: i2p::transports.GetNTCPSessions ()) - { + { // RouterInfo of incoming connection doesn't have address bool outgoing = it.second->GetRemoteRouterInfo ().GetNTCPAddress (); if (it.second->IsEstablished ()) { if (outgoing) s << "-->"; - s << it.second->GetRemoteRouterInfo ().GetIdentHashAbbreviation () << ": " + s << it.second->GetRemoteRouterInfo ().GetIdentHashAbbreviation () << ": " << it.second->GetSocket ().remote_endpoint().address ().to_string (); if (!outgoing) s << "-->"; s << "
"; - } - } + } + } auto ssuServer = i2p::transports.GetSSUServer (); if (ssuServer) { @@ -319,12 +319,16 @@ namespace util s << endpoint.address ().to_string () << ":" << endpoint.port (); if (!outgoing) s << "-->"; s << "
"; - } - } + } + } s << "

Flibusta

"; - } - + } void HTTPConnection::HandleDestinationRequest (const std::string& address, const std::string& uri) + { + HandleDestinationRequest(address, "GET", "", uri); + } + + void HTTPConnection::HandleDestinationRequest (const std::string& address, const std::string& method, const std::string& data, const std::string& uri) { i2p::data::IdentHash destination; std::string fullAddress; @@ -363,7 +367,7 @@ namespace util fullAddress = address + ".b32.i2p"; } } - + auto leaseSet = i2p::data::netdb.FindLeaseSet (destination); if (!leaseSet || !leaseSet->HasNonExpiredLeases ()) { @@ -374,23 +378,29 @@ namespace util { SendReply (leaseSet ? "" + itoopieImage + "
Leases expired" : "" + itoopieImage + "LeaseSet not found", 504); return; - } + } } - if (!m_Stream) + if (!m_Stream) m_Stream = i2p::stream::CreateStream (*leaseSet); if (m_Stream) { - std::string request = "GET " + uri + " HTTP/1.1\n Host:" + fullAddress + "\n"; - m_Stream->Send ((uint8_t *)request.c_str (), request.length (), 10); + std::string request = method+" " + uri + " HTTP/1.1\n Host:" + fullAddress + "\r\n"; + if (!strcmp(method.c_str(), "GET")) + { + // POST/PUT, apply body + request += "\r\n"+ data; + } + LogPrint("HTTP Client Request: ", request); + m_Stream->Send ((uint8_t *)request.c_str (), request.length (), 10); AsyncStreamReceive (); - } - } - + } + } + void HTTPConnection::AsyncStreamReceive () { if (m_Stream) m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, 8192), - boost::bind (&HTTPConnection::HandleStreamReceive, this, + boost::bind (&HTTPConnection::HandleStreamReceive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred), 45); // 45 seconds timeout } @@ -408,7 +418,7 @@ namespace util SendReply ("" + itoopieImage + "
Not responding", 504); else Terminate (); - } + } } void HTTPConnection::SendReply (const std::string& content, int status) @@ -421,16 +431,16 @@ namespace util m_Reply.headers[1].value = "text/html"; 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)); } - - HTTPServer::HTTPServer (int port): - m_Thread (nullptr), m_Work (m_Service), + + HTTPServer::HTTPServer (int port): + m_Thread (nullptr), m_Work (m_Service), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), port)), m_NewSocket (nullptr) { - + } HTTPServer::~HTTPServer () @@ -450,17 +460,17 @@ namespace util m_Acceptor.close(); m_Service.stop (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = nullptr; - } + } } void HTTPServer::Run () { m_Service.run (); - } + } void HTTPServer::Accept () { @@ -476,7 +486,7 @@ namespace util CreateConnection(m_NewSocket); // new HTTPConnection(m_NewSocket); Accept (); } - } + } void HTTPServer::CreateConnection(boost::asio::ip::tcp::socket * m_NewSocket) { diff --git a/HTTPServer.h b/HTTPServer.h index cb594794..39c61070 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -14,13 +14,13 @@ namespace util class HTTPConnection { protected: - + struct header { std::string name; std::string value; }; - + struct request { std::string method; @@ -38,7 +38,7 @@ namespace util std::vector to_buffers (int status); }; - + public: HTTPConnection (boost::asio::ip::tcp::socket * socket): m_Socket (socket), m_Stream (nullptr) { Receive (); }; @@ -48,9 +48,9 @@ namespace util void Terminate (); void Receive (); - void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void AsyncStreamReceive (); - 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 HandleWrite (const boost::system::error_code& ecode); void SendReply (const std::string& content, int status = 200); @@ -58,9 +58,9 @@ namespace util void HandleRequest (); void FillContent (std::stringstream& s); std::string ExtractAddress (); - + protected: - + boost::asio::ip::tcp::socket * m_Socket; i2p::stream::Stream * m_Stream; char m_Buffer[8192], m_StreamBuffer[8192]; @@ -68,14 +68,16 @@ namespace util reply m_Reply; protected: - + + virtual void HandleDestinationRequest(const std::string& address, const std::string& uri); + virtual void HandleDestinationRequest(const std::string& address, const std::string& method, const std::string& data, const std::string& uri); virtual void RunRequest (); private: static const std::string itoopieImage; - }; + }; class HTTPServer { @@ -89,9 +91,9 @@ namespace util private: - void Run (); + void Run (); void Accept (); - void HandleAccept(const boost::system::error_code& ecode); + void HandleAccept(const boost::system::error_code& ecode); private: @@ -103,7 +105,7 @@ namespace util protected: virtual void CreateConnection(boost::asio::ip::tcp::socket * m_NewSocket); - }; + }; } }