Exemple #1
0
        public async Task <bool> ReuseConnectionAsync(FramingConnection connection, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(false);
            }

            if (!_connectionPoolSemaphore.Wait(0))
            {
                //if (DiagnosticUtility.ShouldTraceWarning)
                //{
                //    TraceUtility.TraceEvent(TraceEventType.Warning,
                //        TraceCode.ServerMaxPooledConnectionsQuotaReached,
                //        SR.GetString(SR.TraceCodeServerMaxPooledConnectionsQuotaReached, maxPooledConnections),
                //        new StringTraceRecord("MaxOutboundConnectionsPerEndpoint", maxPooledConnections.ToString(CultureInfo.InvariantCulture)),
                //        this, null);
                //}

                //if (TD.ServerMaxPooledConnectionsQuotaReachedIsEnabled())
                //{
                //    TD.ServerMaxPooledConnectionsQuotaReached();
                //}

                // No space left in the connection pool
                return(false);
            }

            try
            {
                connection.Reset();

                CancellationToken ct = new TimeoutHelper(_idleTimeout).GetCancellationToken();
                using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
                           new TimeoutHelper(_idleTimeout).GetCancellationToken(),
                           cancellationToken))
                {
                    System.IO.Pipelines.ReadResult readResult = await connection.Input.ReadAsync(linkedCts.Token);

                    connection.Input.AdvanceTo(readResult.Buffer.Start); // Don't consume any bytes. The pending read is to know when a new client connects.
                    if (readResult.Buffer.IsEmpty && !readResult.IsCompleted && !readResult.IsCanceled)
                    {
                        // After pending read is canceled, next ReadAsync can return immediately with a 0 byte response so another ReadAsync call is needed
                        readResult = await connection.Input.ReadAsync(linkedCts.Token);

                        connection.Input.AdvanceTo(readResult.Buffer.Start); // Don't consume any bytes. The pending read is to know when a new client connects.
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
            finally
            {
                _connectionPoolSemaphore.Release();
            }
        }
            public async Task <Message> ReceiveAsync(CancellationToken token)
            {
                // TODO: Apply timeouts
                Message message;
                ReadOnlySequence <byte> buffer = ReadOnlySequence <byte> .Empty;

                for (; ;)
                {
                    System.IO.Pipelines.ReadResult readResult = await _connection.Input.ReadAsync(token);

                    if (readResult.IsCompleted || readResult.Buffer.Length == 0)
                    {
                        if (!readResult.IsCompleted)
                        {
                            _connection.Input.AdvanceTo(readResult.Buffer.Start);
                        }

                        EnsureDecoderAtEof();
                        _connection.EOF = true;
                    }

                    if (_connection.EOF)
                    {
                        return(null);
                    }

                    buffer  = readResult.Buffer;
                    message = DecodeMessage(ref buffer);
                    _connection.Input.AdvanceTo(buffer.Start);

                    _connection.Logger.ReceivedMessage(message);
                    if (message != null)
                    {
                        PrepareMessage(message);
                        return(message);
                    }
                    else if (_connection.EOF) // could have read the END record under DecodeMessage
                    {
                        return(null);
                    }

                    if (buffer.Length != 0)
                    {
                        throw Fx.AssertAndThrow("Receive: DecodeMessage() should consume the outstanding buffer or return a message.");
                    }
                }
            }
Exemple #3
0
        public static async Task <string> GetRequestBody(this HttpContext context)
        {
            HttpRequest request     = context.Request;
            string      contentType = request.ContentType.ToLower();

            if (request.Method.ToLower() == "post" && (contentType == "json" || contentType == "application/json"))
            {
                request.Body.Seek(0, SeekOrigin.Begin);
                System.IO.Pipelines.ReadResult r = await request.BodyReader.ReadAsync();

                using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8))
                {
                    await reader.ReadToEndAsync();
                };
            }
            return(JsonConvert.SerializeObject(request.Query));
        }
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            var  decoder = new ServerSingletonDecoder(ConnectionOrientedTransportDefaults.MaxViaSize, ConnectionOrientedTransportDefaults.MaxContentTypeSize, connection.Logger);
            bool success = false;

            try
            {
                ReadOnlySequence <byte> buffer;
                while (decoder.CurrentState != ServerSingletonDecoder.State.PreUpgradeStart)
                {
                    System.IO.Pipelines.ReadResult readResult = await connection.Input.ReadAsync();

                    buffer = readResult.Buffer;

                    while (buffer.Length > 0)
                    {
                        int bytesDecoded = decoder.Decode(buffer);
                        if (bytesDecoded > 0)
                        {
                            buffer = buffer.Slice(bytesDecoded);
                        }

                        if (decoder.CurrentState == ServerSingletonDecoder.State.PreUpgradeStart)
                        {
                            // We now know the Via address (which endpoint the client is connecting to).
                            // The connection now needs to be handled by the correct endpoint which can
                            // handle upgrades etc.
                            break; //exit loop
                        }
                    }

                    connection.Input.AdvanceTo(buffer.Start);
                }

                success = true;
            }
            catch (CommunicationException exception)
            {
                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information);
            }
            catch (OperationCanceledException exception)
            {
                //if (TD.ReceiveTimeoutIsEnabled())
                //{
                //    TD.ReceiveTimeout(exception.Message);
                //}
                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information);
            }
            catch (TimeoutException exception)
            {
                //if (TD.ReceiveTimeoutIsEnabled())
                //{
                //    TD.ReceiveTimeout(exception.Message);
                //}
                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                if (!TransportExceptionHandler.HandleTransportExceptionHelper(e))
                {
                    throw;
                }
                // containment -- all exceptions abort the reader, no additional containment action necessary
            }
            finally
            {
                if (!success)
                {
                    // TODO: On .NET Framework, this Abort call via a long winding path of plumbing will trigger a new pending Accept
                    // as this connection establishment handshake has failed. Some back pressure mechanism needs to be implemented to
                    // stop extra incoming connection handshakes from being started. Maybe a semaphore which is async waited at initial
                    // incoming request and then released on completion of handshake or on an exception. It also closes the connection
                    // so that's all that's happening here for now. Returning and completing the task will cause the connection to be closed.
                    connection.Abort();
                }
            }

            if (success)
            {
                connection.FramingDecoder = decoder;
                await _next(connection);
            }
            // else:
            //   returning will close the connection if it hasn't already been.
        }
