HTTP/2: close connection with PROTOCOL_ERROR when a stream depends on itself.

This commit is contained in:
Cesar Blum Silveira 2017-09-21 10:05:56 -07:00 committed by Cesar Blum Silveira
parent af7944047d
commit 343ce0f01b
2 changed files with 32 additions and 4 deletions

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -13,7 +12,6 @@ using Microsoft.AspNetCore.Protocols;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
@ -275,6 +273,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR); throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
} }
if (_incomingFrame.HeadersHasPriority && _incomingFrame.HeadersStreamDependency == _incomingFrame.StreamId)
{
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
}
_currentHeadersStream = new Http2Stream<TContext>(application, new Http2StreamContext _currentHeadersStream = new Http2Stream<TContext>(application, new Http2StreamContext
{ {
ConnectionId = ConnectionId, ConnectionId = ConnectionId,
@ -316,6 +319,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR); throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
} }
if (_incomingFrame.PriorityStreamDependency == _incomingFrame.StreamId)
{
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
}
if (_incomingFrame.Length != 5) if (_incomingFrame.Length != 5)
{ {
throw new Http2ConnectionErrorException(Http2ErrorCode.FRAME_SIZE_ERROR); throw new Http2ConnectionErrorException(Http2ErrorCode.FRAME_SIZE_ERROR);

View File

@ -692,6 +692,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false); await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false);
} }
[Fact]
public async Task HEADERS_Received_WithPriority_StreamDependencyOnSelf_ConnectionError()
{
await InitializeConnectionAsync(_readHeadersApplication);
await SendHeadersWithPriorityAsync(1, _browserRequestHeaders, priority: 42, streamDependency: 1, endStream: true);
await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false);
}
[Fact] [Fact]
public async Task PRIORITY_Received_StreamIdZero_ConnectionError() public async Task PRIORITY_Received_StreamIdZero_ConnectionError()
{ {
@ -735,6 +745,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false); await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false);
} }
[Fact]
public async Task PRIORITY_Received_StreamDependencyOnSelf_ConnectionError()
{
await InitializeConnectionAsync(_readHeadersApplication);
await SendPriorityAsync(1, streamDependency: 1);
await WaitForConnectionErrorAsync(expectedLastStreamId: 0, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, ignoreNonGoAwayFrames: false);
}
[Fact] [Fact]
public async Task RST_STREAM_Received_AbortsStream() public async Task RST_STREAM_Received_AbortsStream()
{ {
@ -1507,10 +1527,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
return SendAsync(pingFrame.Raw); return SendAsync(pingFrame.Raw);
} }
private Task SendPriorityAsync(int streamId) private Task SendPriorityAsync(int streamId, int streamDependency = 0)
{ {
var priorityFrame = new Http2Frame(); var priorityFrame = new Http2Frame();
priorityFrame.PreparePriority(streamId, streamDependency: 0, exclusive: false, weight: 0); priorityFrame.PreparePriority(streamId, streamDependency: streamDependency, exclusive: false, weight: 0);
return SendAsync(priorityFrame.Raw); return SendAsync(priorityFrame.Raw);
} }