зеркало из https://github.com/dotnet/aspnetcore.git
Merge pull request #50222 from dotnet-maestro-bot/merge/release/8.0-to-main
[automated] Merge branch 'release/8.0' => 'main'
This commit is contained in:
Коммит
aa928a6ffc
|
@ -126,17 +126,17 @@ variables:
|
|||
- name: _InternalRuntimeDownloadCodeSignArgs
|
||||
value: ''
|
||||
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
|
||||
- group: DotNet-MSRC-Storage
|
||||
- group: DotNetBuilds storage account read tokens
|
||||
- name: _InternalRuntimeDownloadArgs
|
||||
value: -RuntimeSourceFeed https://dotnetclimsrc.blob.core.windows.net/dotnet
|
||||
-RuntimeSourceFeedKey $(dotnetclimsrc-read-sas-token-base64)
|
||||
/p:DotNetAssetRootAccessTokenSuffix='$(dotnetclimsrc-read-sas-token-base64)'
|
||||
value: -RuntimeSourceFeed https://dotnetbuilds.blob.core.windows.net/internal
|
||||
-RuntimeSourceFeedKey $(dotnetbuilds-internal-container-read-token-base64)
|
||||
/p:DotNetAssetRootAccessTokenSuffix='$(dotnetbuilds-internal-container-read-token-base64)'
|
||||
# The code signing doesn't use the aspnet build scripts, so the msbuild parameters have to be passed directly. This
|
||||
# is awkward but necessary because the eng/common/ build scripts don't add the msbuild properties automatically.
|
||||
- name: _InternalRuntimeDownloadCodeSignArgs
|
||||
value: $(_InternalRuntimeDownloadArgs)
|
||||
/p:DotNetRuntimeSourceFeed=https://dotnetclimsrc.blob.core.windows.net/dotnet
|
||||
/p:DotNetRuntimeSourceFeedKey=$(dotnetclimsrc-read-sas-token-base64)
|
||||
/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal
|
||||
/p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64)
|
||||
- group: DotNet-HelixApi-Access
|
||||
- ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
|
||||
- name: _SignType
|
||||
|
@ -731,7 +731,7 @@ stages:
|
|||
platform:
|
||||
name: 'Managed'
|
||||
container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8'
|
||||
buildScript: './eng/build.sh $(_PublishArgs) --no-build-repo-tasks'
|
||||
buildScript: './eng/build.sh $(_PublishArgs) --no-build-repo-tasks $(_InternalRuntimeDownloadArgs)'
|
||||
skipPublishValidation: true
|
||||
jobProperties:
|
||||
timeoutInMinutes: 120
|
||||
|
|
|
@ -367,30 +367,30 @@
|
|||
<Uri>https://github.com/dotnet/winforms</Uri>
|
||||
<Sha>4eae6075b679fb57727d7bee8a6eefd5929aec03</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="8.0.0-beta.23415.4">
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="8.0.0-beta.23419.1">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>46ff142f43e887d5f9a4d87ef39d72166f61db8d</Sha>
|
||||
<Sha>385129cbc980a515ddee2fa56f6b16f3183ed9bc</Sha>
|
||||
<SourceBuild RepoName="arcade" ManagedOnly="true" />
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="8.0.0-beta.23415.4">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="8.0.0-beta.23419.1">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>46ff142f43e887d5f9a4d87ef39d72166f61db8d</Sha>
|
||||
<Sha>385129cbc980a515ddee2fa56f6b16f3183ed9bc</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="8.0.0-beta.23415.4">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="8.0.0-beta.23419.1">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>46ff142f43e887d5f9a4d87ef39d72166f61db8d</Sha>
|
||||
<Sha>385129cbc980a515ddee2fa56f6b16f3183ed9bc</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="8.0.0-beta.23415.4">
|
||||
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="8.0.0-beta.23419.1">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>46ff142f43e887d5f9a4d87ef39d72166f61db8d</Sha>
|
||||
<Sha>385129cbc980a515ddee2fa56f6b16f3183ed9bc</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="8.0.0-beta.23415.4">
|
||||
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="8.0.0-beta.23419.1">
|
||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||
<Sha>46ff142f43e887d5f9a4d87ef39d72166f61db8d</Sha>
|
||||
<Sha>385129cbc980a515ddee2fa56f6b16f3183ed9bc</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Telemetry.Testing" Version="9.0.0-alpha.1.23416.6">
|
||||
<Dependency Name="Microsoft.Extensions.Telemetry.Testing" Version="8.0.0-rc.2.23417.1">
|
||||
<Uri>https://github.com/dotnet/extensions</Uri>
|
||||
<Sha>af03153106c48eb7c7248fd15e7286a311b338d8</Sha>
|
||||
<Sha>6f38a71521d48c518445e39dc643a43d8599ce23</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="NuGet.Frameworks" Version="6.2.4">
|
||||
<Uri>https://github.com/nuget/nuget.client</Uri>
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
<SystemIOHashingVersion>8.0.0-rc.1.23421.3</SystemIOHashingVersion>
|
||||
<SystemRuntimeCachingVersion>8.0.0-rc.1.23421.3</SystemRuntimeCachingVersion>
|
||||
<!-- Packages from dotnet/extensions -->
|
||||
<MicrosoftExtensionsTelemetryTestingVersion>9.0.0-alpha.1.23416.6</MicrosoftExtensionsTelemetryTestingVersion>
|
||||
<MicrosoftExtensionsTelemetryTestingVersion>8.0.0-rc.2.23417.1</MicrosoftExtensionsTelemetryTestingVersion>
|
||||
<!-- Packages from dotnet/efcore -->
|
||||
<dotnetefVersion>9.0.0-alpha.1.23421.9</dotnetefVersion>
|
||||
<MicrosoftEntityFrameworkCoreInMemoryVersion>9.0.0-alpha.1.23421.9</MicrosoftEntityFrameworkCoreInMemoryVersion>
|
||||
|
@ -158,9 +158,9 @@
|
|||
<NuGetVersioningVersion>6.2.4</NuGetVersioningVersion>
|
||||
<NuGetFrameworksVersion>6.2.4</NuGetFrameworksVersion>
|
||||
<!-- Packages from dotnet/arcade -->
|
||||
<MicrosoftDotNetBuildTasksInstallersVersion>8.0.0-beta.23415.4</MicrosoftDotNetBuildTasksInstallersVersion>
|
||||
<MicrosoftDotNetBuildTasksTemplatingVersion>8.0.0-beta.23415.4</MicrosoftDotNetBuildTasksTemplatingVersion>
|
||||
<MicrosoftDotNetRemoteExecutorVersion>8.0.0-beta.23415.4</MicrosoftDotNetRemoteExecutorVersion>
|
||||
<MicrosoftDotNetBuildTasksInstallersVersion>8.0.0-beta.23419.1</MicrosoftDotNetBuildTasksInstallersVersion>
|
||||
<MicrosoftDotNetBuildTasksTemplatingVersion>8.0.0-beta.23419.1</MicrosoftDotNetBuildTasksTemplatingVersion>
|
||||
<MicrosoftDotNetRemoteExecutorVersion>8.0.0-beta.23419.1</MicrosoftDotNetRemoteExecutorVersion>
|
||||
<!-- Packages from dotnet/source-build-externals -->
|
||||
<MicrosoftSourceBuildIntermediatesourcebuildexternalsVersion>8.0.0-alpha.1.23418.1</MicrosoftSourceBuildIntermediatesourcebuildexternalsVersion>
|
||||
<!-- Packages from dotnet/source-build-reference-packages -->
|
||||
|
|
|
@ -63,7 +63,7 @@ if [ -z "$CLR_CC" ]; then
|
|||
# Set default versions
|
||||
if [ -z "$majorVersion" ]; then
|
||||
# note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero.
|
||||
if [ "$compiler" = "clang" ]; then versions="16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5"
|
||||
if [ "$compiler" = "clang" ]; then versions="17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5"
|
||||
elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi
|
||||
|
||||
for version in $versions; do
|
||||
|
|
|
@ -25,7 +25,7 @@ function Install-VersionTools-Cli {
|
|||
Write-Host "Installing the package '$CliToolName' with a version of '$version' ..."
|
||||
$feed = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"
|
||||
|
||||
$argumentList = @("tool", "install", "--local", "$CliToolName", "--add-source $feed", "--no-cache", "--version $Version")
|
||||
$argumentList = @("tool", "install", "--local", "$CliToolName", "--add-source $feed", "--no-cache", "--version $Version", "--create-manifest-if-needed")
|
||||
Start-Process "$dotnet" -Verbose -ArgumentList $argumentList -NoNewWindow -Wait
|
||||
}
|
||||
|
||||
|
|
|
@ -105,6 +105,11 @@ jobs:
|
|||
downloadPath: $(Build.ArtifactStagingDirectory)\artifacts
|
||||
checkDownloadedFiles: true
|
||||
|
||||
- powershell: eng/common/sdl/trim-assets-version.ps1
|
||||
-InputPath $(Build.ArtifactStagingDirectory)\artifacts
|
||||
displayName: Trim the version from the NuGet packages
|
||||
continueOnError: ${{ parameters.sdlContinueOnError }}
|
||||
|
||||
- powershell: eng/common/sdl/extract-artifact-packages.ps1
|
||||
-InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts
|
||||
-ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts
|
||||
|
|
|
@ -63,6 +63,11 @@
|
|||
<SasToken>$([System.Environment]::GetEnvironmentVariable('DotNetBuildsInternalReadSasToken'))</SasToken>
|
||||
</AdditionalDotNetPackageFeed>
|
||||
|
||||
<AdditionalDotNetPackageFeed Include="https://dotnetbuilds.blob.core.windows.net/internal"
|
||||
Condition="'$(SYSTEM_TEAMPROJECT)' == 'internal'">
|
||||
<SasToken>$([System.Environment]::GetEnvironmentVariable('DotNetBuildsInternalReadSasToken'))</SasToken>
|
||||
</AdditionalDotNetPackageFeed>
|
||||
|
||||
<!-- Grab the tool packages for what HelixTestRunner installs. -->
|
||||
<HelixCorrelationPayload Include="$(NUGET_PACKAGES)\dotnet-dump\$(DotnetDumpVersion)\dotnet-dump.$(DotnetDumpVersion).nupkg" />
|
||||
<HelixCorrelationPayload Include="$(NUGET_PACKAGES)\dotnet-ef\$(DotnetEfVersion)\dotnet-ef.$(DotnetEfVersion).nupkg" />
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
},
|
||||
"msbuild-sdks": {
|
||||
"Yarn.MSBuild": "1.22.10",
|
||||
"Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23415.4",
|
||||
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23415.4"
|
||||
"Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.23419.1",
|
||||
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23419.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,14 +142,23 @@ internal class Endpoint
|
|||
|
||||
private static (string, int, int) GetLocation(IInvocationOperation operation)
|
||||
{
|
||||
var operationSpan = operation.Syntax.Span;
|
||||
// The invocation expression consists of two properties:
|
||||
// - Expression: which is a `MemberAccessExpressionSyntax` that represents the method being invoked.
|
||||
// - ArgumentList: the list of arguments being invoked.
|
||||
// Here, we resolve the `MemberAccessExpressionSyntax` to get the location of the method being invoked.
|
||||
var memberAccessorExpression = ((MemberAccessExpressionSyntax)((InvocationExpressionSyntax)operation.Syntax).Expression);
|
||||
// The `MemberAccessExpressionSyntax` in turn includes three properties:
|
||||
// - Expression: the expression that is being accessed.
|
||||
// - OperatorToken: the operator token, typically the dot separate.
|
||||
// - Name: the name of the member being accessed, typically `MapGet` or `MapPost`, etc.
|
||||
// Here, we resolve the `Name` to extract the location of the method being invoked.
|
||||
var invocationNameSpan = memberAccessorExpression.Name.Span;
|
||||
// Resolve LineSpan associated with the name span so we can resolve the line and character number.
|
||||
var lineSpan = operation.Syntax.SyntaxTree.GetLineSpan(invocationNameSpan);
|
||||
// Resolve the filepath of the invocation while accounting for source mapped paths.
|
||||
var filePath = operation.Syntax.SyntaxTree.GetInterceptorFilePath(operation.SemanticModel?.Compilation.Options.SourceReferenceResolver);
|
||||
var span = operation.Syntax.SyntaxTree.GetLineSpan(operationSpan);
|
||||
var lineNumber = span.StartLinePosition.Line + 1;
|
||||
// Calculate the character offset to the end of the Map invocation detected
|
||||
var invocationLength = ((MemberAccessExpressionSyntax)((InvocationExpressionSyntax)operation.Syntax).Expression).Expression.Span.Length;
|
||||
var characterNumber = span.StartLinePosition.Character + invocationLength + 2;
|
||||
return (filePath, lineNumber, characterNumber);
|
||||
// LineSpan.LinePosition is 0-indexed, but we want to display 1-indexed line and character numbers in the interceptor attribute.
|
||||
return (filePath, lineSpan.StartLinePosition.Line + 1, lineSpan.StartLinePosition.Character + 1);
|
||||
}
|
||||
|
||||
private static string GetHttpMethod(IInvocationOperation operation)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Http.RequestDelegateGenerator;
|
||||
|
@ -96,6 +97,57 @@ app.MapGet("/hello", (HttpContext context) => Task.CompletedTask);
|
|||
await VerifyAgainstBaselineUsingFile(updatedCompilation);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SupportsMapCallOnNewLine()
|
||||
{
|
||||
var source = """
|
||||
app
|
||||
.MapGet("/hello1/{id}", (int id) => $"Hello {id}!");
|
||||
EndpointRouteBuilderExtensions
|
||||
.MapGet(app, "/hello2/{id}", (int id) => $"Hello {id}!");
|
||||
app.
|
||||
MapGet("/hello1/{id}", (int id) => $"Hello {id}!");
|
||||
EndpointRouteBuilderExtensions.
|
||||
MapGet(app, "/hello2/{id}", (int id) => $"Hello {id}!");
|
||||
app.
|
||||
MapGet("/hello1/{id}", (int id) => $"Hello {id}!");
|
||||
EndpointRouteBuilderExtensions.
|
||||
MapGet(app, "/hello2/{id}", (int id) => $"Hello {id}!");
|
||||
app.
|
||||
|
||||
|
||||
MapGet("/hello1/{id}", (int id) => $"Hello {id}!");
|
||||
EndpointRouteBuilderExtensions.
|
||||
|
||||
|
||||
MapGet(app, "/hello2/{id}", (int id) => $"Hello {id}!");
|
||||
app.
|
||||
MapGet
|
||||
("/hello1/{id}", (int id) => $"Hello {id}!");
|
||||
EndpointRouteBuilderExtensions.
|
||||
MapGet
|
||||
(app, "/hello2/{id}", (int id) => $"Hello {id}!");
|
||||
app
|
||||
.
|
||||
MapGet
|
||||
("/hello1/{id}", (int id) => $"Hello {id}!");
|
||||
EndpointRouteBuilderExtensions
|
||||
.
|
||||
MapGet
|
||||
(app, "/hello2/{id}", (int id) => $"Hello {id}!");
|
||||
""";
|
||||
var (_, compilation) = await RunGeneratorAsync(source);
|
||||
var endpoints = GetEndpointsFromCompilation(compilation);
|
||||
|
||||
for (int i = 0; i < endpoints.Length; i++)
|
||||
{
|
||||
var httpContext = CreateHttpContext();
|
||||
httpContext.Request.RouteValues["id"] = i.ToString(CultureInfo.InvariantCulture);
|
||||
await endpoints[i].RequestDelegate(httpContext);
|
||||
await VerifyResponseBodyAsync(httpContext, $"Hello {i}!");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SourceMapsAllPathsInAttribute()
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Antiforgery;
|
||||
using Microsoft.AspNetCore.Http.Metadata;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
@ -16,7 +17,8 @@ namespace Microsoft.AspNetCore.Http.Features;
|
|||
public class FormFeature : IFormFeature
|
||||
{
|
||||
private readonly HttpRequest _request;
|
||||
private readonly FormOptions _options;
|
||||
private readonly Endpoint? _endpoint;
|
||||
private FormOptions _options;
|
||||
private Task<IFormCollection>? _parsedFormTask;
|
||||
private IFormCollection? _form;
|
||||
|
||||
|
@ -48,12 +50,18 @@ public class FormFeature : IFormFeature
|
|||
/// <param name="request">The <see cref="HttpRequest"/>.</param>
|
||||
/// <param name="options">The <see cref="FormOptions"/>.</param>
|
||||
public FormFeature(HttpRequest request, FormOptions options)
|
||||
: this(request, options, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal FormFeature(HttpRequest request, FormOptions options, Endpoint? endpoint)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
|
||||
_request = request;
|
||||
_options = options;
|
||||
_endpoint = endpoint;
|
||||
}
|
||||
|
||||
// Internal for testing.
|
||||
|
@ -144,6 +152,7 @@ public class FormFeature : IFormFeature
|
|||
private async Task<IFormCollection> InnerReadFormAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
HandleUncheckedAntiforgeryValidationFeature();
|
||||
_options = _endpoint is null ? _options : GetFormOptionsFromMetadata(_options, _endpoint);
|
||||
|
||||
if (!HasFormContentType)
|
||||
{
|
||||
|
@ -345,4 +354,21 @@ public class FormFeature : IFormFeature
|
|||
}
|
||||
return boundary.ToString();
|
||||
}
|
||||
|
||||
private static FormOptions GetFormOptionsFromMetadata(FormOptions baseFormOptions, Endpoint endpoint)
|
||||
{
|
||||
var formOptionsMetadatas = endpoint.Metadata
|
||||
.GetOrderedMetadata<IFormOptionsMetadata>();
|
||||
var metadataCount = formOptionsMetadatas.Count;
|
||||
if (metadataCount == 0)
|
||||
{
|
||||
return baseFormOptions;
|
||||
}
|
||||
var finalFormOptionsMetadata = new MutableFormOptionsMetadata(formOptionsMetadatas[metadataCount - 1]);
|
||||
for (int i = metadataCount - 2; i >= 0; i--)
|
||||
{
|
||||
formOptionsMetadatas[i].MergeWith(ref finalFormOptionsMetadata);
|
||||
}
|
||||
return finalFormOptionsMetadata.ResolveFormOptions(baseFormOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ internal sealed class DefaultHttpRequest : HttpRequest
|
|||
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
|
||||
private static readonly Func<IFeatureCollection, IHttpRequestFeature?> _nullRequestFeature = f => null;
|
||||
private static readonly Func<IFeatureCollection, IQueryFeature?> _newQueryFeature = f => new QueryFeature(f);
|
||||
private static readonly Func<DefaultHttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r, r._context.FormOptions ?? FormOptions.Default);
|
||||
private static readonly Func<DefaultHttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r, r._context.FormOptions ?? FormOptions.Default, r._context.GetEndpoint());
|
||||
private static readonly Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
|
||||
private static readonly Func<IFeatureCollection, IRouteValuesFeature> _newRouteValuesFeature = f => new RouteValuesFeature();
|
||||
private static readonly Func<HttpContext, IRequestBodyPipeFeature> _newRequestBodyPipeFeature = context => new RequestBodyPipeFeature(context);
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.AspNetCore.Http.Metadata;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
internal static class FormOptionsMetadataExtensions
|
||||
{
|
||||
public static void MergeWith(
|
||||
this IFormOptionsMetadata formOptionsMetadata,
|
||||
ref MutableFormOptionsMetadata otherFormOptionsMetadata)
|
||||
{
|
||||
otherFormOptionsMetadata.BufferBody ??= formOptionsMetadata.BufferBody;
|
||||
otherFormOptionsMetadata.MemoryBufferThreshold ??= formOptionsMetadata.MemoryBufferThreshold;
|
||||
otherFormOptionsMetadata.BufferBodyLengthLimit ??= formOptionsMetadata.BufferBodyLengthLimit;
|
||||
otherFormOptionsMetadata.ValueCountLimit ??= formOptionsMetadata.ValueCountLimit;
|
||||
otherFormOptionsMetadata.KeyLengthLimit ??= formOptionsMetadata.KeyLengthLimit;
|
||||
otherFormOptionsMetadata.ValueLengthLimit ??= formOptionsMetadata.ValueLengthLimit;
|
||||
otherFormOptionsMetadata.MultipartBoundaryLengthLimit ??= formOptionsMetadata.MultipartBoundaryLengthLimit;
|
||||
otherFormOptionsMetadata.MultipartHeadersCountLimit ??= formOptionsMetadata.MultipartHeadersCountLimit;
|
||||
otherFormOptionsMetadata.MultipartHeadersLengthLimit ??= formOptionsMetadata.MultipartHeadersLengthLimit;
|
||||
otherFormOptionsMetadata.MultipartBodyLengthLimit ??= formOptionsMetadata.MultipartBodyLengthLimit;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using Microsoft.AspNetCore.Http.Metadata;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Features;
|
||||
|
||||
internal struct MutableFormOptionsMetadata(IFormOptionsMetadata formOptionsMetadata) : IFormOptionsMetadata
|
||||
{
|
||||
internal FormOptions ResolveFormOptions(FormOptions baseFormOptions) => new FormOptions
|
||||
{
|
||||
BufferBody = BufferBody ?? baseFormOptions.BufferBody,
|
||||
MemoryBufferThreshold = MemoryBufferThreshold ?? baseFormOptions.MemoryBufferThreshold,
|
||||
BufferBodyLengthLimit = BufferBodyLengthLimit ?? baseFormOptions.BufferBodyLengthLimit,
|
||||
ValueCountLimit = ValueCountLimit ?? baseFormOptions.ValueCountLimit,
|
||||
KeyLengthLimit = KeyLengthLimit ?? baseFormOptions.KeyLengthLimit,
|
||||
ValueLengthLimit = ValueLengthLimit ?? baseFormOptions.ValueLengthLimit,
|
||||
MultipartBoundaryLengthLimit = MultipartBoundaryLengthLimit ?? baseFormOptions.MultipartBoundaryLengthLimit,
|
||||
MultipartHeadersCountLimit = MultipartHeadersCountLimit ?? baseFormOptions.MultipartHeadersCountLimit,
|
||||
MultipartHeadersLengthLimit = MultipartHeadersLengthLimit ?? baseFormOptions.MultipartHeadersLengthLimit,
|
||||
MultipartBodyLengthLimit = MultipartBodyLengthLimit ?? baseFormOptions.MultipartBodyLengthLimit
|
||||
};
|
||||
|
||||
public bool? BufferBody { get; set; } = formOptionsMetadata.BufferBody;
|
||||
public int? MemoryBufferThreshold { get; set; } = formOptionsMetadata.MemoryBufferThreshold;
|
||||
public long? BufferBodyLengthLimit { get; set; } = formOptionsMetadata.BufferBodyLengthLimit;
|
||||
public int? ValueCountLimit { get; set; } = formOptionsMetadata.ValueCountLimit;
|
||||
public int? KeyLengthLimit { get; set; } = formOptionsMetadata.KeyLengthLimit;
|
||||
public int? ValueLengthLimit { get; set; } = formOptionsMetadata.ValueLengthLimit;
|
||||
public int? MultipartBoundaryLengthLimit { get; set; } = formOptionsMetadata.MultipartBoundaryLengthLimit;
|
||||
public int? MultipartHeadersCountLimit { get; set; } = formOptionsMetadata.MultipartHeadersCountLimit;
|
||||
public int? MultipartHeadersLengthLimit { get; set; } = formOptionsMetadata.MultipartHeadersLengthLimit;
|
||||
public long? MultipartBodyLengthLimit { get; set; } = formOptionsMetadata.MultipartBodyLengthLimit;
|
||||
}
|
|
@ -12,9 +12,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="$(SharedSourceRoot)CancellationTokenSourcePool.cs" />
|
||||
<Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" LinkBase="Shared"/>
|
||||
<Compile Include="$(SharedSourceRoot)ValueTaskExtensions\**\*.cs" LinkBase="Shared"/>
|
||||
<Compile Include="$(SharedSourceRoot)CancellationTokenSourcePool.cs" />
|
||||
<Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" LinkBase="Shared" />
|
||||
<Compile Include="$(SharedSourceRoot)ValueTaskExtensions\**\*.cs" LinkBase="Shared" />
|
||||
<Compile Include="..\..\Shared\StreamCopyOperationInternal.cs" Link="Internal\StreamCopyOperationInternal.cs" />
|
||||
<Compile Include="..\..\Shared\CookieHeaderParserShared.cs" Link="Internal\CookieHeaderParserShared.cs" />
|
||||
<Compile Include="$(SharedSourceRoot)HttpRuleParser.cs" LinkBase="Shared" />
|
||||
|
|
|
@ -33,7 +33,6 @@ public class EndpointRoutingShortCircuitBenchmark
|
|||
new BenchmarkEndpointDataSource(),
|
||||
new DiagnosticListener("benchmark"),
|
||||
Options.Create(new RouteOptions()),
|
||||
Options.Create(new FormOptions()),
|
||||
routingMetrics,
|
||||
context => Task.CompletedTask);
|
||||
|
||||
|
@ -46,7 +45,6 @@ public class EndpointRoutingShortCircuitBenchmark
|
|||
new BenchmarkEndpointDataSource(),
|
||||
new DiagnosticListener("benchmark"),
|
||||
Options.Create(new RouteOptions()),
|
||||
Options.Create(new FormOptions()),
|
||||
routingMetrics,
|
||||
context => Task.CompletedTask);
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ public static class RoutingEndpointConventionBuilderExtensions
|
|||
{
|
||||
throw new InvalidOperationException("This endpoint does not support Order.");
|
||||
}
|
||||
});
|
||||
});
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ internal sealed partial class EndpointRoutingMiddleware
|
|||
private readonly RoutingMetrics _metrics;
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly RouteOptions _routeOptions;
|
||||
private readonly FormOptions _formOptions;
|
||||
private Task<Matcher>? _initializationTask;
|
||||
|
||||
public EndpointRoutingMiddleware(
|
||||
|
@ -39,7 +38,6 @@ internal sealed partial class EndpointRoutingMiddleware
|
|||
EndpointDataSource rootCompositeEndpointDataSource,
|
||||
DiagnosticListener diagnosticListener,
|
||||
IOptions<RouteOptions> routeOptions,
|
||||
IOptions<FormOptions> formOptions,
|
||||
RoutingMetrics metrics,
|
||||
RequestDelegate next)
|
||||
{
|
||||
|
@ -51,7 +49,6 @@ internal sealed partial class EndpointRoutingMiddleware
|
|||
_metrics = metrics;
|
||||
_next = next ?? throw new ArgumentNullException(nameof(next));
|
||||
_routeOptions = routeOptions.Value;
|
||||
_formOptions = formOptions.Value;
|
||||
|
||||
// rootCompositeEndpointDataSource is a constructor parameter only so it always gets disposed by DI. This ensures that any
|
||||
// disposable EndpointDataSources also get disposed. _endpointDataSource is a component of rootCompositeEndpointDataSource.
|
||||
|
@ -139,14 +136,6 @@ internal sealed partial class EndpointRoutingMiddleware
|
|||
// We do this during endpoint routing to ensure that successive middlewares in the pipeline
|
||||
// can access the feature with the correct value.
|
||||
SetMaxRequestBodySize(httpContext);
|
||||
// Map IFormOptionsMetadata to IFormFeature if present on the endpoint if the
|
||||
// request being processed is a form request. Note: we do a manual check for the
|
||||
// form content-types here to avoid prematurely accessing the form feature.
|
||||
if (HttpExtensions.IsValidHttpMethodForForm(httpContext.Request.Method) &&
|
||||
HttpExtensions.IsValidContentTypeForForm(httpContext.Request.ContentType))
|
||||
{
|
||||
SetFormOptions(httpContext, endpoint);
|
||||
}
|
||||
|
||||
var shortCircuitMetadata = endpoint.Metadata.GetMetadata<ShortCircuitMetadata>();
|
||||
if (shortCircuitMetadata is not null)
|
||||
|
@ -345,45 +334,6 @@ internal sealed partial class EndpointRoutingMiddleware
|
|||
}
|
||||
}
|
||||
|
||||
private void SetFormOptions(HttpContext context, Endpoint endpoint)
|
||||
{
|
||||
var features = context.Features;
|
||||
var formFeature = features.Get<IFormFeature>();
|
||||
|
||||
// Request form has not been read yet, so set the limits
|
||||
if (formFeature == null || formFeature is { Form: null })
|
||||
{
|
||||
var baseFormOptions = _formOptions;
|
||||
var finalFormOptionsMetadata = new FormOptionsMetadata();
|
||||
var formOptionsMetadatas = endpoint.Metadata
|
||||
.GetOrderedMetadata<IFormOptionsMetadata>();
|
||||
foreach (var formOptionsMetadata in formOptionsMetadatas)
|
||||
{
|
||||
finalFormOptionsMetadata = finalFormOptionsMetadata.MergeWith(formOptionsMetadata);
|
||||
}
|
||||
|
||||
var formOptions = new FormOptions
|
||||
{
|
||||
BufferBody = finalFormOptionsMetadata.BufferBody ?? baseFormOptions.BufferBody,
|
||||
MemoryBufferThreshold = finalFormOptionsMetadata.MemoryBufferThreshold ?? baseFormOptions.MemoryBufferThreshold,
|
||||
BufferBodyLengthLimit = finalFormOptionsMetadata.BufferBodyLengthLimit ?? baseFormOptions.BufferBodyLengthLimit,
|
||||
ValueCountLimit = finalFormOptionsMetadata.ValueCountLimit ?? baseFormOptions.ValueCountLimit,
|
||||
KeyLengthLimit = finalFormOptionsMetadata.KeyLengthLimit ?? baseFormOptions.KeyLengthLimit,
|
||||
ValueLengthLimit = finalFormOptionsMetadata.ValueLengthLimit ?? baseFormOptions.ValueLengthLimit,
|
||||
MultipartBoundaryLengthLimit = finalFormOptionsMetadata.MultipartBoundaryLengthLimit ?? baseFormOptions.MultipartBoundaryLengthLimit,
|
||||
MultipartHeadersCountLimit = finalFormOptionsMetadata.MultipartHeadersCountLimit ?? baseFormOptions.MultipartHeadersCountLimit,
|
||||
MultipartHeadersLengthLimit = finalFormOptionsMetadata.MultipartHeadersLengthLimit ?? baseFormOptions.MultipartHeadersLengthLimit,
|
||||
MultipartBodyLengthLimit = finalFormOptionsMetadata.MultipartBodyLengthLimit ?? baseFormOptions.MultipartBodyLengthLimit
|
||||
};
|
||||
features.Set<IFormFeature>(new FormFeature(context.Request, formOptions));
|
||||
Log.AppliedFormOptions(_logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.CannotApplyFormOptions(_logger);
|
||||
}
|
||||
}
|
||||
|
||||
private static partial class Log
|
||||
{
|
||||
public static void MatchSuccess(ILogger logger, Endpoint endpoint)
|
||||
|
@ -427,11 +377,5 @@ internal sealed partial class EndpointRoutingMiddleware
|
|||
|
||||
[LoggerMessage(12, LogLevel.Debug, "The maximum request body size has been disabled.", EventName = "MaxRequestBodySizeDisabled")]
|
||||
public static partial void MaxRequestBodySizeDisabled(ILogger logger);
|
||||
|
||||
[LoggerMessage(13, LogLevel.Warning, "Unable to apply configured form options since the request form has already been read.", EventName = "CannotApplyFormOptions")]
|
||||
public static partial void CannotApplyFormOptions(ILogger logger);
|
||||
|
||||
[LoggerMessage(14, LogLevel.Debug, "Applied the configured form options on the current request.", EventName = "AppliedFormOptions")]
|
||||
public static partial void AppliedFormOptions(ILogger logger);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using Microsoft.AspNetCore.Http.Metadata;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing;
|
||||
|
||||
internal static class FormOptionsMetadataExtensions
|
||||
{
|
||||
public static FormOptionsMetadata MergeWith(
|
||||
this IFormOptionsMetadata formOptionsMetadata,
|
||||
IFormOptionsMetadata otherFormOptionsMetadata)
|
||||
{
|
||||
var _bufferBody = otherFormOptionsMetadata.BufferBody != null ? otherFormOptionsMetadata.BufferBody : formOptionsMetadata.BufferBody;
|
||||
var _memoryBufferThreshold = otherFormOptionsMetadata.MemoryBufferThreshold != null ? otherFormOptionsMetadata.MemoryBufferThreshold : formOptionsMetadata.MemoryBufferThreshold;
|
||||
var _bufferBodyLengthLimit = otherFormOptionsMetadata.BufferBodyLengthLimit != null ? otherFormOptionsMetadata.BufferBodyLengthLimit : formOptionsMetadata.BufferBodyLengthLimit;
|
||||
var _valueCountLimit = otherFormOptionsMetadata.ValueCountLimit != null ? otherFormOptionsMetadata.ValueCountLimit : formOptionsMetadata.ValueCountLimit;
|
||||
var _keyLengthLimit = otherFormOptionsMetadata.KeyLengthLimit != null ? otherFormOptionsMetadata.KeyLengthLimit : formOptionsMetadata.KeyLengthLimit;
|
||||
var _valueLengthLimit = otherFormOptionsMetadata.ValueLengthLimit != null ? otherFormOptionsMetadata.ValueLengthLimit : formOptionsMetadata.ValueLengthLimit;
|
||||
var _multipartBoundaryLengthLimit = otherFormOptionsMetadata.MultipartBoundaryLengthLimit != null ? otherFormOptionsMetadata.MultipartBoundaryLengthLimit : formOptionsMetadata.MultipartBoundaryLengthLimit;
|
||||
var _multipartHeadersCountLimit = otherFormOptionsMetadata.MultipartHeadersCountLimit != null ? otherFormOptionsMetadata.MultipartHeadersCountLimit : formOptionsMetadata.MultipartHeadersCountLimit;
|
||||
var _multipartHeadersLengthLimit = otherFormOptionsMetadata.MultipartHeadersLengthLimit != null ? otherFormOptionsMetadata.MultipartHeadersLengthLimit : formOptionsMetadata.MultipartHeadersLengthLimit;
|
||||
var _multipartBodyLengthLimit = otherFormOptionsMetadata.MultipartBodyLengthLimit != null ? otherFormOptionsMetadata.MultipartBodyLengthLimit : formOptionsMetadata.MultipartBodyLengthLimit;
|
||||
return new FormOptionsMetadata(_bufferBody, _memoryBufferThreshold, _bufferBodyLengthLimit, _valueCountLimit, _keyLengthLimit, _valueLengthLimit, _multipartBoundaryLengthLimit, _multipartHeadersCountLimit, _multipartHeadersLengthLimit, _multipartBodyLengthLimit);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
|
@ -8,7 +9,6 @@ using Microsoft.AspNetCore.Http.Metadata;
|
|||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.TestObjects;
|
||||
using Microsoft.AspNetCore.Testing;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
@ -20,42 +20,6 @@ namespace Microsoft.AspNetCore.Routing;
|
|||
|
||||
public class EndpointRoutingMiddlewareFormOptionsTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task LogsWhenFormOptionsAreNotApplied()
|
||||
{
|
||||
var sink = new TestSink(TestSink.EnableWithTypeName<EndpointRoutingMiddleware>);
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
var logger = new Logger<EndpointRoutingMiddleware>(loggerFactory);
|
||||
|
||||
var httpContext = CreateHttpContext();
|
||||
var presetFormFeature = new FormFeature(httpContext.Request, FormOptions.Default);
|
||||
presetFormFeature.Form = new FormCollection(new());
|
||||
httpContext.Features.Set<IFormFeature>(presetFormFeature);
|
||||
|
||||
var formOptionsMetadata = new FormOptionsMetadata(bufferBody: false, valueCountLimit: 54);
|
||||
var middleware = CreateMiddleware(
|
||||
logger: logger,
|
||||
matcherFactory: new TestMatcherFactory(isHandled: true, setEndpointCallback: c =>
|
||||
{
|
||||
c.SetEndpoint(new Endpoint(c => Task.CompletedTask, new EndpointMetadataCollection(formOptionsMetadata), "myapp"));
|
||||
}));
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
|
||||
var formFeature = httpContext.Features.Get<IFormFeature>();
|
||||
var formOptions = Assert.IsType<FormFeature>(formFeature).FormOptions;
|
||||
// Configured values are set
|
||||
Assert.False(formOptions.BufferBody);
|
||||
Assert.Equal(FormReader.DefaultValueCountLimit, formOptions.ValueCountLimit);
|
||||
// Unset values are set to default instead of null
|
||||
Assert.Equal(FormOptions.DefaultMemoryBufferThreshold, formOptions.MemoryBufferThreshold);
|
||||
|
||||
// Logs that FormOptions were not applied
|
||||
var write = Assert.Single(sink.Writes.Where(w => w.EventId.Name == "CannotApplyFormOptions"));
|
||||
Assert.Equal("Unable to apply configured form options since the request form has already been read.", write.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SupportsSettingFormOptionsFromMetadata()
|
||||
{
|
||||
|
@ -64,6 +28,8 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
var logger = new Logger<EndpointRoutingMiddleware>(loggerFactory);
|
||||
|
||||
var httpContext = CreateHttpContext();
|
||||
httpContext.Request.ContentType = "application/x-www-form-urlencoded";
|
||||
httpContext.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes("foo=bar"));
|
||||
|
||||
var formOptionsMetadata = new FormOptionsMetadata(bufferBody: false, valueCountLimit: 54);
|
||||
var middleware = CreateMiddleware(
|
||||
|
@ -75,6 +41,7 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
var _ = httpContext.Request.Form; // Trigger the form feature.
|
||||
|
||||
var formFeature = httpContext.Features.Get<IFormFeature>();
|
||||
var formOptions = Assert.IsType<FormFeature>(formFeature).FormOptions;
|
||||
|
@ -83,10 +50,6 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
Assert.Equal(54, formOptions.ValueCountLimit);
|
||||
// Unset values are set to default instead of null
|
||||
Assert.Equal(FormOptions.DefaultMemoryBufferThreshold, formOptions.MemoryBufferThreshold);
|
||||
|
||||
// Logs that FormOptions were applied
|
||||
var write = Assert.Single(sink.Writes.Where(w => w.EventId.Name == "AppliedFormOptions"));
|
||||
Assert.Equal("Applied the configured form options on the current request.", write.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -97,6 +60,8 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
var logger = new Logger<EndpointRoutingMiddleware>(loggerFactory);
|
||||
|
||||
var httpContext = CreateHttpContext();
|
||||
httpContext.Request.ContentType = "application/x-www-form-urlencoded";
|
||||
httpContext.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes("foo=bar"));
|
||||
|
||||
var formOptionsMetadata1 = new FormOptionsMetadata(bufferBody: false, valueCountLimit: 54);
|
||||
var formOptionsMetadata2 = new FormOptionsMetadata(valueLengthLimit: 45);
|
||||
|
@ -110,6 +75,7 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
var _ = httpContext.Request.Form; // Trigger the form feature.
|
||||
|
||||
var formFeature = httpContext.Features.Get<IFormFeature>();
|
||||
var formOptions = Assert.IsType<FormFeature>(formFeature).FormOptions;
|
||||
|
@ -119,10 +85,6 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
Assert.Equal(45, formOptions.ValueLengthLimit);
|
||||
// Unset values are set to default instead of null
|
||||
Assert.Equal(FormOptions.DefaultMemoryBufferThreshold, formOptions.MemoryBufferThreshold);
|
||||
|
||||
// Logs that FormOptions were applied
|
||||
var write = Assert.Single(sink.Writes.Where(w => w.EventId.Name == "AppliedFormOptions"));
|
||||
Assert.Equal("Applied the configured form options on the current request.", write.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -131,7 +93,15 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
var sink = new TestSink(TestSink.EnableWithTypeName<EndpointRoutingMiddleware>);
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
var logger = new Logger<EndpointRoutingMiddleware>(loggerFactory);
|
||||
var httpContext = CreateHttpContext();
|
||||
var serviceProvider = new ServiceCollection().Configure<FormOptions>(options =>
|
||||
{
|
||||
options.BufferBody = true;
|
||||
options.ValueLengthLimit = 45;
|
||||
}).BuildServiceProvider();
|
||||
var httpContextFactory = new DefaultHttpContextFactory(serviceProvider);
|
||||
var httpContext = httpContextFactory.Create( new DefaultHttpContext().Features);
|
||||
httpContext.Request.ContentType = "application/x-www-form-urlencoded";
|
||||
httpContext.Request.Body = new MemoryStream("foo=bar"u8.ToArray());
|
||||
|
||||
var formOptionsMetadata = new FormOptionsMetadata(bufferBody: false, valueCountLimit: 54);
|
||||
var middleware = CreateMiddleware(
|
||||
|
@ -139,11 +109,11 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
matcherFactory: new TestMatcherFactory(isHandled: true, setEndpointCallback: c =>
|
||||
{
|
||||
c.SetEndpoint(new Endpoint(c => Task.CompletedTask, new EndpointMetadataCollection(formOptionsMetadata), "myapp"));
|
||||
}),
|
||||
formOptions: new FormOptions { BufferBody = true, ValueLengthLimit = 45});
|
||||
}));
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
var _ = httpContext.Request.Form; // Trigger the form feature.
|
||||
|
||||
var formFeature = httpContext.Features.Get<IFormFeature>();
|
||||
var formOptions = Assert.IsType<FormFeature>(formFeature).FormOptions;
|
||||
|
@ -156,12 +126,15 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SettingEndpointManuallyDoesNotOverwriteOptions()
|
||||
public async Task SettingEndpointManuallyStillResolvesFormOptions()
|
||||
{
|
||||
var sink = new TestSink(TestSink.EnableWithTypeName<EndpointRoutingMiddleware>);
|
||||
var loggerFactory = new TestLoggerFactory(sink, enabled: true);
|
||||
var logger = new Logger<EndpointRoutingMiddleware>(loggerFactory);
|
||||
var httpContext = CreateHttpContext();
|
||||
httpContext.Request.ContentType = "application/x-www-form-urlencoded";
|
||||
httpContext.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes("foo=bar"));
|
||||
|
||||
var endpointMetadata = new FormOptionsMetadata(bufferBody: true, valueCountLimit: 70);
|
||||
var endpoint = new Endpoint(c => Task.CompletedTask, new EndpointMetadataCollection(endpointMetadata), "myapp");
|
||||
|
||||
|
@ -176,12 +149,13 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
// Act
|
||||
await middleware.Invoke(httpContext);
|
||||
httpContext.SetEndpoint(endpoint);
|
||||
var _ = httpContext.Request.Form; // Trigger the form feature.
|
||||
|
||||
var formFeature = httpContext.Features.Get<IFormFeature>();
|
||||
var formOptions = Assert.IsType<FormFeature>(formFeature).FormOptions;
|
||||
// Favor the most specific (last) value set for a property
|
||||
Assert.False(formOptions.BufferBody);
|
||||
Assert.Equal(54, formOptions.ValueCountLimit);
|
||||
Assert.True(formOptions.BufferBody);
|
||||
Assert.Equal(70, formOptions.ValueCountLimit);
|
||||
// Unset values are set to default instead of null
|
||||
Assert.Equal(FormOptions.DefaultMemoryBufferThreshold, formOptions.MemoryBufferThreshold);
|
||||
}
|
||||
|
@ -231,8 +205,7 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
ILogger<EndpointRoutingMiddleware> logger = null,
|
||||
MatcherFactory matcherFactory = null,
|
||||
DiagnosticListener listener = null,
|
||||
RequestDelegate next = null,
|
||||
FormOptions formOptions = null)
|
||||
RequestDelegate next = null)
|
||||
{
|
||||
next ??= c => Task.CompletedTask;
|
||||
logger ??= new Logger<EndpointRoutingMiddleware>(NullLoggerFactory.Instance);
|
||||
|
@ -247,7 +220,6 @@ public class EndpointRoutingMiddlewareFormOptionsTest
|
|||
new DefaultEndpointDataSource(),
|
||||
listener,
|
||||
Options.Create(new RouteOptions()),
|
||||
Options.Create(formOptions ?? new FormOptions()),
|
||||
metrics,
|
||||
next);
|
||||
|
||||
|
|
|
@ -449,7 +449,6 @@ public class EndpointRoutingMiddlewareTest
|
|||
new DefaultEndpointDataSource(),
|
||||
listener,
|
||||
Options.Create(new RouteOptions()),
|
||||
Options.Create(new FormOptions()),
|
||||
metrics,
|
||||
next);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNetCore.Http" />
|
||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.AspNetCore.Http.Results" />
|
||||
<Reference Include="Microsoft.AspNetCore.Routing" />
|
||||
<Reference Include="Microsoft.AspNetCore.Http.Results" />
|
||||
|
|
|
@ -167,7 +167,6 @@ public class RoutingMetricsTests
|
|||
new DefaultEndpointDataSource(),
|
||||
listener,
|
||||
Options.Create(new RouteOptions()),
|
||||
Options.Create(new FormOptions()),
|
||||
metrics,
|
||||
next);
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ public static class IdentityApiEndpointRouteBuilderExtensions
|
|||
|
||||
var useCookieScheme = (useCookies == true) || (useSessionCookies == true);
|
||||
var isPersistent = (useCookies == true) && (useSessionCookies != true);
|
||||
signInManager.PrimaryAuthenticationScheme = useCookieScheme ? IdentityConstants.ApplicationScheme : IdentityConstants.BearerScheme;
|
||||
signInManager.AuthenticationScheme = useCookieScheme ? IdentityConstants.ApplicationScheme : IdentityConstants.BearerScheme;
|
||||
|
||||
var result = await signInManager.PasswordSignInAsync(login.Email, login.Password, isPersistent, lockoutOnFailure: true);
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ Microsoft.AspNetCore.Identity.SecurityStampValidator<TUser>.SecurityStampValidat
|
|||
Microsoft.AspNetCore.Identity.SecurityStampValidator<TUser>.TimeProvider.get -> System.TimeProvider!
|
||||
Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions.TimeProvider.get -> System.TimeProvider?
|
||||
Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions.TimeProvider.set -> void
|
||||
Microsoft.AspNetCore.Identity.SignInManager<TUser>.PrimaryAuthenticationScheme.get -> string!
|
||||
Microsoft.AspNetCore.Identity.SignInManager<TUser>.PrimaryAuthenticationScheme.set -> void
|
||||
Microsoft.AspNetCore.Identity.SignInManager<TUser>.AuthenticationScheme.get -> string!
|
||||
Microsoft.AspNetCore.Identity.SignInManager<TUser>.AuthenticationScheme.set -> void
|
||||
Microsoft.AspNetCore.Identity.TwoFactorSecurityStampValidator<TUser>.TwoFactorSecurityStampValidator(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions!>! options, Microsoft.AspNetCore.Identity.SignInManager<TUser!>! signInManager, Microsoft.Extensions.Logging.ILoggerFactory! logger) -> void
|
||||
Microsoft.AspNetCore.Routing.IdentityApiEndpointRouteBuilderExtensions
|
||||
static Microsoft.AspNetCore.Identity.IdentityBuilderExtensions.AddApiEndpoints(this Microsoft.AspNetCore.Identity.IdentityBuilder! builder) -> Microsoft.AspNetCore.Identity.IdentityBuilder!
|
||||
|
|
|
@ -84,7 +84,7 @@ public class SignInManager<TUser> where TUser : class
|
|||
/// <summary>
|
||||
/// The authentication scheme to sign in with. Defaults to <see cref="IdentityConstants.ApplicationScheme"/>.
|
||||
/// </summary>
|
||||
public string PrimaryAuthenticationScheme { get; set; } = IdentityConstants.ApplicationScheme;
|
||||
public string AuthenticationScheme { get; set; } = IdentityConstants.ApplicationScheme;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="HttpContext"/> used.
|
||||
|
@ -122,7 +122,7 @@ public class SignInManager<TUser> where TUser : class
|
|||
{
|
||||
ArgumentNullException.ThrowIfNull(principal);
|
||||
return principal.Identities != null &&
|
||||
principal.Identities.Any(i => i.AuthenticationType == PrimaryAuthenticationScheme);
|
||||
principal.Identities.Any(i => i.AuthenticationType == AuthenticationScheme);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -161,7 +161,7 @@ public class SignInManager<TUser> where TUser : class
|
|||
/// <returns>The task object representing the asynchronous operation.</returns>
|
||||
public virtual async Task RefreshSignInAsync(TUser user)
|
||||
{
|
||||
var auth = await Context.AuthenticateAsync(PrimaryAuthenticationScheme);
|
||||
var auth = await Context.AuthenticateAsync(AuthenticationScheme);
|
||||
IList<Claim> claims = Array.Empty<Claim>();
|
||||
|
||||
var authenticationMethod = auth?.Principal?.FindFirst(ClaimTypes.AuthenticationMethod);
|
||||
|
@ -237,7 +237,7 @@ public class SignInManager<TUser> where TUser : class
|
|||
{
|
||||
userPrincipal.Identities.First().AddClaim(claim);
|
||||
}
|
||||
await Context.SignInAsync(PrimaryAuthenticationScheme,
|
||||
await Context.SignInAsync(AuthenticationScheme,
|
||||
userPrincipal,
|
||||
authenticationProperties ?? new AuthenticationProperties());
|
||||
|
||||
|
@ -250,7 +250,7 @@ public class SignInManager<TUser> where TUser : class
|
|||
/// </summary>
|
||||
public virtual async Task SignOutAsync()
|
||||
{
|
||||
await Context.SignOutAsync(PrimaryAuthenticationScheme);
|
||||
await Context.SignOutAsync(AuthenticationScheme);
|
||||
|
||||
if (await _schemes.GetSchemeAsync(IdentityConstants.ExternalScheme) != null)
|
||||
{
|
||||
|
@ -669,9 +669,9 @@ public class SignInManager<TUser> where TUser : class
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="AuthenticationScheme"/>s for the known external login providers.
|
||||
/// Gets a collection of <see cref="Authentication.AuthenticationScheme"/>s for the known external login providers.
|
||||
/// </summary>
|
||||
/// <returns>A collection of <see cref="AuthenticationScheme"/>s for the known external login providers.</returns>
|
||||
/// <returns>A collection of <see cref="Authentication.AuthenticationScheme"/>s for the known external login providers.</returns>
|
||||
public virtual async Task<IEnumerable<AuthenticationScheme>> GetExternalAuthenticationSchemesAsync()
|
||||
{
|
||||
var schemes = await _schemes.GetAllSchemesAsync();
|
||||
|
|
|
@ -2350,6 +2350,7 @@ public class HubConnectionTests : FunctionalTestBase
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/50180")]
|
||||
public async Task LongPollingUsesHttp2ByDefault()
|
||||
{
|
||||
await using (var server = await StartServer<Startup>(configureKestrelServerOptions: o =>
|
||||
|
|
|
@ -9,5 +9,5 @@ public static class HelixConstants
|
|||
public const string DebianAmd64 = "Debian.11.Amd64.Open;";
|
||||
public const string DebianArm64 = "Debian.11.Arm64.Open;";
|
||||
public const string AlmaLinuxAmd64 = "(AlmaLinux.8.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:almalinux-8-helix-amd64;";
|
||||
public const string NativeAotNotSupportedHelixQueues = "All.OSX;All.Linux;Windows.11.Amd64.Client.Open;Windows.Amd64.Server2022.Open;windows.11.arm64.open";
|
||||
public const string NativeAotNotSupportedHelixQueues = "All.OSX;All.Linux;Windows.11.Amd64.Client.Open;Windows.11.Amd64.Client;Windows.Amd64.Server2022.Open;Windows.Amd64.Server2022;windows.11.arm64.open;windows.11.arm64";
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче