public void PrepareRstStream(int streamId, Http2ErrorCode errorCode)
 {
     PayloadLength      = 4;
     Type               = Http2FrameType.RST_STREAM;
     Flags              = 0;
     StreamId           = streamId;
     RstStreamErrorCode = errorCode;
 }
예제 #2
0
 public Http2GoawayFrame(Http2FrameHeader header, int lastStreamID, Http2ErrorCode errorCode, byte[] additionalDebugData)
 {
     this.Header              = header;
     this.R                   = false;
     this.LastStreamID        = lastStreamID;
     this.ErrorCode           = errorCode;
     this.AdditionalDebugData = additionalDebugData;
 }
예제 #3
0
 public Task WriteRstStreamAsync(int streamId, Http2ErrorCode errorCode)
 {
     lock (_writeLock)
     {
         _outgoingFrame.PrepareRstStream(streamId, errorCode);
         return(WriteAsync(_outgoingFrame.Raw));
     }
 }
예제 #4
0
 public Task WriteGoAwayAsync(int lastStreamId, Http2ErrorCode errorCode)
 {
     lock (_writeLock)
     {
         _outgoingFrame.PrepareGoAway(lastStreamId, errorCode);
         return(WriteAsync(_outgoingFrame.Raw));
     }
 }
예제 #5
0
 protected void VerifyGoAway(Http2Frame frame, int expectedLastStreamId, Http2ErrorCode expectedErrorCode)
 {
     Assert.Equal(Http2FrameType.GOAWAY, frame.Type);
     Assert.Equal(8, frame.PayloadLength);
     Assert.Equal(0, frame.Flags);
     Assert.Equal(0, frame.StreamId);
     Assert.Equal(expectedLastStreamId, frame.GoAwayLastStreamId);
     Assert.Equal(expectedErrorCode, frame.GoAwayErrorCode);
 }
예제 #6
0
 public Http2RstStreamFrame(Http2FrameHeader header, byte[] data)
 {
     if (data.Length != header.Length)
     {
         throw new ArgumentException("Invalid Length.");
     }
     this.Header    = header;
     this.ErrorCode = (Http2ErrorCode)data.ToUInt32(0);
 }
예제 #7
0
 public void PrepareGoAway(int lastStreamId, Http2ErrorCode errorCode)
 {
     PayloadLength      = 8;
     Type               = Http2FrameType.GOAWAY;
     Flags              = 0;
     StreamId           = 0;
     GoAwayLastStreamId = lastStreamId;
     GoAwayErrorCode    = errorCode;
 }
예제 #8
0
        public ValueTask<FlushResult> WriteRstStreamAsync(Http2ErrorCode error)
        {
            lock (_dataWriterLock)
            {
                // Always send the reset even if the response body is _completed. The request body may not have completed yet.
                Stop();

                return _frameWriter.WriteRstStreamAsync(StreamId, error);
            }
        }
예제 #9
0
        public Task WriteRstStreamAsync(Http2ErrorCode error)
        {
            lock (_dataWriterLock)
            {
                // Always send the reset even if the response body is _completed. The request body may not have completed yet.

                Dispose();

                return(_frameWriter.WriteRstStreamAsync(_streamId, error));
            }
        }
예제 #10
0
        public static Http2RstStreamFrame Create(
            int streamID,
            Http2ErrorCode errorCode)
        {
            var header = new Http2FrameHeader(
                4,
                Http2FrameType.RstStream,
                0,
                streamID);

            return(new Http2RstStreamFrame(header, errorCode));
        }
예제 #11
0
        private void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error)
        {
            if (!TryApplyCompletionFlag(StreamCompletionFlags.Aborted))
            {
                return;
            }

            Log.Http2StreamResetAbort(TraceIdentifier, error, abortReason);

            // Don't block on IO. This never faults.
            _ = _http2Output.WriteRstStreamAsync(error);

            AbortCore(abortReason);
        }
