Retrieving adress from browser for my proxy in cpp (boost::Asio)
<p>I'm trying to adapt a sample code of a TCP Proxy in order to use it on my browser.</p>

<p>Here is the complete proxy i use :</p>

<pre><code>#include &lt;cstdlib&gt;
#include &lt;cstddef&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;

#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/bind.hpp&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/thread/mutex.hpp&gt;


namespace tcp_proxy
{
   namespace ip = boost::asio::ip;

   class bridge : public boost::enable_shared_from_this&lt;bridge&gt;
   {
   public:

      typedef ip::tcp::socket socket_type;
      typedef boost::shared_ptr&lt;bridge&gt; ptr_type;

      bridge(boost::asio::io_service&amp; ios)
      : downstream_socket_(ios),
        upstream_socket_(ios)
      {}

      socket_type&amp; downstream_socket()
      {
         return downstream_socket_;
      }

      socket_type&amp; upstream_socket()
      {
         return upstream_socket_;
      }

      void start(const std::string&amp; upstream_host, unsigned short upstream_port)
      {
         upstream_socket_.async_connect(
              ip::tcp::endpoint(
                   boost::asio::ip::address::from_string(upstream_host),
                   upstream_port),
               boost::bind(&amp;bridge::handle_upstream_connect,
                    shared_from_this(),
                    boost::asio::placeholders::error));
      }

      void handle_upstream_connect(const boost::system::error_code&amp; error)
      {
         if (!error)
         {
            upstream_socket_.async_read_some(
                 boost::asio::buffer(upstream_data_,max_data_length),
                 boost::bind(&amp;bridge::handle_upstream_read,
                      shared_from_this(),
                      boost::asio::placeholders::error,
                      boost::asio::placeholders::bytes_transferred));

            downstream_socket_.async_read_some(
                 boost::asio::buffer(downstream_data_,max_data_length),
                 boost::bind(&amp;bridge::handle_downstream_read,
                      shared_from_this(),
                      boost::asio::placeholders::error,
                      boost::asio::placeholders::bytes_transferred));
         }
         else
            close();
      }

   private:

      void handle_downstream_write(const boost::system::error_code&amp; error)
      {
         if (!error)
         {
            upstream_socket_.async_read_some(
                 boost::asio::buffer(upstream_data_,max_data_length),
                 boost::bind(&amp;bridge::handle_upstream_read,
                      shared_from_this(),
                      boost::asio::placeholders::error,
                      boost::asio::placeholders::bytes_transferred));
         }
         else
            close();
      }

      void handle_downstream_read(const boost::system::error_code&amp; error,
                                  const size_t&amp; bytes_transferred)
      {
         if (!error)
         {
            async_write(upstream_socket_,
                  boost::asio::buffer(downstream_data_,bytes_transferred),
                  boost::bind(&amp;bridge::handle_upstream_write,
                        shared_from_this(),
                        boost::asio::placeholders::error));
         }
         else
            close();
      }

      void handle_upstream_write(const boost::system::error_code&amp; error)
      {
         if (!error)
         {
            downstream_socket_.async_read_some(
                 boost::asio::buffer(downstream_data_,max_data_length),
                 boost::bind(&amp;bridge::handle_downstream_read,
                      shared_from_this(),
                      boost::asio::placeholders::error,
                      boost::asio::placeholders::bytes_transferred));
         }
         else
            close();
      }

      void handle_upstream_read(const boost::system::error_code&amp; error,
                                const size_t&amp; bytes_transferred)
      {
         if (!error)
         {
            async_write(downstream_socket_,
                 boost::asio::buffer(upstream_data_,bytes_transferred),
                 boost::bind(&amp;bridge::handle_downstream_write,
                      shared_from_this(),
                      boost::asio::placeholders::error));
         }
         else
            close();
      }

      void close()
      {
         boost::mutex::scoped_lock lock(mutex_);

         if (downstream_socket_.is_open())
         {
            downstream_socket_.close();
         }

         if (upstream_socket_.is_open())
         {
            upstream_socket_.close();
         }
      }

      socket_type downstream_socket_;
      socket_type upstream_socket_;

      enum { max_data_length = 8192 }; //8KB
      unsigned char downstream_data_[max_data_length];
      unsigned char upstream_data_[max_data_length];

      boost::mutex mutex_;

   public:

      class acceptor
      {
      public:

         acceptor(boost::asio::io_service&amp; io_service,
                  const std::string&amp; local_host, unsigned short local_port,
                  const std::string&amp; upstream_host, unsigned short upstream_port)
         : io_service_(io_service),
           localhost_address(boost::asio::ip::address_v4::from_string(local_host)),
           acceptor_(io_service_,ip::tcp::endpoint(localhost_address,local_port)),
           upstream_port_(upstream_port),
           upstream_host_(upstream_host)
         {}

