Example #1
0
        public void DataRecvHandler(ref SelectControl control, Socket sock, Buf safeBuffer)
        {
            Socket otherSocket = (sock == serverSocket) ? clientSocket : serverSocket;

            int bytesReceived = sock.ReceiveNoThrow(safeBuffer.array, 0, safeBuffer.array.Length, SocketFlags.None);

            if (bytesReceived <= 0)
            {
                if (otherSocket != null)
                {
                    otherSocket.ShutdownSafe();
                }
                control.RemoveReceiveSocket(sock);
                return;
            }

            if (otherSocket != null)
            {
                try
                {
                    otherSocket.Send(safeBuffer.array, bytesReceived, SocketFlags.None);
                    return;
                }
                catch (SocketException)
                {
                    sock.ShutdownSafe();
                    control.DisposeAndRemoveReceiveSocket(sock);
                }
            }
        }
Example #2
0
        public void TcpRecvHandler(ref SelectControl control, Socket sock, Buf safeBuffer)
        {
            int bytesReceived = sock.ReceiveNoThrow(safeBuffer.array, 0, safeBuffer.array.Length, SocketFlags.None);

            if (bytesReceived <= 0)
            {
                if (serverSocket != null)
                {
                    serverSocket.ShutdownSafe();
                }
                control.RemoveReceiveSocket(sock);
                return;
            }

            if (serverSocket != null)
            {
                try
                {
                    serverSocket.Send(safeBuffer.array, bytesReceived, SocketFlags.None);
                    return;
                }
                catch (SocketException)
                {
                    sock.ShutdownSafe();
                    control.DisposeAndRemoveReceiveSocket(sock);
                    return;
                }
            }

            httpHeaderBuilders.Append(Encoding.ASCII.GetString(safeBuffer.array, 0, bytesReceived));
            //
            // Check if you have received all the headers
            //
            Int32 totalLength = httpHeaderBuilders.Length;

            if (totalLength > 3)
            {
                if (
                    httpHeaderBuilders[totalLength - 1] == '\n' &&
                    (
                        (httpHeaderBuilders[totalLength - 2] == '\n') ||
                        (httpHeaderBuilders[totalLength - 2] == '\r' &&
                         httpHeaderBuilders[totalLength - 3] == '\n' &&
                         httpHeaderBuilders[totalLength - 4] == '\r'))
                    )
                {
                    String headers = httpHeaderBuilders.ToString();
                    httpHeaderBuilders = null;
                    HandleHeaders(ref control, sock, headers);
                }
            }
        }
