Пример #1
0
        private void CloseServer(SocketData Data)
        {
#if ENABLEDEBUG
            lock (Data.Data.debug)
                Data.Data.debug.Add("CloseServer SocketData");
#endif


            try
            {
                if (Data.Data.CurrentServer == Data)
                {
                    Data.Data.Host = "";
                }

                Data.ServerSocket.Shutdown(SocketShutdown.Both);
                Data.ServerSocket.Disconnect(false);
                Data.ServerSocket.Close();
                Data.ServerSocket.Dispose();
            }
            catch
            {
            }
        }
Пример #2
0
        private void ProcessServerHeader(SocketData Data, byte[] Header, int Len)
        {
            Data.Chunked   = false;
            Data.KeepAlive = Data.Data.KeepAlive;

#if ENABLEDEBUG
            lock (Data.Data.debug)
                Data.Data.debug.Add("ProcessServerHeader");
#endif
            string header = Encoding.ASCII.GetString(Header, 0, Len);
#if ENABLEDEBUG
            Data.Data.responseheaders.Add(header);
#endif
            string[] lines = header.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            int contentLength = -1;

            foreach (string linea in lines)
            {
                string llinea = linea.ToLower();

                if (llinea.StartsWith("content-length:"))
                {
                    string[] partes = linea.Split(':');

                    if (partes.Length != 2 || !int.TryParse(partes[1], out contentLength))
                    {
                        continue;
                    }
                }
                else if (llinea.StartsWith("connection:"))
                {
                    string[] partes = linea.Split(':');

                    if (partes.Length != 2)
                    {
                        continue;
                    }

                    if (partes[1].Trim().ToLower() == "keep-alive")
                    {
                        Data.KeepAlive = Data.Data.KeepAlive;
                    }
                    else
                    {
                        Data.KeepAlive = false;
                    }
                }
                else if (llinea.StartsWith("transfer-encoding:"))
                {
                    string[] partes = linea.Split(':');

                    if (partes.Length != 2)
                    {
                        continue;
                    }

                    if (partes[1].Trim().ToLower() == "chunked")
                    {
                        contentLength = 0;
                        Data.Chunked  = true;
                    }
                }
            }

            ///Si se cierra una conexión de servidor, es una conexión SSL y es KeepAlive
            ///se debería comenzar otro request??

            Data.ResponseLeft = contentLength;

            byte[] data;

            foreach (string s in lines)
            {
                if (s.StartsWith("proxy"))
                {
                    continue;
                }

                data = Encoding.ASCII.GetBytes(s + "\r\n");
                Data.Data.ClientSocket.Send(data);
#if ENABLEDEBUG
                ClientSent(data, Data.Data);
#endif
            }

            data = Encoding.ASCII.GetBytes("\r\n");
            Data.Data.ClientSocket.Send(data);
#if ENABLEDEBUG
            ClientSent(data, Data.Data);
#endif

            if (Data.Chunked)
            {
                string tam = "";

                int leidos = 0;

                while (!tam.EndsWith("\r\n"))
                {
                    leidos = Data.ServerSocket.Receive(Data.ServerBuffer, 1, SocketFlags.None);

                    if (leidos == 0)
                    {
                        throw new Exception();
                    }

                    tam += Encoding.ASCII.GetString(Data.ServerBuffer, 0, 1);
                }

                int tamChunk = int.Parse(tam.Substring(0, tam.Length - 2), System.Globalization.NumberStyles.HexNumber);

                Data.Data.ClientSocket.Send(Encoding.ASCII.GetBytes(tam));

#if ENABLEDEBUG
                ClientSent(Encoding.ASCII.GetBytes(tam), Data.Data);
#endif

                Data.ResponseLeft = contentLength = tamChunk;

                if (tamChunk == 0)
                {
                    leidos = Data.ServerSocket.Receive(Data.ServerBuffer, 1, SocketFlags.None);

                    if (leidos == 0)
                    {
                        throw new Exception();
                    }

                    leidos = Data.ServerSocket.Receive(Data.ServerBuffer, 1, 1, SocketFlags.None);

                    if (leidos == 0)
                    {
                        throw new Exception();
                    }

                    Data.Data.ClientSocket.Send(Data.ServerBuffer, 2, SocketFlags.None);
#if ENABLEDEBUG
                    ClientSent(Data.ServerBuffer, 2, Data.Data);
#endif
                }
            }

            string[] response = lines[0].Split(' ');

            int responseCode = int.Parse(response[1]);

            if ((responseCode > 99 && responseCode < 200) || responseCode == 204 || responseCode == 304)
            {
                contentLength = 0;
            }
            else if (contentLength == -1 && Data.Data.KeepAlive)
            {
                Data.Data.KeepAlive = Data.KeepAlive = false;
            }

            if (contentLength != 0)
            {
                BeginRelayServer(Data);
            }
            else
            {
                BeginReadServerHeader(Data);
            }
        }