         bool accept_connections()
         {
            try
            {
               session_ = boost::shared_ptr&lt;bridge&gt;(new bridge(io_service_));

               acceptor_.async_accept(session_-&gt;downstream_socket(),
                    boost::bind(&amp;acceptor::handle_accept,
                         this,
                         boost::asio::placeholders::error));
            }
            catch(std::exception&amp; e)
            {
               std::cerr &lt;&lt; "acceptor exception: " &lt;&lt; e.what() &lt;&lt; std::endl;
               return false;
            }

            return true;
         }

      private:

         void handle_accept(const boost::system::error_code&amp; error)
         {
            if (!error)
            {
               session_-&gt;start(upstream_host_,upstream_port_);

               if (!accept_connections())
               {
                  std::cerr &lt;&lt; "Failure during call to accept." &lt;&lt; std::endl;
               }
            }
            else
            {
               std::cerr &lt;&lt; "Error: " &lt;&lt; error.message() &lt;&lt; std::endl;
            }
         }

         boost::asio::io_service&amp; io_service_;
         ip::address_v4 localhost_address;
         ip::tcp::acceptor acceptor_;
         ptr_type session_;
         unsigned short upstream_port_;
         std::string upstream_host_;
      };

   };
}

int main(int argc, char* argv[])
{
   if (argc != 5)
   {
      std::cerr &lt;&lt; "usage: tcpproxy_server &lt;local host ip&gt; &lt;local port&gt; &lt;forward host ip&gt; &lt;forward port&gt;" &lt;&lt; std::endl;
      return 1;
   }

   const unsigned short local_port   = static_cast&lt;unsigned short&gt;(::atoi(argv[2]));
   const unsigned short forward_port = static_cast&lt;unsigned short&gt;(::atoi(argv[4]));
   const std::string local_host      = argv[1];
   const std::string forward_host    = argv[3];

   boost::asio::io_service ios;

   try
   {
      tcp_proxy::bridge::acceptor acceptor(ios,
                                           local_host, local_port,
                                           forward_host, forward_port);

      acceptor.accept_connections();

      ios.run();
   }
   catch(std::exception&amp; e)
   {
      std::cerr &lt;&lt; "Error: " &lt;&lt; e.what() &lt;&lt; std::endl;
      return 1;
   }

   return 0;
}
</code></pre>

<p>Actually, this sample code need as args the local host and local port, and the forward port and the forward host.</p>

<p>I would like to edit this code in order to get automatically the host who is asked in the browser...</p>

<p>From my research i have to used the remote_endpoint() property.
The problem is i don't know how to implement it in order to "trigger" this function eachtime use ask for another adress on the browser...</p>

<p>I tried this :</p>

<pre><code>#include &lt;cstdlib&gt;
#include &lt;cstddef&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;

#include &lt;boost/shared_ptr.hpp&gt;
#include &lt;boost/enable_shared_from_this.hpp&gt;
#include &lt;boost/bind.hpp&gt;
#include &lt;boost/asio.hpp&gt;
#include &lt;boost/thread/mutex.hpp&gt;


namespace tcp_proxy
{
    namespace ip = boost::asio::ip;

    class bridge : public boost::enable_shared_from_this&lt;bridge&gt;
    {
    public:

        typedef ip::tcp::socket socket_type;
        typedef boost::shared_ptr&lt;bridge&gt; ptr_type;

        bridge(boost::asio::io_service&amp; ios)
            : downstream_socket_(ios),
            upstream_socket_(ios)
        {}

        socket_type&amp; downstream_socket()
        {
            return downstream_socket_;
        }

        socket_type&amp; upstream_socket()
        {
            return upstream_socket_;
        }

        void start(const std::string&amp; upstream_host, unsigned short upstream_port)
        {
            upstream_socket_.async_connect(
                ip::tcp::endpoint(
                    boost::asio::ip::address::from_string(upstream_host),
                    upstream_port),
                boost::bind(&amp;bridge::handle_upstream_connect,
                    shared_from_this(),
                    boost::asio::placeholders::error));
        }