예제 #12
0
        public static Http2GoawayFrame Create(
            int streamID,
            int lastStreamID,
            Http2ErrorCode errorCode,
            byte[] additionalDebugData)
        {
            var header = new Http2FrameHeader(
                4 + 4 + additionalDebugData.Length,
                Http2FrameType.Goaway,
                0,
                streamID);

            return(new Http2GoawayFrame(header, lastStreamID, errorCode, additionalDebugData));
        }
예제 #13
0
        private void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error)
        {
            if (Interlocked.Exchange(ref _requestAborted, 1) != 0)
            {
                return;
            }

            Log.Http2StreamResetAbort(TraceIdentifier, error, abortReason);

            // Don't block on IO. This never faults.
            _ = _http2Output.WriteRstStreamAsync(error);

            AbortCore(abortReason);
        }
예제 #14
0
        protected async Task WaitForStreamErrorAsync(int expectedStreamId, Http2ErrorCode expectedErrorCode, string expectedErrorMessage)
        {
            var frame = await ReceiveFrameAsync();

            Assert.Equal(Http2FrameType.RST_STREAM, frame.Type);
            Assert.Equal(4, frame.PayloadLength);
            Assert.Equal(0, frame.Flags);
            Assert.Equal(expectedStreamId, frame.StreamId);
            Assert.Equal(expectedErrorCode, frame.RstStreamErrorCode);

            if (expectedErrorMessage != null)
            {
                Assert.Contains(TestApplicationErrorLogger.Messages, m => m.Exception?.Message.Contains(expectedErrorMessage) ?? false);
            }
        }
예제 #15
0
        /* https://tools.ietf.org/html/rfc7540#section-6.8
         +-+-------------------------------------------------------------+
         |R|                  Last-Stream-ID (31)                        |
         +-+-------------------------------------------------------------+
         |                      Error Code (32)                          |
         +---------------------------------------------------------------+
         |                  Additional Debug Data (*)                    | (not implemented)
         +---------------------------------------------------------------+
         */
        public Task WriteGoAwayAsync(int lastStreamId, Http2ErrorCode errorCode)
        {
            lock (_writeLock)
            {
                _outgoingFrame.PrepareGoAway(lastStreamId, errorCode);
                WriteHeaderUnsynchronized();

                var buffer = _outputWriter.GetSpan(8);
                Bitshifter.WriteUInt31BigEndian(buffer, (uint)lastStreamId);
                buffer = buffer.Slice(4);
                BinaryPrimitives.WriteUInt32BigEndian(buffer, (uint)errorCode);
                _outputWriter.Advance(8);

                return(TimeFlushUnsynchronizedAsync());
            }
        }
예제 #16
0
        internal void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error)
        {
            // Future incoming frames will drain for a default grace period to avoid destabilizing the connection.
            var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted);

            if (states.OldState == states.NewState)
            {
                return;
            }

            Log.Http2StreamResetAbort(TraceIdentifier, error, abortReason);

            // Don't block on IO. This never faults.
            _ = _http2Output.WriteRstStreamAsync(error);

            AbortCore(abortReason);
        }
예제 #17
0
        /* https://tools.ietf.org/html/rfc7540#section-6.4
         +---------------------------------------------------------------+
         |                        Error Code (32)                        |
         +---------------------------------------------------------------+
         */
        public Task WriteRstStreamAsync(int streamId, Http2ErrorCode errorCode)
        {
            lock (_writeLock)
            {
                if (_completed)
                {
                    return(Task.CompletedTask);
                }

                _outgoingFrame.PrepareRstStream(streamId, errorCode);
                WriteHeaderUnsynchronized();
                var buffer = _outputWriter.GetSpan(4);
                BinaryPrimitives.WriteUInt32BigEndian(buffer, (uint)errorCode);
                _outputWriter.Advance(4);

                return(TimeFlushUnsynchronizedAsync());
            }
        }
