Fix ArgumentException from duplicate key (#6416)
This commit is contained in:
parent
489735d390
commit
ca7c48c520
|
|
@ -1,13 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
|
|
@ -274,7 +271,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
|||
(context) =>
|
||||
{
|
||||
context.Response.StatusCode = 405;
|
||||
context.Response.Headers.Add("Allow", allow);
|
||||
|
||||
// Prevent ArgumentException from duplicate key if header already added, such as when the
|
||||
// request is re-executed by an error handler (see https://github.com/aspnet/AspNetCore/issues/6415)
|
||||
context.Response.Headers["Allow"] = allow;
|
||||
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
EndpointMetadataCollection.Empty,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -288,6 +288,36 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
|||
MatcherAssert.AssertMatch(context, httpContext, endpoint2, ignoreValues: true);
|
||||
}
|
||||
|
||||
[Fact] // See https://github.com/aspnet/AspNetCore/issues/6415
|
||||
public async Task NotMatch_HttpMethod_Returns405Endpoint_ReExecute()
|
||||
{
|
||||
// Arrange
|
||||
var endpoint1 = CreateEndpoint("/hello", httpMethods: new string[] { "GET", "PUT" });
|
||||
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
|
||||
|
||||
var matcher = CreateMatcher(endpoint1, endpoint2);
|
||||
var (httpContext, context) = CreateContext("/hello", "POST");
|
||||
|
||||
// Act
|
||||
await matcher.MatchAsync(httpContext, context);
|
||||
|
||||
// Assert
|
||||
Assert.NotSame(endpoint1, context.Endpoint);
|
||||
Assert.NotSame(endpoint2, context.Endpoint);
|
||||
|
||||
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, context.Endpoint.DisplayName);
|
||||
|
||||
// Invoke the endpoint
|
||||
await context.Endpoint.RequestDelegate(httpContext);
|
||||
Assert.Equal(405, httpContext.Response.StatusCode);
|
||||
Assert.Equal("DELETE, GET, PUT", httpContext.Response.Headers["Allow"]);
|
||||
|
||||
// Invoke the endpoint again to verify headers not duplicated
|
||||
await context.Endpoint.RequestDelegate(httpContext);
|
||||
Assert.Equal(405, httpContext.Response.StatusCode);
|
||||
Assert.Equal("DELETE, GET, PUT", httpContext.Response.Headers["Allow"]);
|
||||
}
|
||||
|
||||
private static Matcher CreateMatcher(params RouteEndpoint[] endpoints)
|
||||
{
|
||||
var services = new ServiceCollection()
|
||||
|
|
|
|||
Loading…
Reference in New Issue