Example #3
0
        public void TcpSocketRecvCallback(ref SelectControl control, Socket socket, Buf safeBuffer)
        {
            int bytesRead;

            try
            {
                bytesRead = socket.Receive(safeBuffer.array);
            }
            catch (SocketException)
            {
                bytesRead = -1;
            }
            if (bytesRead <= 0)
            {
                control.RemoveReceiveSocket(socket);
                return;
            }
            HandleData(socket, safeBuffer.array, 0, (uint)bytesRead);
        }
        public void HeaderRecvHandler(ref SelectControl selectControl, Socket clientSocket, Buf ignore)
        {
            builder.EnsureTotalCapacity(builder.contentLength + 128);

            UInt32 dataOffset;

            try
            {
                dataOffset = Http.ReadHttpHeaders(clientSocket, builder);
            }
            catch (Exception e)
            {
                if (WebServer.Logger != null)
                {
                    WebServer.Logger.WriteLine("[{0}] Closed: {1}", clientLogString, e.Message);
                }
                selectControl.RemoveReceiveSocket(clientSocket);
                return;
            }

            //
            // Parse the request
            //
            try
            {
                UInt32 parseOffset = 0;

                Slice httpMethod;
                httpMethod.offset = parseOffset;
                httpMethod.limit  = builder.bytes.IndexOfUInt32(parseOffset, dataOffset, (Byte)' ');
                if (httpMethod.limit == UInt32.MaxValue)
                {
                    throw new FormatException("Invalid request: no space after HTTP method");
                }
                parseOffset = (uint)httpMethod.limit + 1;

                Slice httpResource;
                httpResource.offset = parseOffset;
                httpResource.limit  = builder.bytes.IndexOfUInt32(parseOffset, dataOffset, (Byte)' ');
                if (httpResource.limit == UInt32.MaxValue)
                {
                    throw new FormatException("Invalid request: no space after HTTP resource");
                }
                parseOffset = (uint)httpResource.limit + 1;

                this.method   = httpMethod.Decode(builder.bytes);
                this.resource = httpResource.Decode(builder.bytes);

                headerContentLength = Http.GetContentLength(builder.bytes, 0, dataOffset);

                if (headerContentLength != UInt32.MaxValue)
                {
                    throw new NotImplementedException(String.Format("Content-Length {0} is not implemented", headerContentLength));
                }
            }
            catch (Exception e)
            {
                if (WebServer.Logger != null)
                {
                    WebServer.Logger.WriteLine("[{0}] InvalidRequest: {1}", clientLogString, e.Message);
                }
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
                selectControl.RemoveReceiveSocket(clientSocket);
                return;
            }

            if (WebServer.Logger != null)
            {
                WebServer.Logger.WriteLine("[{0}] {1} {2}", clientLogString, method, resource);
            }

            if (!method.Equals("GET"))
            {
                if (WebServer.Logger != null)
                {
                    WebServer.Logger.WriteLine("[{0}] Unsupported HTTP Method: {1}", clientLogString, method);
                }
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
                selectControl.RemoveReceiveSocket(clientSocket);
                return;
            }
            String filename = WebServer.HttpResourceToFile(resource);

            if (!File.Exists(filename))
            {
                clientSocket.Send(NotFound404);
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
                selectControl.RemoveReceiveSocket(clientSocket);
                return;
            }


            builder.Clear();
            FileInfo fileInfo   = new FileInfo(filename);
            Int64    fileLength = fileInfo.Length;

            builder.AppendAscii("HTTP/1.1 200 OK\r\nContent-Length: ");
            builder.AppendAscii(fileLength.ToString());
            builder.AppendAscii("\r\n\r\n");
            using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                UInt32 bufferLeft = (uint)builder.bytes.Length - builder.contentLength;

                if (fileLength <= bufferLeft)
                {
                    fileStream.ReadFullSize(builder.bytes, (int)builder.contentLength, (int)fileLength);
                    clientSocket.Send(builder.bytes, 0, (int)(builder.contentLength + fileLength), 0);
                }
                else
                {
                    Int64 fileLeft = fileLength;

                    fileStream.ReadFullSize(builder.bytes, (int)builder.contentLength, (int)bufferLeft);
                    clientSocket.Send(builder.bytes);
                    fileLeft -= bufferLeft;

                    while (fileLeft > builder.bytes.Length)
                    {
                        fileStream.ReadFullSize(builder.bytes, 0, builder.bytes.Length);
                        clientSocket.Send(builder.bytes);
                        fileLeft -= builder.bytes.Length;
                    }

                    if (fileLeft > 0)
                    {
                        fileStream.ReadFullSize(builder.bytes, 0, (int)fileLeft);
                        clientSocket.Send(builder.bytes, 0, (int)fileLeft, 0);
                    }
                }

                clientSocket.Close();
                selectControl.RemoveReceiveSocket(clientSocket);
            }
        }
