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.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Text;
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.Http2.HPack;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.Extensions.Logging;
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);
}
if (_incomingFrame.HeadersHasPriority && _incomingFrame.HeadersStreamDependency == _incomingFrame.StreamId)
{
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
}
_currentHeadersStream = new Http2Stream<TContext>(application, new Http2StreamContext
{
ConnectionId = ConnectionId,
@ -316,6 +319,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
}
if (_incomingFrame.PriorityStreamDependency == _incomingFrame.StreamId)
{
throw new Http2ConnectionErrorException(Http2ErrorCode.PROTOCOL_ERROR);
}
if (_incomingFrame.Length != 5)
{
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);
}
[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]
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);
}
[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]
public async Task RST_STREAM_Received_AbortsStream()
{
@ -1507,10 +1527,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
return SendAsync(pingFrame.Raw);
}
private Task SendPriorityAsync(int streamId)
private Task SendPriorityAsync(int streamId, int streamDependency = 0)
{
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);
}