Search code examples
c#proxytcpclient

TcpClient vs WebClient with CCProxy


I have This code :

        using (TcpClient tc = new TcpClient())
        {
            button1.Enabled = false;
            //string Data = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("user:123"));
            //tc.Connect("bot.whatismyipaddress.com", 80);
            //tc.Connect("xxx.xx.xxx.xxx", 3128); external proxy works
            try
            {
                //tc.Connect("192.168.1.2", 808); internal proxy doesn't work
                using (NetworkStream ns = tc.GetStream())
                {
                    using (StreamWriter sw = new StreamWriter(ns))
                    {
                        using (StreamReader sr = new StreamReader(ns))
                        {
                            sw.Write(@"GET / HTTP/1.1
Host: bot.whatismyipaddress.com
Connection: close
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36 OPR/28.0.1750.40
DNT: 1
Accept-Encoding: gzip, deflate, lzma, sdch
Accept-Language: en-US,en;q=0.8

");
                            sw.Flush();
                            string Res = sr.ReadToEnd();
                            richTextBox1.Text = Res;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                richTextBox1.Text = ex.Message;
            }
            button1.Enabled = true;
        }
    }

Which working great with any external proxy URL, but I want to try the authentication part so I used CCProxy then I realized that the code doesn't work with local CCProxy (although the WebClient works well) , the TcpClient respond is totally empty.

I don't know how it can work externally and doesn't internally ! [edit] Is there a way to test the authentication other than ccproxy?


Solution

  • Ok Here is the answer

    byte[] buffer = new byte[2048];
            int bytes;
            using (TcpClient tc = new TcpClient("192.168.1.2", 808))
            {                
                button1.Enabled = false;                
                NetworkStream stream = tc.GetStream();
    
                // Establish Tcp tunnel
                byte[] tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:80  HTTP/1.1\r\nHost: {0}\r\n\r\n", "bot.whatismyipaddress.com"));
                stream.Write(tunnelRequest, 0, tunnelRequest.Length);
                stream.Flush();
    
                // Read response to CONNECT request
                bytes = stream.Read(buffer, 0, buffer.Length);
                richTextBox1.Text  = Encoding.UTF8.GetString(buffer, 0, bytes);
                // Establish Get
                tunnelRequest = Encoding.UTF8.GetBytes(String.Format(@"GET / HTTP/1.1
    Host: bot.whatismyipaddress.com
    Connection: close
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36 OPR/28.0.1750.40
    DNT: 1
    Accept-Encoding: gzip, deflate, lzma, sdch
    Accept-Language: en-US,en;q=0.8
    
    "));
                stream.Write(tunnelRequest, 0, tunnelRequest.Length);
                stream.Flush();
                bytes = stream.Read(buffer, 0, buffer.Length);
                richTextBox1.Text += Encoding.UTF8.GetString(buffer, 0, bytes);
                button1.Enabled = true;
    

    I have to 'CONNECT' the proxy first to open connection through it then I send the 'GET' as usual. and to implement the user and pass (Basic authorization)

    string Data = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("user:123"));
    byte[] tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:80  HTTP/1.1\r\nHost: {0}\r\nProxy-Authorization: Basic {1}\r\n\r\n", "bot.whatismyipaddress.com", Data));