Example #5
0
        void GotHeaders(ref SelectControl selectControl, Socket clientSocket, Byte[] headers, UInt32 totalLength)
        {
            String serverIPOrHost = null;
            UInt16 serverPort     = 0;

            try
            {
                serverIPOrHost = GetServerFromHeaders(out serverPort, out isConnect,
                                                      headers, ref headersLength, ref totalLength, clientLogString);
            }
            catch (Exception e)
            {
                if (AppLayerProxy.ErrorLogger != null)
                {
                    AppLayerProxy.ErrorLogger.WriteLine("{0} Failed to get server from HTTP Headers: {1}", clientLogString, e);
                }
            }

            if (serverIPOrHost == null)
            {
                selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket);
                return;
            }

            this.serverLogString = serverIPOrHost + ":" + serverPort.ToString();

            Boolean needToConnect;

            if (AppLayerProxy.ForwardProxy == null)
            {
                // TODO: Fix so this does not block during DNS resolution
                IPAddress serverIP;
                try
                {
                    serverIP = EndPoints.ParseIPOrResolveHost(serverIPOrHost, DnsPriority.IPv4ThenIPv6);
                }
                catch (SocketException)
                {
                    if (AppLayerProxy.ErrorLogger != null)
                    {
                        AppLayerProxy.ErrorLogger.WriteLine("{0} Failed to resolve server hostname '{1}'",
                                                            clientLogString, serverIPOrHost);
                    }
                    selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket);
                    return;
                }
                IPEndPoint serverEndPoint = new IPEndPoint(serverIP, serverPort);

                serverSocket          = new Socket(serverEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Blocking = false;
                needToConnect         = NonBlockingSocket.ConnectNonBlocking(serverSocket, serverEndPoint);
            }
            else
            {
                this.serverEndPointForProxy = new StringEndPoint(serverIPOrHost, serverPort);

                Console.WriteLine("[DEBUG] Connecting to proxy '{0}'", AppLayerProxy.ForwardProxy.host.CreateTargetString());
                serverSocket          = new Socket(AppLayerProxy.ForwardProxy.host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Blocking = false;
                throw new NotImplementedException();
                //needToConnect = NonBlockingSocket.ConnectNonBlocking(serverSocket, AppLayerProxy.ForwardProxy.endPoint);
            }

            //Console.WriteLine("[DEBUG] {0} > {1} Connecting...", clientLogString, serverLogString);
            if (needToConnect)
            {
                selectControl.RemoveReceiveSocket(clientSocket); // Remove the clientSocket from the read list
                                                                 // until the connection gets established or lost
                selectControl.AddConnectSocket(serverSocket, ServerSocketConnected);

                // Save Data
                if (isConnect)
                {
                    if (totalLength == headersLength)
                    {
                        clientBuffer = null; // Clean up the client buffer (if there is one)
                    }
                }
                else
                {
                    if (clientBuffer == null)
                    {
                        clientBuffer = new ByteBuilder(totalLength);
                        Array.Copy(headers, clientBuffer.bytes, totalLength);
                        clientBuffer.contentLength = totalLength;
                    }
                    else
                    {
                        // Data already in the client buffer
                    }
                }
            }
            else
            {
                if (AppLayerProxy.Logger != null)
                {
                    AppLayerProxy.Logger.WriteLine("{0} > {1} Connection Completed Synchronously (CornerCase)", clientLogString, serverLogString);
                }

                if (!clientSocket.Connected)
                {
                    selectControl.DisposeAndRemoveReceiveSocket(clientSocket);
                    if (serverSocket.Connected)
                    {
                        if (AppLayerProxy.Logger != null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Server Connected but Client Disconnected...Closing Server", clientLogString, serverLogString);
                        }
                        try { serverSocket.Shutdown(SocketShutdown.Both); }
                        catch (Exception) { }
                    }
                    else
                    {
                        if (AppLayerProxy.Logger != null)
                        {
                            AppLayerProxy.Logger.WriteLine("{0} > {1} Client disconnected before server could connect", clientLogString, serverLogString);
                        }
                    }
                    serverSocket.Close();
                }
                else if (!serverSocket.Connected)
                {
                    if (AppLayerProxy.Logger != null)
                    {
                        AppLayerProxy.Logger.WriteLine("{0} > {1} Failed to connect to server..Closing Client", clientLogString, serverLogString);
                    }
                    selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket);
                    serverSocket.Close();
                }
                else
                {
                    if (AppLayerProxy.Logger != null)
                    {
                        AppLayerProxy.Logger.WriteLine("{0} > {1} Connected to Server", clientLogString, serverLogString);
                    }

                    if (isConnect)
                    {
                        uint extraChars = totalLength - headersLength;
                        FinishConnection(headers, headersLength, extraChars);
                    }
                    else
                    {
                        FinishConnection(headers, 0, totalLength);
                    }

                    TcpBridge bridge = new TcpBridge(clientLogString, clientSocket, serverLogString, serverSocket);
                    selectControl.UpdateHandler(clientSocket, bridge.ReceiveHandler);
                    selectControl.AddReceiveSocket(serverSocket, bridge.ReceiveHandler);
                }
            }
        }