Пример #3
0
        //Si estamos recibiendo un Header del servidor, por mucho que sea KeepAlive se cierra para que se
        //entere el servidor a no ser que se cierre por un swapeo
        //
        //->//MAL!!
        //->//Desde el relay se vuelve a lanzar el ReadServer, puede que haga falta encapsular el socket y la query en
        //->//otro objeto para poder cambiar referencias
        void EndReadServerHeader(IAsyncResult Result)
        {
            SocketData sckData = (SocketData)Result.AsyncState;

            if (sckData != sckData.Data.CurrentServer)
            {
                try
                {
                    sckData.ServerSocket.EndReceive(Result);
                }
                catch { }
                try
                {
                    CloseServer(sckData);
                }
                catch { }

                return;
            }

            ProxyData Data = sckData.Data;

#if ENABLEDEBUG
            lock (Data.debug)
                Data.debug.Add("EndReadServerHeader");
#endif
            try
            {
                int leidos = sckData.ServerSocket.EndReceive(Result);

                if (leidos == 0)
                {
                    CloseServer(sckData);

                    if (!Data.ClosedBySwap && Data.RequestLeft != 0)
                    {
                        CloseClient(Data);
                    }
                    else
                    {
                        Data.ClosedBySwap = false;
                    }

                    return;
                }


                byte[] endBuffer = new Byte[4096];

                bool gotHeader = false;
                int  pos       = 0;

                while (leidos > 0 && !gotHeader)
                {
#if ENABLEDEBUG
                    Data.serverReceived.AddRange(sckData.ServerBuffer.Take(leidos));
#endif
                    Buffer.BlockCopy(sckData.ServerBuffer, 0, endBuffer, pos, leidos);
                    pos += leidos;

                    if (pos > 4)
                    {
                        //HasTrail
                        gotHeader = endBuffer[pos - 4] == trail[0] &&
                                    endBuffer[pos - 3] == trail[1] &&
                                    endBuffer[pos - 2] == trail[2] &&
                                    endBuffer[pos - 1] == trail[3];

                        if (!gotHeader)
                        {
                            leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 0, 1, SocketFlags.None);
                        }
                        else
                        {
                            ProcessServerHeader(sckData, endBuffer, pos);
                        }
                    }
                    else
                    {
                        leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 0, 1, SocketFlags.None);
                    }
                }
            }
            catch
            {
                CloseServer(sckData);

                if (!Data.ClosedBySwap && Data.RequestLeft != 0)
                {
                    CloseClient(Data);
                }
                else
                {
                    Data.ClosedBySwap = false;
                }
            }
        }
