예제 #1
0
        private bool ValidateClientRequest(TTFSHTTPRequestParser request)
        {
            // Parser checked a lot of stuff already, but we need to make sure it is fully parsed
            if (!request.ReceivedFullRequest)
            {
                return(false);
            }

            // Client should not be allowed to specify a path outside the ttfspath
            string fullPath = Path.GetFullPath(Path.Combine(ttfsPath, request.RequestTargetPath));

            if (!fullPath.StartsWith(ttfsPath, StringComparison.Ordinal))
            {
                return(false);
            }

            // Hosts should match
            if (!hostAddress.Equals(request.HostEndPoint.Address) || !localPort.Equals(request.HostEndPoint.Port))
            {
                return(false);
            }

            // Seems to be an ok request
            return(true);
        }
예제 #2
0
        private async Task HandleClientAsync(TcpClient client, EndPoint remoteEndPoint, RenegadeDispatcher dispatcher, CancellationToken cancellationToken)
        {
            try
            {
                TTFSHTTPRequestParser requestParser = new TTFSHTTPRequestParser(ClientGetRequestBufferSize);

                NetworkStream clientStream = client.GetStream();

                while (!requestParser.IsBufferFull && !cancellationToken.IsCancellationRequested)
                {
                    TTFSHTTPReadResult readResult = await requestParser.ReadAsync(clientStream, cancellationToken);

                    if (readResult == TTFSHTTPReadResult.PeerSocketClosed)
                    {
                        // We're done here, client closed connection
                        return;
                    }

                    // We've succesfully parsed the entire request, or it was invalid
                    if (readResult == TTFSHTTPReadResult.Done || readResult == TTFSHTTPReadResult.InvalidData)
                    {
                        break;
                    }
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    // We're done here

                    return;
                }

                if (ValidateClientRequest(requestParser))
                {
                    await SendFileToClient(client, remoteEndPoint, requestParser.RequestTargetPath, dispatcher, cancellationToken);
                }
                else
                {
                    // Client did something wrong
                    await SendBadRequestResponse(client, remoteEndPoint, dispatcher, cancellationToken);
                }
            }
            catch (SocketException ex)
            {
                if (
                    ex.SocketErrorCode == SocketError.Interrupted ||
                    ex.SocketErrorCode == SocketError.ConnectionAborted ||
                    ex.SocketErrorCode == SocketError.ConnectionRefused ||
                    ex.SocketErrorCode == SocketError.ConnectionReset)
                {
                    throw new OperationCanceledException();
                }
                else
                {
                    dispatcher.InvokeAsync(() =>
                    {
                        Engine.ConsoleOutput($"[{nameof(PackageServer)}]: Client {remoteEndPoint} triggered internal server error '{ex.Message}'\n");
                    });
                }
            }
            catch (ObjectDisposedException) when(cancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException();
            }
        }