Proxy

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;

namespace exProxy
{

    public partial class Form1 : Form
    {
        static int ThreadCount = 0;
        static string CRLF = Environment.NewLine;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread SocketMonitor = new Thread(MainWorker);
            SocketMonitor.IsBackground = true;
            SocketMonitor.Start();
        }

        private void ex(string s)
        {
            this.Invoke((MethodInvoker)delegate { Log.AppendText(s + Environment.NewLine); });
        }

        private void debug(string s)
        {
            //this.ex(s);
        }

        public void dump(byte[] buffer)
        {
            ex("=== DUMP =================================================");
            ex(Encoding.ASCII.GetString(buffer));
            ex("----------------------------------------------------------");
        }

        private void ThreadDelta(int Delta)
        {
            this.Invoke((MethodInvoker)delegate { ThreadCount += Delta; StatusLine.Text = ThreadCount.ToString() + " Threads"; });
        }

        private void MainWorker()
        {
            TcpListener Listener = new TcpListener(IPAddress.Any, 8888);
            Listener.Start();
            ex("Listener started on " + IPAddress.Loopback.ToString());

            try
            {
                while (true)
                {
                    Socket ClientSocket = Listener.AcceptSocket();

                    Thread T = new Thread(SocketProcessor);
                    T.IsBackground = true;
                    T.Start(ClientSocket);
                }
            }
            catch (Exception e) {
                ex("Server stopped. Exception: " + e.ToString());
            }

        }

        public bool ReadMessage(Socket S, ref MemoryStream BufferStream, ref MemoryStream MessageStream, ref String Host)
        {
            try
            {
                byte[] Buffer = new byte[S.ReceiveBufferSize];
                int BufferSize = 0;
                String DestinationHost = String.Empty;

                // Read Buffer to BufferStream
                BufferSize = S.Receive(Buffer);
                BufferStream.Write(Buffer, 0, BufferSize);

                // Convert to String
                String BufferString = Encoding.ASCII.GetString(BufferStream.ToArray(), 0, (int)BufferStream.Length);

                // Decode Head Block
                int HeaderDelimiterPosition = BufferString.IndexOf(CRLF + CRLF);
                if (HeaderDelimiterPosition > 0)
                {

                    int HeaderLength = HeaderDelimiterPosition > 0 ? HeaderDelimiterPosition + 2 * (CRLF.Length) : 0;
                    String Head = BufferString.Substring(0, HeaderLength);

                    // Decode Request Line
                    int RequestDelimiterPosition = Head.IndexOf(CRLF);
                    String RequestString = Head.Substring(0, RequestDelimiterPosition);
                    int DelimiterPosition1 = RequestString.IndexOf(' ');
                    String Method = RequestString.Substring(0, DelimiterPosition1);
                    int DelimiterPosition2 = RequestString.IndexOf(' ', DelimiterPosition1 + 1);
                    String URI = RequestString.Substring(DelimiterPosition1 + 1, DelimiterPosition2 - DelimiterPosition1);
                    String Version = RequestString.Substring(DelimiterPosition2 + 1);

                    if (Method == "GET" || Method == "POST")
                    {
                        // Use URI Class to decode Destination Host
                        try
                        {
                            Uri URIDecoder = new Uri(URI);
                            DestinationHost = URIDecoder.Host;
                            int DestinationPort = URIDecoder.Port;
                            Host = DestinationHost;
                        }
                        catch (UriFormatException e) { } // Cannot decode URI
                        ex(RequestString);
                    }
                    else if (Method == "HTTP/1.1" || Method == "HTTP/1.0")
                    {
                        ex(Method + " Reply StatusCode: " + URI + " Reason: " + Version);
                    }
                    else
                    {
                        ex("Unknown Method: " + RequestString);
                    }

                    // Decode Headers
                    Dictionary<String, String> Headers = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
                    int DelimiterOffset = RequestDelimiterPosition + CRLF.Length;
                    while (true)
                    {
                        int NextDelimiterPosition = Head.IndexOf(CRLF, DelimiterOffset);
                        if (NextDelimiterPosition > 0)
                        {
                            // Read Line (Token)
                            String Token = Head.Substring(DelimiterOffset, NextDelimiterPosition - DelimiterOffset);
                            // Decode single Header
                            int ColonPosition = Token.IndexOf(':');
                            if (ColonPosition > 0)
                                Headers.Add(Token.Substring(0, ColonPosition).Trim(), Token.Substring(ColonPosition + 1).Trim());
                            else { } // Bad Header
                            DelimiterOffset = NextDelimiterPosition + CRLF.Length;
                        }
                        else break;
                    }
                    // foreach (KeyValuePair<String, String> Header in Headers) ex(Header.Key + " : " + Header.Value); // Enumerate Headers

                    // Override Host if provided by Host-Header
                    if (Headers.ContainsKey("Host"))
                        DestinationHost = Headers["Host"];


                    // Get Message Length
                    int MessageBodyLength = 0;
                    if (Headers.ContainsKey("Content-Length"))
                    {
                        MessageBodyLength = Convert.ToInt32(Headers["Content-Length"]);
                    }
                    int TotalLength = HeaderLength + MessageBodyLength;

                    // Chunked Encoding
                    bool Chunked = false;
                    if (Headers.ContainsKey("Transfer-Encoding"))
                    {
                        Chunked = true;
                    }


                    if (Chunked)
                    {
                        int NextChunkSizeOffset = HeaderLength;

                        int ChunkSize = 0;
                        do
                        {
                            BufferString = Encoding.ASCII.GetString(BufferStream.ToArray(), 0, (int)BufferStream.Length);
                            int ChunkSizeDelimiter = BufferString.IndexOf(CRLF, NextChunkSizeOffset);
                            String ChunkSizeHex = BufferString.Substring(NextChunkSizeOffset, ChunkSizeDelimiter - NextChunkSizeOffset);
                            ChunkSize = Convert.ToInt32(ChunkSizeHex, 16);
                            if (ChunkSize > 0)
                            {
                                TotalLength += ChunkSizeHex.Length + CRLF.Length + ChunkSize + CRLF.Length;
                                NextChunkSizeOffset = TotalLength;
                            }
                            else
                            {
                                TotalLength += ChunkSizeHex.Length + CRLF.Length + CRLF.Length;
                            }

                            while (BufferStream.Length < TotalLength)
                            {
                                BufferSize = S.Receive(Buffer);
                                BufferStream.Write(Buffer, 0, BufferSize);
                            }
                        } while (ChunkSize > 0);
                    }
                    else
                    {
                        while (BufferStream.Length < TotalLength)
                        {
                            BufferSize = S.Receive(Buffer);
                            BufferStream.Write(Buffer, 0, BufferSize);
                        }
                    }

                    if (TotalLength <= BufferStream.Length)
                    {
                        MessageStream.Write(BufferStream.ToArray(), 0, TotalLength);
                        MemoryStream NewBufferStream = new MemoryStream();
                        NewBufferStream.Write(BufferStream.ToArray(), TotalLength, (int)BufferStream.Length - TotalLength);
                        BufferStream = NewBufferStream;
                    }
                }

                return true;
            }
            catch (SocketException e)
            {
                ex("Socket Esception: " + e.Message);
                return false;
            }
        }