Пример #4
0
        public override void ProcessRequest(GusServer.GusServerRequest Request)
        {
            string currentHost = Request.Method.ToLower() == "connect" ? Request.Path : Request.RequestHeaders["Host"];

            string[] address = currentHost.Split(':');

            Socket socket;

            ManualResetEvent evt;
            ProxyData        bdata = null;

            try
            {
                string sport = "80";

                if (address.Length == 1)
                {
                    if (Request.Method.ToLower() == "connect")
                    {
                        sport = "443";
                    }
                }
                else
                {
                    sport = address[1];
                }

                socket = CreateSocket(address[0], int.Parse(sport));

                evt = new ManualResetEvent(false);

                bdata = new ProxyData {
                    ClientSocket = Request.Processor.Socket, Event = evt, Host = currentHost, SourceRequest = Request, KeepAlive = Request.Method.ToLower() != "connect"
                };

                SocketData sckData = new SocketData {
                    Data = bdata, ServerSocket = socket
                };
                bdata.CurrentServer = sckData;

                if (Request.RequestHeaders.ContainsKey("Proxy-Connection") && Request.RequestHeaders["Proxy-Connection"].ToLower() != "keep-alive")
                {
                    bdata.KeepAlive = false;
                }

                if (Request.RequestHeaders.ContainsKey("Connection") && Request.RequestHeaders["Connection"].ToLower() != "keep-alive")
                {
                    bdata.KeepAlive = false;
                }


#if ENABLEDEBUG
                bdata.ProxyKeepAlive = bdata.KeepAlive;
#endif

                if (Request.Method.ToLower() == "connect")
                {
                    bdata.SSL            = true;
                    bdata.RequestLeft    = -1;
                    sckData.ResponseLeft = -1;
                    bdata.KeepAlive      = false;
                }

                if (bdata.SSL)
                {
                    byte[] okdata = Encoding.ASCII.GetBytes(Request.ProtocolVersion + " 200 Connection established\r\nProxy-Agent: GusNet.GusBridge Server\r\n\r\n");
                    bdata.ClientSocket.Send(okdata, 0, okdata.Length, SocketFlags.None);
                }
                else
                {
                    byte[] header = ReconstructRequest(Request, bdata);
#if ENABLEDEBUG
                    bdata.requestheaders.Add("Original\r\n" + Encoding.ASCII.GetString(Request.Processor.OriginalRequest) + "Enviada\r\n" + Encoding.ASCII.GetString(header));
#endif
                    socket.Send(header, SocketFlags.None);

                    if (!string.IsNullOrEmpty(Request.Processor.PostDataFile))
                    {
                        Stream str    = File.OpenRead(Request.Processor.PostDataFile);
                        int    leidos = str.Read(bdata.ClientBuffer, 0, bdata.ClientBuffer.Length);

                        while (leidos > 0)
                        {
                            socket.Send(bdata.ClientBuffer, leidos, SocketFlags.None);
                            leidos = str.Read(bdata.ClientBuffer, 0, bdata.ClientBuffer.Length);
                        }

                        str.Close();
                    }
                }

                if (bdata.SSL)
                {
                    BeginRelayClient(bdata);
                }
                else
                {
                    BeginReadClientHeader(bdata);
                }

                if (bdata.SSL)
                {
                    BeginRelayServer(sckData);
                }
                else
                {
                    BeginReadServerHeader(sckData);
                }

#if ENABLEDEBUG
                //Para poder poner Breakpoints en peticiones que se están ejecutando
                while (!evt.WaitOne(10))
                {
                }
                DebugData(bdata);
#else
                evt.WaitOne();
#endif
            }
            catch
            { }
        }
