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); } }
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. }