specify keys file for proxy's local destination

This commit is contained in:
orignal 2015-03-17 11:44:01 -04:00
parent 028e3a6c35
commit a09c67772c
6 changed files with 209 additions and 134 deletions

View file

@ -18,9 +18,11 @@ namespace i2p
namespace proxy
{
static const size_t http_buffer_size = 8192;
class HTTPProxyHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this<HTTPProxyHandler> {
class HTTPProxyHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this<HTTPProxyHandler>
{
private:
enum state {
enum state
{
GET_METHOD,
GET_HOSTNAME,
GET_HTTPV,
@ -53,6 +55,7 @@ namespace proxy
state m_state;//Parsing state
public:
HTTPProxyHandler(HTTPProxyServer * parent, boost::asio::ip::tcp::socket * sock) :
I2PServiceHandler(parent), m_sock(sock)
{ EnterState(GET_METHOD); }
@ -92,7 +95,8 @@ namespace proxy
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
}
void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate) {
void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate)
{
m_state = nstate;
}
@ -104,11 +108,10 @@ namespace proxy
boost::regex rHTTP("http://(.*?)(:(\\d+))?(/.*)");
boost::smatch m;
std::string path;
if(boost::regex_search(m_url, m, rHTTP, boost::match_extra)) {
if(boost::regex_search(m_url, m, rHTTP, boost::match_extra))
{
server=m[1].str();
if(m[2].str() != "") {
port=m[3].str();
}
if (m[2].str() != "") port=m[3].str();
path=m[4].str();
}
LogPrint(eLogDebug,"--- HTTP Proxy server is: ",server, " port is: ", port, "\n path is: ",path);
@ -117,8 +120,10 @@ namespace proxy
m_path = path;
}
bool HTTPProxyHandler::ValidateHTTPRequest() {
if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" ) {
bool HTTPProxyHandler::ValidateHTTPRequest()
{
if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" )
{
LogPrint(eLogError,"--- HTTP Proxy unsupported version: ", m_version);
HTTPRequestFailed(); //TODO: send right stuff
return false;
@ -126,7 +131,8 @@ namespace proxy
return true;
}
void HTTPProxyHandler::HandleJumpServices() {
void HTTPProxyHandler::HandleJumpServices()
{
static const char * helpermark1 = "?i2paddresshelper=";
static const char * helpermark2 = "&i2paddresshelper=";
size_t addressHelperPos1 = m_path.rfind (helpermark1);
@ -157,7 +163,8 @@ namespace proxy
m_path.erase(addressHelperPos);
}
bool HTTPProxyHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len) {
bool HTTPProxyHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len)
{
ExtractRequest(); //TODO: parse earlier
if (!ValidateHTTPRequest()) return false;
HandleJumpServices();
@ -176,36 +183,42 @@ namespace proxy
bool HTTPProxyHandler::HandleData(uint8_t *http_buff, std::size_t len)
{
assert(len); // This should always be called with a least a byte left to parse
while (len > 0) {
while (len > 0)
{
//TODO: fallback to finding HOst: header if needed
switch (m_state) {
switch (m_state)
{
case GET_METHOD:
switch (*http_buff) {
switch (*http_buff)
{
case ' ': EnterState(GET_HOSTNAME); break;
default: m_method.push_back(*http_buff); break;
}
break;
break;
case GET_HOSTNAME:
switch (*http_buff) {
switch (*http_buff)
{
case ' ': EnterState(GET_HTTPV); break;
default: m_url.push_back(*http_buff); break;
}
break;
break;
case GET_HTTPV:
switch (*http_buff) {
switch (*http_buff)
{
case '\r': EnterState(GET_HTTPVNL); break;
default: m_version.push_back(*http_buff); break;
}
break;
break;
case GET_HTTPVNL:
switch (*http_buff) {
switch (*http_buff)
{
case '\n': EnterState(DONE); break;
default:
LogPrint(eLogError,"--- HTTP Proxy rejected invalid request ending with: ", ((int)*http_buff));
HTTPRequestFailed(); //TODO: add correct code
return false;
}
break;
break;
default:
LogPrint(eLogError,"--- HTTP Proxy invalid state: ", m_state);
HTTPRequestFailed(); //TODO: add correct code 500
@ -222,29 +235,33 @@ namespace proxy
void HTTPProxyHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len)
{
LogPrint(eLogDebug,"--- HTTP Proxy sock recv: ", len);
if(ecode) {
if(ecode)
{
LogPrint(eLogWarning," --- HTTP Proxy sock recv got error: ", ecode);
Terminate();
return;
}
if (HandleData(m_http_buff, len)) {
if (m_state == DONE) {
if (HandleData(m_http_buff, len))
{
if (m_state == DONE)
{
LogPrint(eLogInfo,"--- HTTP Proxy requested: ", m_url);
GetOwner()->CreateStream (std::bind (&HTTPProxyHandler::HandleStreamRequestComplete,
shared_from_this(), std::placeholders::_1), m_address, m_port);
} else {
}
else
AsyncSockRead();
}
}
}
void HTTPProxyHandler::SentHTTPFailed(const boost::system::error_code & ecode)
{
if (!ecode) {
if (!ecode)
Terminate();
} else {
else
{
LogPrint (eLogError,"--- HTTP Proxy Closing socket after sending failure because: ", ecode.message ());
Terminate();
}
@ -252,21 +269,24 @@ namespace proxy
void HTTPProxyHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
{
if (stream) {
if (stream)
{
if (Kill()) return;
LogPrint (eLogInfo,"--- HTTP Proxy New I2PTunnel connection");
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
GetOwner()->AddHandler (connection);
connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
Done(shared_from_this());
} else {
}
else
{
LogPrint (eLogError,"--- HTTP Proxy Issue when creating the stream, check the previous warnings for more info.");
HTTPRequestFailed(); // TODO: Send correct error message host unreachable
}
}
HTTPProxyServer::HTTPProxyServer(int port):
TCPIPAcceptor(port, i2p::client::context.GetSharedLocalDestination ())
HTTPProxyServer::HTTPProxyServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
TCPIPAcceptor(port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
{
}