/// <summary>Creates a new IncomingRequestFrame.</summary> /// <param name="protocol">The Ice protocol.</param> /// <param name="data">The frame data as an array segment.</param> public IncomingRequestFrame(Protocol protocol, ArraySegment <byte> data) { Data = data; Protocol = protocol; var istr = new InputStream(Protocol.GetEncoding(), data); Identity = new Identity(istr); Facet = istr.ReadFacet(); Operation = istr.ReadString(); IsIdempotent = istr.ReadOperationMode() != OperationMode.Normal; Context = istr.ReadContext(); Payload = Data.Slice(istr.Pos); (int size, Encoding encoding) = istr.ReadEncapsulationHeader(); if (protocol == Protocol.Ice1 && size + 4 != Payload.Count) { // The payload holds an encapsulation and the encapsulation must use up the full buffer with ice1. // "4" corresponds to fixed-length size with the 1.1 encoding. throw new InvalidDataException($"invalid request encapsulation size: {size}"); } else { // TODO: with ice2, the payload is followed by a context, and the size is not fixed-length. // TODO: read the compression status from the encapsulation data } Encoding = encoding; }
internal virtual async ValueTask <((long, long), string message)> ReceiveGoAwayFrameAsync() { byte frameType = _transceiver.Endpoint.Protocol == Protocol.Ice1 ? (byte)Ice1Definitions.FrameType.CloseConnection : (byte)Ice2Definitions.FrameType.GoAway; (ArraySegment <byte> data, bool fin) = await ReceiveFrameAsync(frameType, CancellationToken.None).ConfigureAwait(false); if (!fin) { throw new InvalidDataException($"expected end of stream after GoAway frame"); } if (_transceiver.Endpoint.Communicator.TraceLevels.Protocol >= 1) { TraceFrame(data, frameType); } if (_transceiver.Endpoint.Protocol == Protocol.Ice1) { // LastResponseStreamId contains the stream ID of the last received response. We make sure to return // this stream ID to ensure the request with this stream ID will complete successfully in case the // close connection message is received shortly after the response and potentially processed before // due to the thread scheduling. return((_transceiver.LastResponseStreamId, 0), "connection gracefully closed by peer"); } else { var istr = new InputStream(data, Ice2Definitions.Encoding); return(((long)istr.ReadVarULong(), (long)istr.ReadVarULong()), istr.ReadString()); } }
private protected IPEndpoint(InputStream istr, Communicator communicator, Protocol protocol) : base(protocol) { Communicator = communicator; Host = istr.ReadString(); Port = istr.ReadInt(); }
internal WSEndpoint(TransportInstance instance, Endpoint del, InputStream istr) { _instance = instance; _delegate = del; Resource = istr.ReadString(); }
internal static new WSEndpoint CreateIce1Endpoint(Transport transport, InputStream istr) { Debug.Assert(transport == Transport.WS || transport == Transport.WSS); string host = istr.ReadString(); ushort port = ReadPort(istr); var timeout = TimeSpan.FromMilliseconds(istr.ReadInt()); bool compress = istr.ReadBool(); string resource = istr.ReadString(); string[] options = resource == "/" ? Array.Empty <string>() : new string[] { resource }; return(new WSEndpoint(new EndpointData(transport, host, port, options), timeout, compress, istr.Communicator !)); }
// Constructor for unmarshaling. internal WSEndpoint(InputStream istr, Transport transport, Protocol protocol) : base(istr, transport, protocol, mostDerived: false) { if (protocol == Protocol.Ice1) { _resource = istr.ReadString(); } else { int optionCount = istr.ReadSize(); if (optionCount > 0) { _resource = istr.ReadString(); optionCount--; SkipUnknownOptions(istr, optionCount); } } }
internal DispatchException ReadDispatchException() { var istr = new InputStream(_communicator, Protocol.GetEncoding(), Payload, 1); var identity = new Identity(istr); string facet = istr.ReadFacet(); string operation = istr.ReadString(); if (ReplyStatus == ReplyStatus.OperationNotExistException) { return(new OperationNotExistException(identity, facet, operation)); } else { return(new ObjectNotExistException(identity, facet, operation)); } }
// Constructor for unmarshaling. private protected IPEndpoint(InputStream istr, Communicator communicator, Protocol protocol) : base(communicator, protocol) { Host = istr.ReadString(); if (protocol == Protocol.Ice1) { checked { Port = (ushort)istr.ReadInt(); } } else { Port = istr.ReadUShort(); } }
/// <summary>Creates a new IncomingRequestFrame.</summary> /// <param name="protocol">The Ice protocol.</param> /// <param name="data">The frame data as an array segment.</param> /// <param name="sizeMax">The maximum payload size, checked during decompress.</param> public IncomingRequestFrame(Protocol protocol, ArraySegment <byte> data, int sizeMax) : base(data, protocol, sizeMax) { var istr = new InputStream(Data, Protocol.GetEncoding()); Identity = new Identity(istr); Facet = istr.ReadFacet(); Operation = istr.ReadString(); IsIdempotent = istr.ReadOperationMode() != OperationMode.Normal; if (Protocol == Protocol.Ice1) { Context = istr.ReadDictionary(minKeySize: 1, minValueSize: 1, InputStream.IceReaderIntoString, InputStream.IceReaderIntoString); } else { Context = new Dictionary <string, string>(); } (int size, int sizeLength, Encoding encoding) = Data.Slice(istr.Pos).AsReadOnlySpan().ReadEncapsulationHeader(Protocol.GetEncoding()); Payload = Data.Slice(istr.Pos, size + sizeLength); // the payload is the encapsulation if (Protocol == Protocol.Ice2 && BinaryContext.TryGetValue(0, out ReadOnlyMemory <byte> value)) { Context = value.Read(istr => istr.ReadDictionary(minKeySize: 1, minValueSize: 1, InputStream.IceReaderIntoString, InputStream.IceReaderIntoString)); } if (protocol == Protocol.Ice1 && size + 4 + istr.Pos != data.Count) { // The payload holds an encapsulation and the encapsulation must use up the full buffer with ice1. // "4" corresponds to fixed-length size with the 1.1 encoding. throw new InvalidDataException($"invalid request encapsulation size: {size}"); } Encoding = encoding; HasCompressedPayload = Encoding == Encoding.V2_0 && Payload[sizeLength + 2] != 0; }
// Constructor for unmarshaling. private protected IPEndpoint(InputStream istr, Communicator communicator, Protocol protocol) : base(communicator, protocol) { Debug.Assert(protocol == Protocol.Ice1 || protocol == Protocol.Ice2); Host = istr.ReadString(); if (protocol == Protocol.Ice1) { checked { Port = (ushort)istr.ReadInt(); } } else { Port = istr.ReadUShort(); } SourceAddress = communicator.DefaultSourceAddress; }
/// <summary>Creates a new IncomingRequestFrame.</summary> /// <param name="communicator">The communicator to use when initializing the stream.</param> /// <param name="data">The frame data as an array segment.</param> public IncomingRequestFrame(Communicator communicator, ArraySegment <byte> data) { _communicator = communicator; Data = data; var istr = new InputStream(communicator, Ice1Definitions.Encoding, data); Identity = new Identity(istr); Facet = istr.ReadFacet(); Operation = istr.ReadString(); IsIdempotent = istr.ReadOperationMode() != OperationMode.Normal; Context = istr.ReadContext(); Payload = Data.Slice(istr.Pos); (int size, Encoding encoding) = istr.ReadEncapsulationHeader(); if (size + 4 != Payload.Count) { throw new InvalidDataException($"invalid request encapsulation size: {size}"); } Encoding = encoding; }
private protected IPEndpoint(Communicator communicator, InputStream istr) { Communicator = communicator; Host = istr.ReadString(); Port = istr.ReadInt(); }
internal UnhandledException ReadUnhandledException() => new UnhandledException(InputStream.ReadString(Protocol.GetEncoding(), Payload.Slice(1).AsSpan()), Identity.Empty, "", "");
private protected IPEndpoint(TransportInstance instance, InputStream s) { Instance = instance; Host = s.ReadString(); Port = s.ReadInt(); }
internal override async ValueTask <(long StreamId, IncomingFrame?Frame, bool Fin)> ReceiveAsync( CancellationToken cancel) { FrameType type; ArraySegment <byte> data; while (true) { // Read Slic frame header (type, data) = await ReceiveFrameAsync(CancellationToken.None).ConfigureAwait(false); switch (type) { case FrameType.Ping: { ValueTask task = PrepareAndSendFrameAsync(FrameType.Pong, null, CancellationToken.None); HeartbeatCallback !(); break; } case FrameType.Pong: { // TODO: setup a timer to expect pong frame response? break; } case FrameType.Stream: case FrameType.StreamLast: { (long streamId, int streamIdSize) = data.AsReadOnlySpan().ReadVarLong(); data = data.Slice(streamIdSize); IncomingFrame frame = ParseIce2Frame(data); if (Endpoint.Communicator.TraceLevels.Protocol >= 1) { ProtocolTrace.TraceFrame(Endpoint.Communicator, streamId, frame); } return(StreamId : streamId, Frame : frame, Fin : type == FrameType.StreamLast); } case FrameType.ResetStream: { var istr = new InputStream(data, Encoding); long streamId = istr.ReadVarLong(); long reason = istr.ReadVarLong(); return(StreamId : streamId, Frame : null, Fin : true); } case FrameType.Close: { var istr = new InputStream(data, Encoding); long code = istr.ReadVarLong(); // TODO: is this really useful? string reason = istr.ReadString(); throw new ConnectionClosedByPeerException(reason); } default: { throw new InvalidDataException($"unexpected Slic frame with frame type `{type}'"); } } } }
/// <summary>Constructs an incoming request frame.</summary> /// <param name="protocol">The Ice protocol.</param> /// <param name="data">The frame data as an array segment.</param> /// <param name="sizeMax">The maximum payload size, checked during decompression.</param> public IncomingRequestFrame(Protocol protocol, ArraySegment <byte> data, int sizeMax) : base(data, protocol, sizeMax) { var istr = new InputStream(Data, Protocol.GetEncoding()); if (Protocol == Protocol.Ice1) { Identity = new Identity(istr); Facet = istr.ReadFacet11(); Location = Array.Empty <string>(); Operation = istr.ReadString(); IsIdempotent = istr.ReadOperationMode() != OperationMode.Normal; Context = istr.ReadDictionary(minKeySize: 1, minValueSize: 1, InputStream.IceReaderIntoString, InputStream.IceReaderIntoString); Priority = default; } else { var requestHeader = new Ice2RequestHeader(istr); Identity = requestHeader.Identity; Facet = requestHeader.Facet ?? ""; Location = requestHeader.Location ?? Array.Empty <string>(); Operation = requestHeader.Operation; IsIdempotent = requestHeader.Idempotent; Priority = requestHeader.Priority ?? default; Context = new Dictionary <string, string>(); if (Location.Any(segment => segment.Length == 0)) { throw new InvalidDataException("received request with empty location segment"); } } if (Identity.Name.Length == 0) { throw new InvalidDataException("received request with null identity"); } if (Operation.Length == 0) { throw new InvalidDataException("received request with empty operation name"); } (int size, int sizeLength, Encoding encoding) = Data.Slice(istr.Pos).AsReadOnlySpan().ReadEncapsulationHeader(Protocol.GetEncoding()); Payload = Data.Slice(istr.Pos, size + sizeLength); // the payload is the encapsulation if (Protocol == Protocol.Ice2 && BinaryContext.TryGetValue(0, out ReadOnlyMemory <byte> value)) { Context = value.Read(istr => istr.ReadDictionary(minKeySize: 1, minValueSize: 1, InputStream.IceReaderIntoString, InputStream.IceReaderIntoString)); } if (protocol == Protocol.Ice1 && size + 4 + istr.Pos != data.Count) { // The payload holds an encapsulation and the encapsulation must use up the full buffer with ice1. // "4" corresponds to fixed-length size with the 1.1 encoding. throw new InvalidDataException($"invalid request encapsulation size: {size}"); } Encoding = encoding; HasCompressedPayload = Encoding == Encoding.V20 && Payload[sizeLength + 2] != 0; }