예제 #1
0
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            var decoder = new ServerSessionDecoder(ConnectionOrientedTransportDefaults.MaxViaSize, ConnectionOrientedTransportDefaults.MaxContentTypeSize);
            ReadOnlySequence <byte> buffer;

            while (decoder.CurrentState != ServerSessionDecoder.State.PreUpgradeStart)
            {
                var readResult = await connection.Input.ReadAsync();

                buffer = readResult.Buffer;

                while (buffer.Length > 0)
                {
                    int bytesDecoded;
                    try
                    {
                        bytesDecoded = decoder.Decode(buffer);
                    }
                    catch (CommunicationException e)
                    {
                        // see if we need to send back a framing fault
                        string framingFault;
                        if (FramingEncodingString.TryGetFaultString(e, out framingFault))
                        {
                            // TODO: Drain the rest of the data and send a fault then close the connection
                            //byte[] drainBuffer = new byte[128];
                            //InitialServerConnectionReader.SendFault(
                            //    Connection, framingFault, drainBuffer, GetRemainingTimeout(),
                            //    MaxViaSize + MaxContentTypeSize);
                            //base.Close(GetRemainingTimeout());
                        }
                        throw;
                    }

                    if (bytesDecoded > 0)
                    {
                        buffer = buffer.Slice(bytesDecoded);
                    }

                    if (decoder.CurrentState == ServerSessionDecoder.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);
            }

            connection.ServerSessionDecoder = decoder;

            await _next(connection);
        }
        private static void ProcessUpgradeRequest(FramingConnection connection, ServerSessionDecoder decoder)
        {
            var upgradeAcceptor = connection.StreamUpgradeAcceptor;

            if (upgradeAcceptor == null)
            {
                // TODO: SendFault
                //SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new ProtocolException(SR.Format(SR.UpgradeRequestToNonupgradableService, decoder.Upgrade)));
            }

            if (!upgradeAcceptor.CanUpgrade(decoder.Upgrade))
            {
                // TODO: SendFault
                //SendFault(FramingEncodingString.UpgradeInvalidFault, ref timeoutHelper);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new ProtocolException(SR.Format(SR.UpgradeProtocolNotSupported, decoder.Upgrade)));
            }
        }
        private static void ValidateContentType(FramingConnection connection, ServerSessionDecoder decoder)
        {
            var            messageEncoderFactory = connection.MessageEncoderFactory;
            MessageEncoder messageEncoder        = messageEncoderFactory.CreateSessionEncoder();

            connection.MessageEncoder = messageEncoder;

            if (!messageEncoder.IsContentTypeSupported(decoder.ContentType))
            {
                // TODO: Send fault response
                //SendFault(FramingEncodingString.ContentTypeInvalidFault, ref timeoutHelper);
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format(
                                                                                                    SR.ContentTypeMismatch, decoder.ContentType, messageEncoder.ContentType)));
            }

            ICompressedMessageEncoder compressedMessageEncoder = messageEncoder as ICompressedMessageEncoder;

            if (compressedMessageEncoder != null && compressedMessageEncoder.CompressionEnabled)
            {
                compressedMessageEncoder.SetSessionContentType(decoder.ContentType);
            }
        }
예제 #4
0
        public async Task OnConnectedAsync(FramingConnection connection)
        {
            var  decoder = new ServerSessionDecoder(ConnectionOrientedTransportDefaults.MaxViaSize, ConnectionOrientedTransportDefaults.MaxContentTypeSize);
            bool success = false;

            try
            {
                ReadOnlySequence <byte> buffer;
                while (decoder.CurrentState != ServerSessionDecoder.State.PreUpgradeStart)
                {
                    var 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 == ServerSessionDecoder.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.
        }