        void handle_upstream_connect(const boost::system::error_code&amp; error)
        {
            if (!error)
            {
                upstream_socket_.async_read_some(
                    boost::asio::buffer(upstream_data_, max_data_length),
                    boost::bind(&amp;bridge::handle_upstream_read,
                        shared_from_this(),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));

                downstream_socket_.async_read_some(
                    boost::asio::buffer(downstream_data_, max_data_length),
                    boost::bind(&amp;bridge::handle_downstream_read,
                        shared_from_this(),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
            }
            else
                close();
        }

    private:

        void handle_downstream_write(const boost::system::error_code&amp; error)
        {
            if (!error)
            {
                upstream_socket_.async_read_some(
                    boost::asio::buffer(upstream_data_, max_data_length),
                    boost::bind(&amp;bridge::handle_upstream_read,
                        shared_from_this(),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
            }
            else
                close();
        }

        void handle_downstream_read(const boost::system::error_code&amp; error,
            const size_t&amp; bytes_transferred)
        {
            if (!error)
            {
                async_write(upstream_socket_,
                    boost::asio::buffer(downstream_data_, bytes_transferred),
                    boost::bind(&amp;bridge::handle_upstream_write,
                        shared_from_this(),
                        boost::asio::placeholders::error));
            }
            else
                close();
        }

        void handle_upstream_write(const boost::system::error_code&amp; error)
        {
            if (!error)
            {
                downstream_socket_.async_read_some(
                    boost::asio::buffer(downstream_data_, max_data_length),
                    boost::bind(&amp;bridge::handle_downstream_read,
                        shared_from_this(),
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred));
            }
            else
                close();
        }

        void handle_upstream_read(const boost::system::error_code&amp; error,
            const size_t&amp; bytes_transferred)
        {
            if (!error)
            {
                async_write(downstream_socket_,
                    boost::asio::buffer(upstream_data_, bytes_transferred),
                    boost::bind(&amp;bridge::handle_downstream_write,
                        shared_from_this(),
                        boost::asio::placeholders::error));
            }
            else
                close();
        }

        void close()
        {
            boost::mutex::scoped_lock lock(mutex_);

            if (downstream_socket_.is_open())
            {
                downstream_socket_.close();
            }

            if (upstream_socket_.is_open())
            {
                upstream_socket_.close();
            }
        }

        socket_type downstream_socket_;
        socket_type upstream_socket_;

        enum { max_data_length = 8192 }; //8KB
        unsigned char downstream_data_[max_data_length];
        unsigned char upstream_data_[max_data_length];

        boost::mutex mutex_;

    public:

        class acceptor
        {
        public:

            acceptor(boost::asio::io_service&amp; io_service,
                const std::string&amp; local_host, unsigned short local_port,
                const std::string&amp; upstream_host, unsigned short upstream_port)
                : io_service_(io_service),
                localhost_address(boost::asio::ip::address_v4::from_string(local_host)),
                acceptor_(io_service_, ip::tcp::endpoint(localhost_address, local_port)),
                upstream_port_(upstream_port),
                upstream_host_(upstream_host)
            {}

            bool accept_connections()
            {
                try
                {
                    session_ = boost::shared_ptr&lt;bridge&gt;(new bridge(io_service_));

                    acceptor_.async_accept(session_-&gt;downstream_socket(),
                        boost::bind(&amp;acceptor::handle_accept,
                            this,
                            boost::asio::placeholders::error));
                }
                catch (std::exception&amp; e)
                {
                    std::cerr &lt;&lt; "acceptor exception: " &lt;&lt; e.what() &lt;&lt; std::endl;
                    return false;
                }

                return true;
            }

        private:

            void handle_accept(const boost::system::error_code&amp; error)
            {
                if (!error)
                {
                    session_-&gt;start(upstream_host_, upstream_port_);

                    if (!accept_connections())
                    {
                        std::cerr &lt;&lt; "Failure during call to accept." &lt;&lt; std::endl;
                    }
                }
                else
                {
                    std::cerr &lt;&lt; "Error: " &lt;&lt; error.message() &lt;&lt; std::endl;
                }
            }

            boost::asio::io_service&amp; io_service_;
            ip::address_v4 localhost_address;
            ip::tcp::acceptor acceptor_;
            ptr_type session_;
            unsigned short upstream_port_;
            std::string upstream_host_;
        };

    };
}

int main(int argc, char* argv[])
{
    if (argc != 5)
    {
        std::cerr &lt;&lt; "usage: EvilProxy.exe &lt;local host ip&gt; &lt;local port&gt; &lt;forward host ip&gt; &lt;forward port&gt;" &lt;&lt; std::endl;
        return 1;
    }

    const unsigned short local_port = static_cast&lt;unsigned short&gt;(::atoi(argv[2]));
    const unsigned short forward_port = static_cast&lt;unsigned short&gt;(::atoi(argv[4]));
    const std::string local_host = argv[1];
    const std::string forward_host = argv[3];

    boost::asio::io_service ios;

    boost::system::error_code ec;

    boost::asio::ip::tcp::socket &amp;mySocket = tcp_proxy::bridge(ios).downstream_socket();

    try
    {

        std::string str_IpDest = mySocket.remote_endpoint().address().to_string(); // Here i try to get the adresse but with this code, the adresse is seeking only at the begining...it's too earl

        tcp_proxy::bridge::acceptor acceptor(ios,
            local_host, local_port,
            str_IpDest, forward_port);

        acceptor.accept_connections();

        ios.run();
    }
    catch (std::exception&amp; e)
    {
        std::cerr &lt;&lt; "Error: " &lt;&lt; e.what() &lt;&lt; std::endl;
        return 1;
    }

    return 0;
}
</code></pre>

<p>I'm doing this </p>

<pre><code>std::string str_IpDest = mySocket.remote_endpoint().address().to_string();
</code></pre>

<p>But it's called to earl, i don't know how to trigger it each time user ask another adress.</p>

<p>I use boost:asio.</p>

<p>Anyon can help me please ?
The goal...After is to use SSL...but...after :)</p>

<p>Thanks a lot :)</p>

<p>Regards</p>