예제 #1
0
        /// <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;
        }
예제 #2
0
        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());
            }
        }
예제 #3
0
 private protected IPEndpoint(InputStream istr, Communicator communicator, Protocol protocol)
     : base(protocol)
 {
     Communicator = communicator;
     Host         = istr.ReadString();
     Port         = istr.ReadInt();
 }
예제 #4
0
파일: WSEndpoint.cs 프로젝트: nail-lian/ice
        internal WSEndpoint(TransportInstance instance, Endpoint del, InputStream istr)
        {
            _instance = instance;
            _delegate = del;

            Resource = istr.ReadString();
        }
예제 #5
0
파일: WSEndpoint.cs 프로젝트: mreinart/ice
        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 !));
        }
예제 #6
0
 // 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);
         }
     }
 }
예제 #7
0
        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));
            }
        }
예제 #8
0
        // 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();
            }
        }
예제 #9
0
        /// <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;
        }
예제 #10
0
파일: IPEndpoint.cs 프로젝트: keno1213/ice
        // 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;
        }
예제 #11
0
        /// <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;
        }
예제 #12
0
파일: IPEndpoint.cs 프로젝트: wandec/ice
 private protected IPEndpoint(Communicator communicator, InputStream istr)
 {
     Communicator = communicator;
     Host         = istr.ReadString();
     Port         = istr.ReadInt();
 }
예제 #13
0
 internal UnhandledException ReadUnhandledException() =>
 new UnhandledException(InputStream.ReadString(Protocol.GetEncoding(), Payload.Slice(1).AsSpan()),
                        Identity.Empty,
                        "",
                        "");
예제 #14
0
 private protected IPEndpoint(TransportInstance instance, InputStream s)
 {
     Instance = instance;
     Host     = s.ReadString();
     Port     = s.ReadInt();
 }
예제 #15
0
        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}'");
                }
                }
            }
        }
예제 #16
0
        /// <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;
        }