Exemple #5
0
 public abstract bool TryRead(out System.IO.Pipelines.ReadResult result);
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            bool success = false;

            try
            {
                var decoder = connection.FramingDecoder as ServerSessionDecoder;
                Fx.Assert(decoder != null, "FramingDecoder must be non-null and an instance of ServerSessionDecoder");
                // first validate our content type
                ValidateContentType(connection, decoder);

                // next read any potential upgrades and finish consuming the preamble
                ReadOnlySequence <byte> buffer;
                while (true)
                {
                    System.IO.Pipelines.ReadResult readResult = await connection.Input.ReadAsync();

                    buffer = readResult.Buffer;
                    if (readResult.IsCompleted)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(decoder.CreatePrematureEOFException());
                    }

                    while (buffer.Length > 0)
                    {
                        int bytesDecoded = decoder.Decode(buffer);
                        if (bytesDecoded > 0)
                        {
                            buffer = buffer.Slice(bytesDecoded);
                        }

                        switch (decoder.CurrentState)
                        {
                        case ServerSessionDecoder.State.UpgradeRequest:
                            ProcessUpgradeRequest(connection, decoder);

                            // accept upgrade
                            await connection.Output.WriteAsync(ServerSessionEncoder.UpgradeResponseBytes);

                            await connection.Output.FlushAsync();

                            //await context.Transport.Output.WriteAsync
                            //Connection.Write(ServerSessionEncoder.UpgradeResponseBytes, 0, ServerSessionEncoder.UpgradeResponseBytes.Length, true, timeoutHelper.RemainingTime());

                            try
                            {
                                connection.Input.AdvanceTo(buffer.Start);
                                buffer = ReadOnlySequence <byte> .Empty;
                                await UpgradeConnectionAsync(connection, decoder.Upgrade);

                                // TODO: ChannelBinding
                                //if (this.channelBindingProvider != null && this.channelBindingProvider.IsChannelBindingSupportEnabled)
                                //{
                                //    this.SetChannelBinding(this.channelBindingProvider.GetChannelBinding(this.upgradeAcceptor, ChannelBindingKind.Endpoint));
                                //}

                                //this.connectionBuffer = Connection.AsyncReadBuffer;
                            }
                            catch (Exception exception)
                            {
                                if (Fx.IsFatal(exception))
                                {
                                    throw;
                                }

                                // Audit Authentication Failure
                                //WriteAuditFailure(upgradeAcceptor as StreamSecurityUpgradeAcceptor, exception);
                                throw;
                            }
                            break;

                        case ServerSessionDecoder.State.Start:
                            SetupSecurityIfNecessary(connection);
                            // we've finished the preamble. Ack and continue to the next middleware.
                            await connection.Output.WriteAsync(ServerSessionEncoder.AckResponseBytes);

                            await connection.Output.FlushAsync();

                            connection.Input.AdvanceTo(buffer.Start);
                            await _next(connection);

                            success = true;
                            return;
                        }
                    }
                }
            }
            finally
            {
                if (!success)
                {
                    connection.Abort();
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// 处理浏览器
        /// </summary>
        /// <param name="browser"></param>
        /// <returns></returns>
        public static void ProcessBrowserAsync(ConnectionContext browser)
        {
            Task.Run(async() =>
            {
                //最终网站
                SocketConnect target = new SocketConnect();
                try
                {
                    while (true)
                    {
                        System.IO.Pipelines.ReadResult result = await browser.Transport.Input.ReadAsync();
                        if (!result.Buffer.IsEmpty)
                        {
                            var message = Message.ParsePack(result.Buffer.ToArray());
                            if (message.Item1 != null)
                            {
                                var data = message.Item1.Content;
                                //var data = Crypto.DecryptAES(message.Item1.Content);
                                Socket5Info socket5Info = new Socket5Info();
                                if (socket5Info.TryParse(data))
                                {
                                    await target.ConnectAsync(System.Text.Encoding.UTF8.GetString(socket5Info.Address), socket5Info.Port);
                                    //连接到服务器
                                    //var ipEndPoint = await GetIpEndPointAsync(System.Text.Encoding.UTF8.GetString(socket5Info.Address), socket5Info.Port);
                                    //if(ipEndPoint == null)
                                    //{
                                    //    break;
                                    //}

                                    //await target.ConnectAsync(ipEndPoint.Address,ipEndPoint.Port);

                                    byte[] sendData = new byte[] { 0x05, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x1f, 0x40 };
                                    //发送确认到浏览器

                                    await browser.Transport.Output.WriteAsync(sendData);

                                    ProcessTargetServer(browser, target);
                                }
                                else
                                {
                                    //发送数据到目标服务器
                                    await target.TcpClient.Client.SendAsync(data, SocketFlags.None);
                                }

                                browser.Transport.Input.AdvanceTo(result.Buffer.GetPosition(message.Item2));
                            }
                            else
                            {
                                browser.Transport.Input.AdvanceTo(result.Buffer.GetPosition(0));
                            }
                        }
                        else
                        {
                            if (result.IsCompleted || result.IsCanceled)
                            {
                                break;
                            }
                        }
                    }
                    await browser.Transport.Input.CompleteAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            });
        }
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            TimeSpan receiveTimeout = connection.ServiceDispatcher.Binding.ReceiveTimeout;
            var      timeoutHelper  = new TimeoutHelper(receiveTimeout);
            bool     success        = false;

            try
            {
                var decoder = connection.FramingDecoder as ServerSingletonDecoder;
                Fx.Assert(decoder != null, "FramingDecoder must be non-null and an instance of ServerSessionDecoder");

                // first validate our content type
                //ValidateContentType(connection, decoder);
                UpgradeState upgradeState = UpgradeState.None;
                // next read any potential upgrades and finish consuming the preamble
                ReadOnlySequence <byte> buffer = ReadOnlySequence <byte> .Empty;
                while (true)
                {
                    if (buffer.Length == 0 && CanReadAndDecode(upgradeState))
                    {
                        System.IO.Pipelines.ReadResult readResult = await connection.Input.ReadAsync();

                        buffer = readResult.Buffer;
                        if (readResult.IsCompleted)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(decoder.CreatePrematureEOFException());
                        }
                    }

                    while (true)
                    {
                        if (CanReadAndDecode(upgradeState))
                        {
                            Fx.Assert(buffer.Length > 0, "There must be something in the buffer to decode");
                            int bytesDecoded = decoder.Decode(buffer);
                            if (bytesDecoded > 0)
                            {
                                buffer = buffer.Slice(bytesDecoded);
                                if (buffer.Length == 0)
                                {
                                    connection.Input.AdvanceTo(buffer.Start);
                                }
                            }
                        }

                        switch (decoder.CurrentState)
                        {
                        case ServerSingletonDecoder.State.UpgradeRequest:
                            switch (upgradeState)
                            {
                            case UpgradeState.None:
                                //change the state so that we don't read/decode until it is safe
                                ChangeUpgradeState(ref upgradeState, UpgradeState.VerifyingUpgradeRequest);
                                break;

                            case UpgradeState.VerifyingUpgradeRequest:
                                if (connection.StreamUpgradeAcceptor == null)
                                {
                                    await connection.SendFaultAsync(FramingEncodingString.UpgradeInvalidFault, timeoutHelper.RemainingTime(), TransportDefaults.MaxDrainSize);

                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                              new ProtocolException(SR.Format(SR.UpgradeRequestToNonupgradableService, decoder.Upgrade)));
                                }

                                if (!connection.StreamUpgradeAcceptor.CanUpgrade(decoder.Upgrade))
                                {
                                    await connection.SendFaultAsync(FramingEncodingString.UpgradeInvalidFault, timeoutHelper.RemainingTime(), TransportDefaults.MaxDrainSize);

                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format(SR.UpgradeProtocolNotSupported, decoder.Upgrade)));
                                }

                                ChangeUpgradeState(ref upgradeState, UpgradeState.WritingUpgradeAck);
                                // accept upgrade
                                await connection.Output.WriteAsync(ServerSingletonEncoder.UpgradeResponseBytes, timeoutHelper.GetCancellationToken());

                                await connection.Output.FlushAsync(timeoutHelper.GetCancellationToken());

                                ChangeUpgradeState(ref upgradeState, UpgradeState.UpgradeAckSent);
                                break;

                            case UpgradeState.UpgradeAckSent:
                                // This state was used to capture any extra read bytes into PreReadConnection but we don't need to do that when using pipes.
                                // This extra state transition has been left here to maintain the same state transitions as on .NET Framework to make comparison easier.
                                ChangeUpgradeState(ref upgradeState, UpgradeState.BeginUpgrade);
                                break;

                            case UpgradeState.BeginUpgrade:
                                // Set input pipe so that the next read will return all the unconsumed bytes.
                                // If all bytes have already been consumed so the buffer has 0 length, AdvanceTo would throw
                                // as it's already been called.
                                if (buffer.Length > 0)
                                {
                                    connection.Input.AdvanceTo(buffer.Start);
                                }

                                buffer = ReadOnlySequence <byte> .Empty;
                                try
                                {
                                    await UpgradeConnectionAsync(connection, decoder.Upgrade);

                                    ChangeUpgradeState(ref upgradeState, UpgradeState.EndUpgrade);
                                }
                                catch (Exception exception)
                                {
                                    if (Fx.IsFatal(exception))
                                    {
                                        throw;
                                    }

                                    throw;
                                }
                                break;

                            case UpgradeState.EndUpgrade:
                                //Must be a different state here than UpgradeComplete so that we don't try to read from the connection
                                ChangeUpgradeState(ref upgradeState, UpgradeState.UpgradeComplete);
                                break;

                            case UpgradeState.UpgradeComplete:
                                //Client is doing more than one upgrade, reset the state
                                ChangeUpgradeState(ref upgradeState, UpgradeState.VerifyingUpgradeRequest);
                                break;
                            }
                            break;

                        case ServerSingletonDecoder.State.Start:
                            SetupSecurityIfNecessary(connection);
                            if (upgradeState == UpgradeState.UpgradeComplete ||  //We have done at least one upgrade, but we are now done.
                                upgradeState == UpgradeState.None)       //no upgrade, just send the preample end bytes
                            {
                                ChangeUpgradeState(ref upgradeState, UpgradeState.WritingPreambleEnd);
                                // we've finished the preamble. Ack and return.
                                await connection.Output.WriteAsync(ServerSessionEncoder.AckResponseBytes);

                                await connection.Output.FlushAsync();

                                //terminal state
                                ChangeUpgradeState(ref upgradeState, UpgradeState.PreambleEndSent);
                            }
                            // If all bytes have already been consumed so the buffer has 0 length, AdvanceTo would throw
                            // as it's already been called.
                            if (buffer.Length > 0)
                            {
                                connection.Input.AdvanceTo(buffer.Start);
                            }

                            success = true;
                            await _next(connection);

                            return;
                        }

                        if (buffer.Length == 0)
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                if (!success)
                {
                    connection.Abort();
                }
            }
        }