        public void SocketProcessor(object SocketObject)
        {
            debug("Thread started.");
            ThreadDelta(+1);

            Socket ClientSocket = (Socket)SocketObject;

            MemoryStream Buffer = new MemoryStream();
            MemoryStream Request = new MemoryStream();
            MemoryStream ReceiveBuffer = new MemoryStream();
            String RemoteHost = String.Empty;

            // TRAFFIC EXCHANGE
            //try
            //{
                while (ClientSocket.Connected)
                {
                    Request = new MemoryStream();
                    ReadMessage(ClientSocket, ref Buffer, ref Request, ref RemoteHost);

                    try
                    {
                        // (RE)CONNECT
                        Socket ServerSocket = new Socket(ClientSocket.AddressFamily, ClientSocket.SocketType, ClientSocket.ProtocolType);
                        ServerSocket.Connect(RemoteHost, 80);
                        byte[] SendBuffer = Request.ToArray();
                        ServerSocket.Send(SendBuffer);

                        // GET REPLY
                        MemoryStream Reply = new MemoryStream();
                        ReadMessage(ServerSocket, ref ReceiveBuffer, ref Reply, ref RemoteHost);

                        // SEND REPLY TO CLIENT
                        ClientSocket.Send(Reply.GetBuffer());

                    }
                    catch (Exception e) {
                        ex("EXCEPTION: " + e.Message);
                        if (ClientSocket.Connected)
                        {
                            ClientSocket.Shutdown(SocketShutdown.Both);
                            ClientSocket.Close();
                        }
                    }

                }
            //}
            //catch (Exception e)
            //{
            //    ex("EXCEPTION: " + e.Message);
            //}

            if (ClientSocket.Connected) ClientSocket.Close();
            ThreadDelta(-1);
        }


    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值