I've looked around links related. I can't find any. Help me, please. Here's my code.(VS2010)

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://whatismyipaddress.com/");
        request.Proxy = new WebProxy("127.0.0.1:9150");
        request.KeepAlive = false;

        try
        {
            using (var response = request.GetResponse())
            {
                using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
                {
                    string temp = reader.ReadToEnd();
                    MessageBox.Show(temp);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

That brings error message like this. (501) Not implemented.

And Tor says.

Socks version 71 not recognized.(Tor is not a http proxy)

What's wrong?Someone help me.

有帮助吗?

解决方案

Unfortunately after some digging TOR is not a HTTP Proxy. It's a SOCKS proxy, you can use something like Privoxy that allows sock forwarding.

using Tor as Proxy

How to use Privoxy with TOR: http://www.privoxy.org/faq/misc.html#TOR

其他提示

I created the following class (HttpOverSocksProxy) to route my http requests through to the Tor socks proxy.

It does this by:

  1. listening on a local port (eg 127.0.0.1:9091) for incoming http requests
  2. grabs the host from the headers of these requests
  3. opens up a connection through Tor to this host
  4. copys all data (GET\POST,headers,body) from the source connection through to the Tor connection and visa versa
  5. Http requests are then made as you have done above but with the WebProxy set to the http\socks proxy in the above case this would be 127.0.0.1:9091

Note that https requests are not supported, you will recieve a 400 error from the webserver

I am using the Mentalis class ProxySocket to wrap up the Socks connection as a standard Socket http://www.mentalis.org/soft/class.qpx?id=9

This code has not being thoroughly tested but so far it works fine.

HttpOverSocksProxy Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;
using Org.Mentalis.Network.ProxySocket;
using System.IO;

namespace ConsoleApplication1
{
    /*
     * HTTPS is not supported, it will probably result in a (400) 'Bad Request' response. 
     */

    public class HttpOverSocksProxy
    {
        private class Connection
        {
            public IPLocation host_loc;
            public bool host_found = false;
            public bool host_connected = false; //if have_found==true && host_connected==false then we are currently connecting to the host
            public long host_last_read_pos = 0;

            public NetworkStream client_stream = null;
            public TcpClient client_tcp = null;

            public NetworkStream host_stream = null;
            public ProxySocket host_socket = null;

            public byte[] client_buf_ary = null;
            public byte[] host_buf_ary = null;
            public MemoryStream buf_str = null;

            public Connection(NetworkStream str,TcpClient client,int buffer_size)
            {
                this.client_stream = str;
                this.client_tcp = client;
                this.host_buf_ary = new byte[buffer_size];
                this.client_buf_ary = new byte[buffer_size];
                this.buf_str = new MemoryStream(buffer_size);
            }
        }

        private struct IPLocation
        {
            public string host;
            public int port;

            public IPLocation(string host, int port)
            {
                this.host = host;
                this.port = port;
            }
        }

        private TcpListener _tcp_server;
        private List<Connection> _connections = new List<Connection>();

        public IPEndPoint EndPoint_Source_Http { get; private set; }
        public IPEndPoint EndPoint_Destination_Socks { get; private set; }
        public ProxyTypes SocksProxyType { get; private set; }
        public int Buffer_Size { get; private set; }

        public HttpOverSocksProxy(IPEndPoint http_listen, IPEndPoint socks_proxy, ProxyTypes socks_proxy_type, int buffer_size = 1024*4)
        {
            this.EndPoint_Source_Http = http_listen;
            this.EndPoint_Destination_Socks = socks_proxy;
            this.SocksProxyType = socks_proxy_type;
            this.Buffer_Size = buffer_size;
        }

        public void Start()
        {
            _tcp_server = new TcpListener(EndPoint_Source_Http);
            _tcp_server.Start();
            _tcp_server.BeginAcceptTcpClient(Client_Accept, _tcp_server);
        }

        public void Stop()
        {
            lock (_connections)
            {
                _tcp_server.Stop();
                _connections.ForEach(a => Close(a));
                _connections.Clear();
            }
        }

        private void Client_Accept(IAsyncResult result)
        {
            TcpListener tcp_server = result.AsyncState as TcpListener;

            if (tcp_server != null)
            {
                TcpClient tcp_client = tcp_server.EndAcceptTcpClient(result);

                if (tcp_client != null)
                {
                    Connection conn = new Connection(tcp_client.GetStream(), tcp_client, Buffer_Size);

                    lock (_connections)
                    {
                        _connections.Add(conn);
                    }

                    conn.client_stream.BeginRead(conn.client_buf_ary, 0, Buffer_Size, Client_Write, conn);
                }

                tcp_server.BeginAcceptTcpClient(Client_Accept, tcp_server);
            }
        }

        private void Client_Write(IAsyncResult result)
        {
            Connection conn = result.AsyncState as Connection;

            if (conn != null)
            {
                try
                {
                    int len = conn.client_stream.EndRead(result);

                    if (len == 0) // Client has closed the connection
                    {
                        Close(conn);
                    }
                    else
                    {
                        lock (conn)
                        {
                            if (conn.host_connected)
                            {
                                try
                                {
                                    conn.host_stream.Write(conn.client_buf_ary, 0, len); //we want this to block
                                }
                                catch (Exception e_h)
                                {
                                    if (!Handle_Disposed(e_h, conn))
                                        throw;
                                }
                            }
                            else
                                conn.buf_str.Write(conn.client_buf_ary, 0, len);

                            if (!conn.host_found)
                                OpenHostConnection(conn);

                            conn.client_stream.BeginRead(conn.client_buf_ary, 0, Buffer_Size, Client_Write, conn);
                        }
                    }
                }
                catch (Exception e_c)
                {
                    if (!Handle_Disposed(e_c, conn))
                        throw;
                }
            }
        }

        private void OpenHostConnection(Connection conn)
        {
            if (conn.host_found)
                throw new Exception("Already have host");   //should never happen

            #region Get Host from headers
            {
                MemoryStream str_mem = conn.buf_str;
                str_mem.Position = conn.host_last_read_pos;

                string raw_host_line;
                while ((raw_host_line = ReadLine(str_mem, ASCIIEncoding.ASCII)) != null)
                {
                    conn.host_last_read_pos = str_mem.Position;

                    if (raw_host_line.Length == 0)
                        throw new Exception("Failed to find Host in request headers");

                    int idx_split;
                    if ((idx_split = raw_host_line.IndexOf(':')) > 0 && idx_split < raw_host_line.Length)
                    {
                        string key = raw_host_line.Substring(0, idx_split);
                        string val = raw_host_line.Substring(idx_split + 1).Trim();

                        if (key.Equals("host", StringComparison.InvariantCultureIgnoreCase))
                        {
                            string[] host_parts = val.Split(':');

                            if (host_parts.Length == 1)
                            {
                                conn.host_loc = new IPLocation(host_parts[0], 80);
                            }
                            else if (host_parts.Length == 2)
                            {
                                conn.host_loc = new IPLocation(host_parts[0], Int32.Parse(host_parts[1]));
                            }
                            else
                                throw new Exception(String.Format("Failed to parse HOST from '{0}'", raw_host_line));

                            conn.host_found = true;
                        }
                    }
                }

                str_mem.Seek(0,SeekOrigin.End);
            }
            #endregion

            #region Open Host Connection
            {
                if (conn.host_found)
                {
                    try
                    {
                        ProxySocket skt = new ProxySocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        skt.ProxyEndPoint = EndPoint_Destination_Socks;
                        skt.ProxyType = ProxyTypes.Socks5;
                        conn.host_socket = skt;

                        if (conn.host_loc.port == 443)
                            Console.WriteLine("HTTPS is not suported.");

                        skt.BeginConnect(conn.host_loc.host, conn.host_loc.port, Host_Connected, conn);
                    }
                    catch (ObjectDisposedException e)
                    {
                        if (!Handle_Disposed(e, conn))
                            throw;
                    }
                }
            }
            #endregion
        }

        private void Host_Connected(IAsyncResult result)
        {
            Connection conn = result.AsyncState as Connection;

            if (conn != null)
            {
                lock (conn) //Need to set up variables and empty buffer, cant have the Client writing to the host stream during this time
                {
                    try
                    {
                        conn.host_socket.EndConnect(result);
                        conn.host_stream = new NetworkStream(conn.host_socket);
                        conn.host_connected = true;

                        conn.buf_str.Position = 0;
                        conn.buf_str.CopyTo(conn.host_stream);

                        conn.host_stream.BeginRead(conn.host_buf_ary, 0, Buffer_Size, Host_Write, conn);
                    }
                    catch (Exception e)
                    {
                        if (!Handle_Disposed(e, conn))
                            throw;
                    }
                }
            }
        }

        private void Host_Write(IAsyncResult result)
        {
            Connection conn = result.AsyncState as Connection;

            if (conn != null)
            {
                try
                {
                    int len = conn.host_stream.EndRead(result);

                    if (len == 0)
                    {
                        Close(conn);
                    }
                    else
                    {
                        try
                        {
                            conn.client_stream.Write(conn.host_buf_ary, 0, len);    //we want this to block
                        }
                        catch (Exception e_c)
                        {
                            if (!Handle_Disposed(e_c, conn))
                                throw;
                        }

                        conn.host_stream.BeginRead(conn.host_buf_ary, 0, Buffer_Size, Host_Write, conn);
                    }
                }
                catch (Exception e_h)
                {
                    if (!Handle_Disposed(e_h, conn))
                        throw;
                }
            }
        }

        private void Close(Connection conn)
        {
            lock (conn)
            {
                try
                {
                    if (conn.host_connected)
                        conn.host_socket.Close();
                }
                catch { }
                try
                {
                    conn.client_tcp.Close();
                }
                catch { }
            }
        }

        private bool Handle_Disposed(Exception exp,Connection conn)
        {
            if (exp is ObjectDisposedException || (exp.InnerException != null && exp.InnerException is ObjectDisposedException))
            {
                Close(conn);
                return true;
            }
            else
                return false;
        }

        private string ReadLine(MemoryStream str,Encoding encoding)    // Reads a line terminated by \r\n else returns resets postion and returns null
        {
            long idxA= str.Position;    //first position of line
            long idxB =-1;  //position after last char

            int b_last = str.ReadByte();
            int b_this = 0;

            for (long i = 1; i < str.Length; i++)
            {
                b_this = str.ReadByte();

                if (b_this == '\n' && b_last == '\r')
                {
                    idxB = str.Position;
                    str.Position = idxA;

                    int len = (int)(idxB - idxA);
                    byte[] buf = new byte[len];
                    str.Read(buf, 0, len);

                    return encoding.GetString(buf);
                }
                else
                    b_last = b_this;
            }

            str.Position = idxA;
            return null;
        }
    }
}

Example Usage:

static void Main(string[] args)
{
    IPAddress localhost = IPAddress.Parse("127.0.0.1");

    IPEndPoint src_http = new IPEndPoint(localhost, 9091);
    IPEndPoint des_tor = new IPEndPoint(localhost, 9050);

    HttpOverSocksProxy proxy = new HttpOverSocksProxy(src_http, des_tor, ProxyTypes.Socks5);
    proxy.Start();

    WebClientExt client = new WebClientExt();
    client.Proxy = new WebProxy(src_http.ToString(), false);
    string res = client.DownloadString("http://en.wikipedia.org/wiki/HTTP_compression");

    Console.WriteLine(res);

    Console.WriteLine("Done");
    Console.ReadKey();
}

I had to make small modifications to the class ProxySocket so that the async calls retuned my state object. Not sure why it didn't already.

I can't post the updated code due to a character limit but I can describe them quickly enough: In ProxySocket.BeginConnect set this.State = state In ProxySocket.OnHandShakeComplete set AsyncResult.AsyncState = State. The property IAsyncProxyResult.AsyncState was updated so the there was a setter with privacy 'internal'

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top