Пример #5
0
        private void EndRelayServer(IAsyncResult Result)
        {
            SocketData sckData = (SocketData)Result.AsyncState;

            if (sckData != sckData.Data.CurrentServer)
            {
                try
                {
                    sckData.ServerSocket.EndReceive(Result);
                }
                catch { }

                try
                {
                    sckData.ServerSocket.Shutdown(SocketShutdown.Both);
                    sckData.ServerSocket.Disconnect(false);
                    sckData.ServerSocket.Close();
                    sckData.ServerSocket.Dispose();
                }
                catch { }

                return;
            }

            ProxyData Data = sckData.Data;

#if ENABLEDEBUG
            lock (Data.debug)
                Data.debug.Add("EndRelayServer");
#endif
            try
            {
                int leidos = sckData.ServerSocket.EndReceive(Result);

                if (leidos == 0)
                {
                    CloseServer(Data);

                    if (!Data.KeepAlive || sckData.ResponseLeft != 0)
                    {
                        CloseClient(Data);
                    }

                    return;
                }
#if ENABLEDEBUG
                Data.serverReceived.AddRange(sckData.ServerBuffer.Take(leidos));
#endif

                int enviados = 0;
                //OJ
                if (sckData.ResponseLeft == -1)
                {
                    Data.ClientSocket.Send(sckData.ServerBuffer, 0, leidos, SocketFlags.None);
                }
                else
                {
                    enviados = Data.ClientSocket.Send(sckData.ServerBuffer, 0, Math.Min(leidos, sckData.ResponseLeft), SocketFlags.None);
#if ENABLEDEBUG
                    ClientSent(sckData.ServerBuffer, 0, Math.Min(leidos, sckData.ResponseLeft), Data);
#endif
                }

                int inicio    = sckData.ResponseLeft;
                int restantes = leidos - sckData.ResponseLeft;

                if (sckData.ResponseLeft > 0)
                {
                    sckData.ResponseLeft -= Math.Min(leidos, sckData.ResponseLeft);
                }



                if (sckData.ResponseLeft < 1 && Data.SourceRequest.Method.ToLower() != "connect" && (sckData.KeepAlive || Data.KeepAlive || sckData.Chunked))
                {
                    if (!sckData.Chunked)
                    {
                        BeginReadServerHeader(sckData);
                    }
                    else
                    {
                        string tam = "";
                        int    pos = inicio;

                        int tamChunk = -1;

newChunk:
                        //aqui se atrapa el \r\n anterior
                        while (restantes > 0 && (!tam.EndsWith("\r\n") || tam.Length < 3))
                        {
                            restantes--;
                            tam += Encoding.ASCII.GetString(sckData.ServerBuffer, pos, 1);
                            pos++;
                        }

                        while (!tam.EndsWith("\r\n") || tam.Length < 3)
                        {
                            leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 1, SocketFlags.None);

                            if (leidos == 0)
                            {
                                throw new Exception();
                            }

                            tam += Encoding.ASCII.GetString(sckData.ServerBuffer, 0, 1);
                        }

                        tamChunk = int.Parse(tam.Substring(2, tam.Length - 4), System.Globalization.NumberStyles.HexNumber);

                        bool lastChunk = tamChunk == 0;

                        Data.ClientSocket.Send(Encoding.ASCII.GetBytes(tam));
#if ENABLEDEBUG
                        ClientSent(Encoding.ASCII.GetBytes(tam), Data);
#endif
                        if (restantes > 0)
                        {
                            if (restantes >= tamChunk)
                            {
                                Data.ClientSocket.Send(sckData.ServerBuffer, pos, tamChunk, SocketFlags.None);
#if ENABLEDEBUG
                                ClientSent(sckData.ServerBuffer, pos, tamChunk, Data);
#endif
                                restantes -= tamChunk;
                                pos       += tamChunk;
                                tam        = "";

                                if (lastChunk)
                                {
                                    if (restantes >= 2)
                                    {
                                        Data.ClientSocket.Send(sckData.ServerBuffer, pos, 2, SocketFlags.None);
#if ENABLEDEBUG
                                        ClientSent(sckData.ServerBuffer, pos, 2, Data);
#endif
                                    }
                                    else if (restantes > 0)
                                    {
                                        Data.ClientSocket.Send(sckData.ServerBuffer, pos, 1, SocketFlags.None);
#if ENABLEDEBUG
                                        ClientSent(sckData.ServerBuffer, pos, 1, Data);
#endif

                                        leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 1, SocketFlags.None);

                                        if (leidos == 0)
                                        {
                                            throw new Exception();
                                        }

                                        Data.ClientSocket.Send(sckData.ServerBuffer, 0, 1, SocketFlags.None);
#if ENABLEDEBUG
                                        ClientSent(sckData.ServerBuffer, 0, 1, Data);
#endif
                                    }
                                    else
                                    {
                                        leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 1, SocketFlags.None);

                                        if (leidos == 0)
                                        {
                                            throw new Exception();
                                        }

                                        Data.ClientSocket.Send(sckData.ServerBuffer, 0, 1, SocketFlags.None);
#if ENABLEDEBUG
                                        ClientSent(sckData.ServerBuffer, 0, 1, Data);
#endif

                                        leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 1, SocketFlags.None);

                                        if (leidos == 0)
                                        {
                                            throw new Exception();
                                        }

                                        Data.ClientSocket.Send(sckData.ServerBuffer, 0, 1, SocketFlags.None);
#if ENABLEDEBUG
                                        ClientSent(sckData.ServerBuffer, 0, 1, Data);
#endif
                                    }

                                    if (restantes > 2)
                                    {
                                        throw new Exception();
                                    }

                                    lastChunk = false;

                                    BeginReadServerHeader(sckData);

                                    return;
                                }
                                else
                                {
                                    goto newChunk;
                                }
                            }

                            tamChunk -= Math.Min(restantes, tamChunk);

                            Data.ClientSocket.Send(sckData.ServerBuffer, pos, restantes, SocketFlags.None);
#if ENABLEDEBUG
                            ClientSent(sckData.ServerBuffer, pos, restantes, Data);
#endif
                        }

                        sckData.ResponseLeft = tamChunk;

                        if (lastChunk)
                        {
                            leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 1, SocketFlags.None);

                            if (leidos == 0)
                            {
                                throw new Exception();
                            }

                            leidos = sckData.ServerSocket.Receive(sckData.ServerBuffer, 1, 1, SocketFlags.None);

                            if (leidos == 0)
                            {
                                throw new Exception();
                            }

                            Data.ClientSocket.Send(sckData.ServerBuffer, 2, SocketFlags.None);
#if ENABLEDEBUG
                            ClientSent(sckData.ServerBuffer, 2, Data);
#endif
                            BeginReadServerHeader(sckData);
                        }
                        else
                        {
                            BeginRelayServer(sckData);
                        }
                    }
                }
                else
                {
                    BeginRelayServer(sckData);
                }
            }
            catch
            {
                CloseServer(sckData);

                if (!Data.KeepAlive || sckData.ResponseLeft != 0)
                {
                    CloseClient(Data);
                }
            }
        }