예제 #18
0
        private void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error)
        {
            var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted);

            if (states.OldState == states.NewState)
            {
                return;
            }

            try
            {
                Log.Http2StreamResetAbort(TraceIdentifier, error, abortReason);

                // Don't block on IO. This never faults.
                _ = _http2Output.WriteRstStreamAsync(error);

                AbortCore(abortReason);
            }
            finally
            {
                TryFireOnStreamCompleted(states);
            }
        }
예제 #19
0
        protected async Task WaitForConnectionErrorAsync <TException>(bool ignoreNonGoAwayFrames, int expectedLastStreamId, Http2ErrorCode expectedErrorCode, string expectedErrorMessage)
            where TException : Exception
        {
            var frame = await ReceiveFrameAsync();

            if (ignoreNonGoAwayFrames)
            {
                while (frame.Type != Http2FrameType.GOAWAY)
                {
                    frame = await ReceiveFrameAsync();
                }
            }

            VerifyGoAway(frame, expectedLastStreamId, expectedErrorCode);

            if (expectedErrorMessage != null)
            {
                var message = Assert.Single(TestApplicationErrorLogger.Messages, m => m.Exception is TException);
                Assert.Contains(expectedErrorMessage, message.Exception.Message);
            }

            await _connectionTask;

            _pair.Application.Output.Complete();
        }
예제 #20
0
 public EncoderException(Http2ErrorCode errorCode, string errorMessage) : base(errorCode, errorMessage)
 {
 }
 public Http2ConnectionErrorException(string message, Http2ErrorCode errorCode)
     : base($"HTTP/2 connection error ({errorCode}): {message}")
 {
     ErrorCode = errorCode;
 }
예제 #22
0
 public void Http2StreamResetAbort(string traceIdentifier, Http2ErrorCode error, ConnectionAbortedException abortReason)
 {
 }
예제 #23
0
 public Http2ConnectionErrorException(Http2ErrorCode errorCode)
     : base($"HTTP/2 connection error: {errorCode}")
 {
     ErrorCode = errorCode;
 }
예제 #24
0
 public Http2Exception(Http2ErrorCode httpErrorCode, string message) : base(message)
 {
 }
예제 #25
0
 public Http2StreamErrorException(int streamId, string message, Http2ErrorCode errorCode)
     : base($"HTTP/2 stream ID {streamId} error ({errorCode}): {message}")
 {
     StreamId  = streamId;
     ErrorCode = errorCode;
 }
예제 #26
0
        private async Task WaitForConnectionErrorAsync(PipeReader reader, bool ignoreNonGoAwayFrames, int expectedLastStreamId, Http2ErrorCode expectedErrorCode)
        {
            var frame = await ReceiveFrameAsync(reader);

            if (ignoreNonGoAwayFrames)
            {
                while (frame.Type != Http2FrameType.GOAWAY)
                {
                    frame = await ReceiveFrameAsync(reader);
                }
            }

            Assert.Equal(Http2FrameType.GOAWAY, frame.Type);
            Assert.Equal(8, frame.PayloadLength);
            Assert.Equal(0, frame.Flags);
            Assert.Equal(0, frame.StreamId);
            Assert.Equal(expectedLastStreamId, frame.GoAwayLastStreamId);
            Assert.Equal(expectedErrorCode, frame.GoAwayErrorCode);
        }
예제 #27
0
 public DecoderException(Http2ErrorCode httpErrorCode, string message) : base(httpErrorCode, message)
 {
 }
예제 #28
0
 public Http2RstStreamFrame(Http2FrameHeader header, Http2ErrorCode errorCode)
 {
     this.Header    = header;
     this.ErrorCode = errorCode;
 }
예제 #29
0
 internal static string FormatHttp2StreamResetByApplication(Http2ErrorCode errorCode) => $"The HTTP/2 stream was reset by the application with error code {errorCode}.";
예제 #30
0
 public static partial void Http2StreamResetAbort(ILogger logger, string traceIdentifier, Http2ErrorCode error, ConnectionAbortedException abortReason);