Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
ed0abe5e24
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
/build/ @natemcmaster
|
||||
/eng/ @natemcmaster
|
||||
/src/Components/ @SteveSandersonMS
|
||||
/src/DefaultBuilder/ @tratcher
|
||||
/src/Hosting/ @tratcher
|
||||
/src/Http/ @tratcher
|
||||
|
|
|
|||
|
|
@ -102,6 +102,11 @@ param(
|
|||
[Parameter(ParameterSetName = 'Groups')]
|
||||
[switch]$Installers,
|
||||
|
||||
# By default, Windows builds will use MSBuild.exe. Passing this will force the build to run on
|
||||
# dotnet.exe instead, which may cause issues if you invoke build on a project unsupported by
|
||||
# MSBuild for .NET Core
|
||||
[switch]$ForceCoreMsbuild,
|
||||
|
||||
# Other lifecycle targets
|
||||
[switch]$Help, # Show help
|
||||
|
||||
|
|
@ -269,6 +274,9 @@ Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
|
|||
|
||||
try {
|
||||
Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $RepoRoot -ConfigFile $ConfigFile -CI:$CI
|
||||
if ($ForceCoreMsbuild) {
|
||||
$global:KoreBuildSettings.MSBuildType = 'core'
|
||||
}
|
||||
Invoke-KoreBuildCommand 'default-build' @MSBuildArguments
|
||||
}
|
||||
finally {
|
||||
|
|
|
|||
|
|
@ -1,130 +1,13 @@
|
|||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PublishDependsOn>
|
||||
GetFilesToPublish;
|
||||
PublishToAzureFeed;
|
||||
PublishToMyGet;
|
||||
</PublishDependsOn>
|
||||
</PropertyGroup>
|
||||
<Target Name="Publish">
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)publish\Publish.csproj"
|
||||
Targets="Restore"
|
||||
Properties="$(BuildProperties);KoreBuildTasksDll=$(KoreBuildTasksDll);__DummyTarget=Restore" />
|
||||
|
||||
<Target Name="Publish" DependsOnTargets="$(PublishDependsOn)" />
|
||||
|
||||
<Target Name="GetFilesToPublish">
|
||||
<ItemGroup>
|
||||
<!-- Installer output files with specific metadata. -->
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*.txt">
|
||||
<ContentType>text/plain</ContentType>
|
||||
</_FilesToPublish>
|
||||
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*.version">
|
||||
<ContentType>text/plain</ContentType>
|
||||
<CacheControl>no-cache, no-store, must-revalidate</CacheControl>
|
||||
</_FilesToPublish>
|
||||
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*.svg">
|
||||
<CacheControl>no-cache, no-store, must-revalidate</CacheControl>
|
||||
<ContentType>image/svg+xml</ContentType>
|
||||
</_FilesToPublish>
|
||||
|
||||
<!-- All other installer files. -->
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*" Exclude="@(_FilesToPublish)" />
|
||||
|
||||
<!-- Java packages -->
|
||||
<_FilesToPublish Include="$(ProductPackageOutputPath)*.jar;$(ProductPackageOutputPath)*.pom">
|
||||
<BlobBasePath>aspnetcore/jar/$(PackageVersion)/</BlobBasePath>
|
||||
</_FilesToPublish>
|
||||
|
||||
<!--
|
||||
Transform the intermediate item group into the final group.
|
||||
You can't use globbing _and_ set metadata using FileName and Extension at the same time. MSBuild quirks are fun.
|
||||
-->
|
||||
<FilesToPublish Include="@(_FilesToPublish)">
|
||||
<RelativeBlobPath Condition="'%(_FilesToPublish.BlobBasePath)' != ''">%(_FilesToPublish.BlobBasePath)%(_FilesToPublish.FileName)%(_FilesToPublish.Extension)</RelativeBlobPath>
|
||||
<RelativeBlobPath Condition="'%(_FilesToPublish.BlobBasePath)' == ''">aspnetcore/Runtime/$(PackageVersion)/%(_FilesToPublish.FileName)%(_FilesToPublish.Extension)</RelativeBlobPath>
|
||||
</FilesToPublish>
|
||||
<_FilesToPublish Remove="@(_FilesToPublish)" />
|
||||
|
||||
<!-- NPM packages -->
|
||||
<NpmPackageToPublish Include="$(ProductPackageOutputPath)*.tgz" />
|
||||
|
||||
<PackageToPublish Include="$(ProductPackageOutputPath)*.symbols.nupkg" IsSymbolsPackage="true" />
|
||||
<PackageToPublish Include="$(ProductPackageOutputPath)*.nupkg" Exclude="@(PackageToPublish)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
'Internal' packages are used to transfer bits to partner teams, and should not be used by customers.
|
||||
Publishing these can be disabled.
|
||||
-->
|
||||
<ItemGroup Condition=" '$(PublishInternalPackages)' != 'false' ">
|
||||
<PackageToPublish Include="$(InternalPackageOutputPath)*.symbols.nupkg" IsSymbolsPackage="true">
|
||||
<ManifestArtifactData>NonShipping=true</ManifestArtifactData>
|
||||
</PackageToPublish>
|
||||
<PackageToPublish Include="$(InternalPackageOutputPath)*.nupkg" Exclude="@(PackageToPublish)">
|
||||
<ManifestArtifactData>NonShipping=true</ManifestArtifactData>
|
||||
</PackageToPublish>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishToMyGet"
|
||||
DependsOnTargets="GetFilesToPublish;GetToolsets"
|
||||
Condition="'$(PublishToMyget)' == 'true'">
|
||||
|
||||
<Error Text="Missing required property: PublishMyGetFeedUrl" Condition=" '$(PublishMyGetFeedUrl)' == '' "/>
|
||||
<Error Text="Missing required property: PublishMyGetSymbolsFeedUrl" Condition=" '$(PublishMyGetSymbolsFeedUrl)' == '' "/>
|
||||
<Error Text="Missing required property: PublishMyGetNpmRegistryUrl" Condition=" '$(PublishMyGetNpmRegistryUrl)' == '' "/>
|
||||
<Error Text="Missing required property: PublishMyGetFeedKey" Condition=" '$(PublishMyGetFeedKey)' == '' "/>
|
||||
|
||||
<Error Text="No packages found to publish" Condition="@(PackageToPublish->Count()) == 0" />
|
||||
|
||||
<PushNuGetPackages Condition="'%(PackageToPublish.IsSymbolsPackage)' != 'true' AND @(PackageToPublish->Count()) != 0"
|
||||
Packages="@(PackageToPublish)"
|
||||
Feed="$(PublishMyGetFeedUrl)"
|
||||
ApiKey="$(PublishMyGetFeedKey)" />
|
||||
|
||||
<PushNuGetPackages Condition="'%(PackageToPublish.IsSymbolsPackage)' == 'true' AND @(PackageToPublish->Count()) != 0"
|
||||
Packages="@(PackageToPublish)"
|
||||
Feed="$(PublishMyGetSymbolsFeedUrl)"
|
||||
ApiKey="$(PublishMyGetFeedKey)" />
|
||||
|
||||
<PropertyGroup>
|
||||
<AuthTokenSetting>$(PublishMyGetNpmRegistryUrl.Replace("https:", "")):_authToken</AuthTokenSetting>
|
||||
</PropertyGroup>
|
||||
|
||||
<Message Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Text="Skipping NPM publish because there are no npm packages to publish."
|
||||
Importance="high" />
|
||||
|
||||
<Exec Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Command="npm config set "$(AuthTokenSetting)" $(PublishMyGetFeedKey)"
|
||||
StandardOutputImportance="Normal" />
|
||||
|
||||
<!-- When you UseCommandProcessor FileName is ignored -->
|
||||
<Run Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
FileName="cmd"
|
||||
Arguments="npm;publish;--registry;$(PublishMyGetNpmRegistryUrl);%(NpmPackageToPublish.Identity)"
|
||||
MaxRetries="5"
|
||||
UseCommandProcessor="true"
|
||||
ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" ItemName="_NpmExitCodes" />
|
||||
</Run>
|
||||
|
||||
<Exec Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Command="npm config delete $(AuthTokenSetting)"
|
||||
StandardOutputImportance="Normal" />
|
||||
|
||||
<Error Text="Publishing npm modules failed" Condition=" @(NpmPackageToPublish->Count()) != 0 AND %(_NpmExitCodes.Identity) != 0" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishToAzureFeed"
|
||||
DependsOnTargets="GetFilesToPublish"
|
||||
Condition="'$(PublishToAzureFeed)' == 'true'">
|
||||
|
||||
<RepoTasks.PublishToAzureBlob
|
||||
AccountName="$(AzureAccountName)"
|
||||
SharedAccessToken="$(AzureSharedAccessToken)"
|
||||
ContainerName="$(AzureContainerName)"
|
||||
Files="@(FilesToPublish)" />
|
||||
<MSBuild Projects="$(MSBuildThisFileDirectory)publish\Publish.csproj"
|
||||
Targets="Publish"
|
||||
Properties="$(BuildProperties);KoreBuildTasksDll=$(KoreBuildTasksDll);__DummyTarget=Publish" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
<SharedFrameworkAndPackage Include="Microsoft.AspNetCore.JsonPatch" />
|
||||
<SharedFrameworkAndPackage Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" />
|
||||
|
||||
<!-- Assemblies required by components and WebAssembly -->
|
||||
<SharedFrameworkAndPackage Include="Microsoft.AspNetCore.Components" />
|
||||
<SharedFrameworkAndPackage Include="Microsoft.AspNetCore.Components.Browser" />
|
||||
|
||||
<!-- Assemblies required by the SignalR client. -->
|
||||
<SharedFrameworkAndPackage Include="Microsoft.AspNetCore.Http.Features" />
|
||||
<SharedFrameworkAndPackage Include="Microsoft.AspNetCore.SignalR.Common" />
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
<ExternalDependency Include="Microsoft.Extensions.Logging.Configuration" Version="$(MicrosoftExtensionsLoggingConfigurationPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.Extensions.Logging.Debug" Version="$(MicrosoftExtensionsLoggingDebugPackageVersion)" />
|
||||
<ExternalDependency Include="Microsoft.JSInterop" Version="$(MicrosoftJSInteropPackageVersion)" />
|
||||
|
||||
<!-- Packages from aspnet/EntityFrameworkCore -->
|
||||
<ExternalDependency Include="dotnet-ef" Version="$(DotNetEfPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
<Project>
|
||||
|
||||
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- TFM doesn't matter. These settings are required to make NuGet happy so we can restore required MSBuild packages. -->
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
|
||||
<ManifestsPath>$(ArtifactsDir)manifests\</ManifestsPath>
|
||||
<MaestroApiEndpoint Condition="'$(MaestroApiEndpoint)' == ''">https://maestro-prod.westus2.cloudapp.azure.com</MaestroApiEndpoint>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.DotNet.Build.Tasks.Feed" Version="2.2.0-beta.19061.6" />
|
||||
<PackageReference Include="Microsoft.DotNet.Maestro.Tasks" Version="1.1.0-beta.19065.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
|
||||
|
||||
<PropertyGroup>
|
||||
<PublishDependsOn>
|
||||
GetFilesToPublish;
|
||||
GenerateBuildAssetManifest;
|
||||
PublishToAzureFeed;
|
||||
PublishToMyGet;
|
||||
PublishToBuildAssetRegistry;
|
||||
</PublishDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="Publish" DependsOnTargets="$(PublishDependsOn)" />
|
||||
|
||||
<Target Name="GetFilesToPublish">
|
||||
<ItemGroup>
|
||||
<!-- Installer output files with specific metadata. -->
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*.txt">
|
||||
<ContentType>text/plain</ContentType>
|
||||
</_FilesToPublish>
|
||||
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*.version">
|
||||
<ContentType>text/plain</ContentType>
|
||||
<CacheControl>no-cache, no-store, must-revalidate</CacheControl>
|
||||
</_FilesToPublish>
|
||||
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*.svg">
|
||||
<CacheControl>no-cache, no-store, must-revalidate</CacheControl>
|
||||
<ContentType>image/svg+xml</ContentType>
|
||||
</_FilesToPublish>
|
||||
|
||||
<!-- All other installer files. -->
|
||||
<_FilesToPublish Include="$(InstallersOutputPath)*" Exclude="@(_FilesToPublish)" />
|
||||
|
||||
<!-- Java packages -->
|
||||
<_FilesToPublish Include="$(ProductPackageOutputPath)*.jar;$(ProductPackageOutputPath)*.pom">
|
||||
<BlobBasePath>aspnetcore/jar/$(PackageVersion)/</BlobBasePath>
|
||||
</_FilesToPublish>
|
||||
|
||||
<!-- NPM packages -->
|
||||
<NpmPackageToPublish Include="$(ProductPackageOutputPath)*.tgz">
|
||||
<BlobBasePath>aspnetcore/npm/$(PackageVersion)/</BlobBasePath>
|
||||
</NpmPackageToPublish>
|
||||
<_FilesToPublish Include="@(NpmPackageToPublish)" />
|
||||
|
||||
<!--
|
||||
Transform the intermediate item group into the final group.
|
||||
You can't use globbing _and_ set metadata using FileName and Extension at the same time. MSBuild quirks are fun.
|
||||
-->
|
||||
<FilesToPublish Include="@(_FilesToPublish)">
|
||||
<RelativeBlobPath Condition="'%(_FilesToPublish.BlobBasePath)' != ''">%(_FilesToPublish.BlobBasePath)%(_FilesToPublish.FileName)%(_FilesToPublish.Extension)</RelativeBlobPath>
|
||||
<RelativeBlobPath Condition="'%(_FilesToPublish.BlobBasePath)' == ''">aspnetcore/Runtime/$(PackageVersion)/%(_FilesToPublish.FileName)%(_FilesToPublish.Extension)</RelativeBlobPath>
|
||||
</FilesToPublish>
|
||||
<_FilesToPublish Remove="@(_FilesToPublish)" />
|
||||
|
||||
<PackageToPublish Include="$(ProductPackageOutputPath)*.symbols.nupkg" IsSymbolsPackage="true" />
|
||||
<PackageToPublish Include="$(ProductPackageOutputPath)*.nupkg" Exclude="@(PackageToPublish)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
'Internal' packages are used to transfer bits to partner teams, and should not be used by customers.
|
||||
Publishing these can be disabled.
|
||||
-->
|
||||
<ItemGroup Condition=" '$(PublishInternalPackages)' != 'false' ">
|
||||
<PackageToPublish Include="$(InternalPackageOutputPath)*.symbols.nupkg" IsSymbolsPackage="true">
|
||||
<ManifestArtifactData>NonShipping=true</ManifestArtifactData>
|
||||
</PackageToPublish>
|
||||
<PackageToPublish Include="$(InternalPackageOutputPath)*.nupkg" Exclude="@(PackageToPublish)">
|
||||
<ManifestArtifactData>NonShipping=true</ManifestArtifactData>
|
||||
</PackageToPublish>
|
||||
</ItemGroup>
|
||||
|
||||
<Error Text="Missing required metadata 'RelativeBlobPath' for FilesToPublish: @(FilesToPublish)" Condition="'@(FilesToPublish)' != '' AND '%(RelativeBlobPath)' == ''" />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="KoreBuild.Tasks.PushNuGetPackages" AssemblyFile="$(KoreBuildTasksDll)" />
|
||||
|
||||
<Target Name="PublishToMyGet"
|
||||
DependsOnTargets="GetFilesToPublish"
|
||||
Condition="'$(PublishToMyget)' == 'true'">
|
||||
|
||||
<Error Text="Missing required property: PublishMyGetFeedUrl" Condition=" '$(PublishMyGetFeedUrl)' == '' "/>
|
||||
<Error Text="Missing required property: PublishMyGetSymbolsFeedUrl" Condition=" '$(PublishMyGetSymbolsFeedUrl)' == '' "/>
|
||||
<Error Text="Missing required property: PublishMyGetNpmRegistryUrl" Condition=" '$(PublishMyGetNpmRegistryUrl)' == '' "/>
|
||||
<Error Text="Missing required property: PublishMyGetFeedKey" Condition=" '$(PublishMyGetFeedKey)' == '' "/>
|
||||
|
||||
<Error Text="No packages found to publish" Condition="@(PackageToPublish->Count()) == 0" />
|
||||
|
||||
<PushNuGetPackages Condition="'%(PackageToPublish.IsSymbolsPackage)' != 'true' AND @(PackageToPublish->Count()) != 0"
|
||||
Packages="@(PackageToPublish)"
|
||||
TimeoutSeconds="300"
|
||||
Feed="$(PublishMyGetFeedUrl)"
|
||||
ApiKey="$(PublishMyGetFeedKey)" />
|
||||
|
||||
<PushNuGetPackages Condition="'%(PackageToPublish.IsSymbolsPackage)' == 'true' AND @(PackageToPublish->Count()) != 0"
|
||||
Packages="@(PackageToPublish)"
|
||||
TimeoutSeconds="300"
|
||||
Feed="$(PublishMyGetSymbolsFeedUrl)"
|
||||
ApiKey="$(PublishMyGetFeedKey)" />
|
||||
|
||||
<PropertyGroup>
|
||||
<AuthTokenSetting>$(PublishMyGetNpmRegistryUrl.Replace("https:", "")):_authToken</AuthTokenSetting>
|
||||
</PropertyGroup>
|
||||
|
||||
<Message Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Text="Skipping NPM publish because there are no npm packages to publish."
|
||||
Importance="high" />
|
||||
|
||||
<Exec Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Command="npm config set "$(AuthTokenSetting)" $(PublishMyGetFeedKey)"
|
||||
StandardOutputImportance="Normal" />
|
||||
|
||||
<Exec Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Command="npm publish --registry "$(PublishMyGetNpmRegistryUrl)" "%(NpmPackageToPublish.Identity)""
|
||||
ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" ItemName="_NpmExitCodes" />
|
||||
</Exec>
|
||||
|
||||
<Exec Condition=" @(NpmPackageToPublish->Count()) != 0 "
|
||||
Command="npm config delete $(AuthTokenSetting)"
|
||||
StandardOutputImportance="Normal" />
|
||||
|
||||
<Error Text="Publishing npm modules failed" Condition=" @(NpmPackageToPublish->Count()) != 0 AND %(_NpmExitCodes.Identity) != 0" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishToAzureFeed"
|
||||
DependsOnTargets="GetFilesToPublish"
|
||||
Condition="'$(PublishToAzureFeed)' == 'true'">
|
||||
|
||||
<RepoTasks.PublishToAzureBlob
|
||||
AccountName="$(AzureAccountName)"
|
||||
SharedAccessToken="$(AzureSharedAccessToken)"
|
||||
ContainerName="$(AzureContainerName)"
|
||||
Files="@(FilesToPublish)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateBuildAssetManifest"
|
||||
DependsOnTargets="GetFilesToPublish;ResolveRepositoryBranch;ResolveCommitHash">
|
||||
|
||||
<GenerateBuildManifest
|
||||
Artifacts="@(PackageToPublish);@(FilesToPublish)"
|
||||
OutputPath="$(ManifestsPath)aspnetcore-$(SharedFxRid)-$(PackageVersion).xml"
|
||||
BuildId="$(PackageVersion)"
|
||||
BuildData="Location=https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json"
|
||||
RepoUri="$(RepositoryUrl)"
|
||||
RepoBranch="$(RepositoryBranch)"
|
||||
RepoCommit="$(RepositoryCommit)" />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="PushMetadataToBuildAssetRegistry" AssemblyFile="$(PkgMicrosoft_DotNet_Maestro_Tasks)\tools\netcoreapp2.1\Microsoft.DotNet.Maestro.Tasks.dll"/>
|
||||
|
||||
<Target Name="PublishToBuildAssetRegistry"
|
||||
DependsOnTargets="GenerateBuildAssetManifest"
|
||||
Condition="'$(PublishToBuildAssetRegistry)' == 'true'">
|
||||
|
||||
<Error Text="Missing required property: MaestroApiEndpoint" Condition=" '$(MaestroApiEndpoint)' == '' "/>
|
||||
<Error Text="Missing required property: BuildAssetRegistryToken" Condition=" '$(BuildAssetRegistryToken)' == '' "/>
|
||||
|
||||
<PushMetadataToBuildAssetRegistry
|
||||
ManifestsPath="$(ManifestsPath)"
|
||||
BuildAssetRegistryToken="$(BuildAssetRegistryToken)"
|
||||
MaestroApiEndpoint="$(MaestroApiEndpoint)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.
|
||||
|
||||
#if BUILD_AZ_TASKS
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
|
@ -142,3 +143,4 @@ namespace RepoTasks
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,13 +5,14 @@
|
|||
<TargetFramework Condition="'$(MSBuildRuntimeType)' == 'Core' ">netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework Condition="'$(MSBuildRuntimeType)' != 'Core' ">net461</TargetFramework>
|
||||
<DefineConstants Condition="'$(BuildWindowsInstallers)' == 'true'">$(DefineConstants);BUILD_MSI_TASKS</DefineConstants>
|
||||
<DefineConstants Condition="'$(PublishToAzureFeed)' == 'true'">$(DefineConstants);BUILD_AZ_TASKS</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Remove="Internal.AspNetCore.Sdk" />
|
||||
<PackageReference Include="NuGet.Build.Tasks" Version="4.9.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
|
||||
<PackageReference Include="WindowsAzure.Storage" Version="8.7.0" />
|
||||
<PackageReference Include="WindowsAzure.Storage" Version="8.7.0" Condition="'$(PublishToAzureFeed)' == 'true'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(BuildWindowsInstallers)' == 'true'">
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
<UsingTask TaskName="RepoTasks.JoinRepoItems" AssemblyFile="$(_RepoTaskAssembly)" />
|
||||
<UsingTask TaskName="RepoTasks.OrderBy" AssemblyFile="$(_RepoTaskAssembly)" />
|
||||
<UsingTask TaskName="RepoTasks.GenerateSharedFrameworkMetadataFiles" AssemblyFile="$(_RepoTaskAssembly)" />
|
||||
<UsingTask TaskName="RepoTasks.PublishToAzureBlob" AssemblyFile="$(_RepoTaskAssembly)" />
|
||||
<UsingTask TaskName="RepoTasks.PublishToAzureBlob" AssemblyFile="$(_RepoTaskAssembly)" Condition="'$(PublishToAzureFeed)' == 'true'" />
|
||||
<UsingTask TaskName="RepoTasks.RemoveSharedFrameworkDependencies" AssemblyFile="$(_RepoTaskAssembly)" />
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -37,227 +37,231 @@
|
|||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.AspNetCore.Analyzer.Testing" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.AspNetCore.Analyzer.Testing" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.ActivatorUtilities.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.ActivatorUtilities.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.SqlServer" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.SqlServer" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.CommandLineUtils.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.CommandLineUtils.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.KeyPerFile" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.KeyPerFile" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Specification.Tests" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Specification.Tests" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.DiagnosticAdapter" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.DiagnosticAdapter" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.HashCodeCombiner.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.HashCodeCombiner.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Http" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Http" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Localization.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Localization.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Localization" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Localization" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.AzureAppServices" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.AzureAppServices" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Testing" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging.Testing" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Logging" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Logging" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.ObjectPool" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.ObjectPool" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Options" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Options" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.ParameterDefaultValue.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.ParameterDefaultValue.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.TypeNameHelper.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.TypeNameHelper.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.ValueStopWatch.Sources" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.ValueStopWatch.Sources" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Extensions.WebEncoders" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.Extensions.WebEncoders" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.JSInterop" Version="3.0.0-preview.19059.5">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
|
|
@ -355,11 +359,11 @@
|
|||
</Dependency>
|
||||
</ProductDependencies>
|
||||
<ToolsetDependencies>
|
||||
<Dependency Name="Internal.AspNetCore.Analyzers" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Internal.AspNetCore.Analyzers" Version="3.0.0-preview.19065.2">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.AspNetCore.Testing" Version="3.0.0-preview.19059.4">
|
||||
<Dependency Name="Microsoft.AspNetCore.Testing" Version="3.0.0-preview.19065.2">
|
||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||
<Sha>000000</Sha>
|
||||
</Dependency>
|
||||
|
|
|
|||
|
|
@ -35,64 +35,65 @@
|
|||
<SystemThreadingChannelsPackageVersion>4.6.0-preview.18619.1</SystemThreadingChannelsPackageVersion>
|
||||
|
||||
<!-- Packages from aspnet/Extensions -->
|
||||
<InternalAspNetCoreAnalyzersPackageVersion>3.0.0-preview.19059.4</InternalAspNetCoreAnalyzersPackageVersion>
|
||||
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-preview.19059.4</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview.19059.4</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>
|
||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsCachingSqlServerPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsCachingSqlServerPackageVersion>
|
||||
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationIniPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionSpecificationTestsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsDependencyInjectionSpecificationTestsPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLocalizationAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLocalizationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLocalizationPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLocalizationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||
<MicrosoftExtensionsObjectPoolPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsObjectPoolPackageVersion>
|
||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-preview.19059.4</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<InternalAspNetCoreAnalyzersPackageVersion>3.0.0-preview.19059.5</InternalAspNetCoreAnalyzersPackageVersion>
|
||||
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-preview.19059.5</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview.19059.5</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>
|
||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||
<MicrosoftExtensionsCachingSqlServerPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsCachingSqlServerPackageVersion>
|
||||
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationIniPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionSpecificationTestsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsDependencyInjectionSpecificationTestsPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsHostingPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsHostingPackageVersion>
|
||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||
<MicrosoftExtensionsHttpPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsHttpPackageVersion>
|
||||
<MicrosoftExtensionsLocalizationAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLocalizationAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLocalizationPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLocalizationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||
<MicrosoftExtensionsObjectPoolPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsObjectPoolPackageVersion>
|
||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
|
||||
<MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
||||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-preview.19059.5</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||
<MicrosoftJSInteropPackageVersion>3.0.0-preview.19059.5</MicrosoftJSInteropPackageVersion>
|
||||
|
||||
<!-- Packages from aspnet/EntityFrameworkCore -->
|
||||
<DotNetEfPackageVersion>3.0.0-preview.18604.3</DotNetEfPackageVersion>
|
||||
|
|
@ -105,7 +106,7 @@
|
|||
<MicrosoftEntityFrameworkCorePackageVersion>3.0.0-preview.18604.3</MicrosoftEntityFrameworkCorePackageVersion>
|
||||
|
||||
<!-- Packages from aspnet/AspNetCore-Tooling -->
|
||||
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview-19057-06</MicrosoftNETSdkRazorPackageVersion>
|
||||
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview-19064-09</MicrosoftNETSdkRazorPackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Build tool dependencies">
|
||||
|
|
|
|||
|
|
@ -73,6 +73,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.TestHo
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authorization", "..\Security\Authorization\Core\src\Microsoft.AspNetCore.Authorization.csproj", "{C57DFBC2-A887-44B4-A149-7ABFA6D98F7E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.OpenIdConnect", "..\Security\Authentication\OpenIdConnect\src\Microsoft.AspNetCore.Authentication.OpenIdConnect.csproj", "{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.OAuth", "..\Security\Authentication\OAuth\src\Microsoft.AspNetCore.Authentication.OAuth.csproj", "{406DF28A-0B58-408E-96B0-2D373EE36352}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication", "..\Security\Authentication\Core\src\Microsoft.AspNetCore.Authentication.csproj", "{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -383,6 +389,42 @@ Global
|
|||
{C57DFBC2-A887-44B4-A149-7ABFA6D98F7E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C57DFBC2-A887-44B4-A149-7ABFA6D98F7E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C57DFBC2-A887-44B4-A149-7ABFA6D98F7E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Release|x64.Build.0 = Release|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -418,6 +460,9 @@ Global
|
|||
{38027842-48A7-4A64-A44F-004BAF0AB450} = {84622717-F98A-4DE2-806E-1EF89C45C0EB}
|
||||
{C520D48E-87A0-463D-B4CF-3E6B68F8F4D0} = {84622717-F98A-4DE2-806E-1EF89C45C0EB}
|
||||
{C57DFBC2-A887-44B4-A149-7ABFA6D98F7E} = {84622717-F98A-4DE2-806E-1EF89C45C0EB}
|
||||
{F44054A2-DAC9-467F-B899-F35F9DCDAE9C} = {84622717-F98A-4DE2-806E-1EF89C45C0EB}
|
||||
{406DF28A-0B58-408E-96B0-2D373EE36352} = {84622717-F98A-4DE2-806E-1EF89C45C0EB}
|
||||
{A5E7BA46-B76B-467A-88FA-38E04D0A42FC} = {84622717-F98A-4DE2-806E-1EF89C45C0EB}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {81AADD49-473B-43ED-8A08-F6B7A058AA39}
|
||||
|
|
|
|||
|
|
@ -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 Microsoft.AspNetCore.Authorization;
|
||||
|
||||
using System.Net;
|
||||
|
|
@ -11,7 +11,9 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -158,5 +160,60 @@ namespace Microsoft.AspNetCore.Authentication.AzureAD.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(expectedStatusCode, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ADB2C_EndToEnd_PasswordReset()
|
||||
{
|
||||
var client = Factory.WithWebHostBuilder(builder => builder.ConfigureTestServices(
|
||||
services =>
|
||||
{
|
||||
services
|
||||
.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
|
||||
.AddAzureADB2C(o =>
|
||||
{
|
||||
o.Instance = "https://login.microsoftonline.com/tfp/";
|
||||
o.ClientId = "ClientId";
|
||||
o.CallbackPath = "/signin-oidc";
|
||||
o.Domain = "test.onmicrosoft.com";
|
||||
o.SignUpSignInPolicyId = "B2C_1_SiUpIn";
|
||||
o.ResetPasswordPolicyId = "B2C_1_SSPR";
|
||||
o.EditProfilePolicyId = "B2C_1_SiPe";
|
||||
});
|
||||
|
||||
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, o =>
|
||||
{
|
||||
o.Configuration = new OpenIdConnectConfiguration()
|
||||
{
|
||||
Issuer = "https://www.example.com",
|
||||
TokenEndpoint = "https://www.example.com/token",
|
||||
AuthorizationEndpoint = "https://www.example.com/authorize",
|
||||
EndSessionEndpoint = "https://www.example.com/logout"
|
||||
};
|
||||
// CookieContainer doesn't allow cookies from other paths
|
||||
o.CorrelationCookie.Path = "/";
|
||||
o.NonceCookie.Path = "/";
|
||||
});
|
||||
|
||||
services.AddMvc(o => o.Filters.Add(
|
||||
new AuthorizeFilter(new AuthorizationPolicyBuilder(new[] { AzureADB2CDefaults.AuthenticationScheme })
|
||||
.RequireAuthenticatedUser().Build())));
|
||||
})).CreateClient(new WebApplicationFactoryClientOptions() { AllowAutoRedirect = false });
|
||||
|
||||
var response = await client.GetAsync("/api/get");
|
||||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
|
||||
var location = response.Headers.Location;
|
||||
Assert.StartsWith("https://www.example.com/authorize", location.AbsoluteUri);
|
||||
var queryString = location.Query;
|
||||
var query = QueryHelpers.ParseQuery(queryString);
|
||||
var state = query["state"];
|
||||
Assert.False(StringValues.IsNullOrEmpty(state));
|
||||
|
||||
// Mock Authorization response
|
||||
response = await client.GetAsync($"/signin-oidc?error=access_denied&error_description=AADB2C90118&state={state}");
|
||||
|
||||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
Assert.Equal("/AzureADB2C/Account/ResetPassword/AzureADB2C", response.Headers.Location.OriginalString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
|
|
@ -9,16 +9,8 @@
|
|||
<Reference Include="Microsoft.AspNetCore.Authentication.AzureADB2C.UI" />
|
||||
<Reference Include="Microsoft.AspNetCore.Authorization" />
|
||||
<Reference Include="Microsoft.AspNetCore.DataProtection.Extensions" />
|
||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||
<Reference Include="Microsoft.AspNetCore" />
|
||||
<Reference Include="Microsoft.AspNetCore.Mvc" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.IISIntegration" />
|
||||
<Reference Include="Microsoft.AspNetCore.Server.Kestrel" />
|
||||
<Reference Include="Microsoft.Extensions.Configuration.CommandLine" />
|
||||
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||
<Reference Include="Microsoft.Extensions.Configuration.UserSecrets" />
|
||||
<Reference Include="Microsoft.Extensions.Logging.Configuration" />
|
||||
<Reference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<Reference Include="Microsoft.Extensions.Logging.Debug" />
|
||||
<Reference Include="Microsoft.NET.Sdk.Razor" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -23,55 +23,8 @@ namespace AzureAD.WebSite
|
|||
|
||||
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.UseKestrel((builderContext, options) =>
|
||||
{
|
||||
options.Configure(builderContext.Configuration.GetSection("Kestrel"));
|
||||
})
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
var env = hostingContext.HostingEnvironment;
|
||||
|
||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
|
||||
if (appAssembly != null)
|
||||
{
|
||||
config.AddUserSecrets(appAssembly, optional: true);
|
||||
}
|
||||
}
|
||||
|
||||
config.AddEnvironmentVariables();
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
config.AddCommandLine(args);
|
||||
}
|
||||
})
|
||||
.ConfigureLogging((hostingContext, logging) =>
|
||||
{
|
||||
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||
logging.AddConsole();
|
||||
logging.AddDebug();
|
||||
})
|
||||
.UseIISIntegration()
|
||||
.UseDefaultServiceProvider((context, options) =>
|
||||
{
|
||||
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
|
||||
});
|
||||
|
||||
if (args != null)
|
||||
{
|
||||
builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
|
||||
}
|
||||
|
||||
builder.UseStartup<Startup>();
|
||||
|
||||
return builder;
|
||||
return WebHost.CreateDefaultBuilder()
|
||||
.UseStartup<Startup>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,3 +25,31 @@ indent_size = 2
|
|||
|
||||
[*.{xml,csproj,config,*proj,targets,props}]
|
||||
indent_size = 2
|
||||
|
||||
# Dotnet code style settings:
|
||||
[*.cs]
|
||||
# Sort using and Import directives with System.* appearing first
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
||||
# Don't use this. qualifier
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
|
||||
# use int x = .. over Int32
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
|
||||
# use int.MaxValue over Int32.MaxValue
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
# Require var all the time.
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
|
||||
# Newline settings
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
<SignedPackageFile Include="Microsoft.AspNetCore.Components.Browser.JS.dll" Certificate="$(AssemblySigningCertName)" />
|
||||
<SignedPackageFile Include="Microsoft.AspNetCore.Blazor.Build.exe" Certificate="$(AssemblySigningCertName)" />
|
||||
|
||||
<!-- 1st party assembly we redistribute (part of the CLI tool) -->
|
||||
<SignedPackageFile Include="Microsoft.JSInterop.dll" Certificate="$(AssemblySigningCertName)" />
|
||||
|
||||
<!-- 3rd party assemblies we redistribute. -->
|
||||
<SignedPackageFile Include="AngleSharp.dll" Certificate="$(AssemblySigning3rdPartyCertName)" />
|
||||
<SignedPackageFile Include="Mono.Cecil.dll" Certificate="$(AssemblySigning3rdPartyCertName)" />
|
||||
|
|
@ -37,7 +40,6 @@
|
|||
<ExcludePackageFileFromSigning Include="Microsoft.Extensions.FileProviders.Physical.dll" />
|
||||
<ExcludePackageFileFromSigning Include="Microsoft.Extensions.FileSystemGlobbing.dll" />
|
||||
<ExcludePackageFileFromSigning Include="Microsoft.Extensions.Primitives.dll" />
|
||||
<ExcludePackageFileFromSigning Include="Microsoft.JSInterop.dll" />
|
||||
<ExcludePackageFileFromSigning Include="System.CodeDom.dll" />
|
||||
<ExcludePackageFileFromSigning Include="System.Runtime.CompilerServices.Unsafe.dll" />
|
||||
<ExcludePackageFileFromSigning Include="System.Text.Encoding.CodePages.dll" />
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mono.WebAssembly.Interop" Version="$(JSInteropPackageVersion)" />
|
||||
<PackageReference Include="Mono.WebAssembly.Interop" Version="$(MonoWebAssemblyInteropPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Blazor.Rendering
|
|||
/// Provides mechanisms for rendering <see cref="IComponent"/> instances in a
|
||||
/// web browser, dispatching events to them, and refreshing the UI as required.
|
||||
/// </summary>
|
||||
public class WebAssemblyRenderer : Renderer, IDisposable
|
||||
public class WebAssemblyRenderer : Renderer
|
||||
{
|
||||
private readonly int _webAssemblyRendererId;
|
||||
|
||||
|
|
@ -71,11 +71,10 @@ namespace Microsoft.AspNetCore.Blazor.Rendering
|
|||
RenderRootComponent(componentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the instance.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
RendererRegistry.Current.TryRemove(_webAssemblyRendererId);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>3.0.0-alpha1-10605</MicrosoftAspNetCoreHtmlAbstractionsPackageVersion>
|
||||
<MicrosoftAspNetCoreRazorDesignPackageVersion>3.0.0-alpha1-10605</MicrosoftAspNetCoreRazorDesignPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-alpha1-10605</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview-19057-06</MicrosoftNETSdkRazorPackageVersion>
|
||||
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview-19064-09</MicrosoftNETSdkRazorPackageVersion>
|
||||
<MonoCecilPackageVersion>0.10.1</MonoCecilPackageVersion>
|
||||
<SignalRPackageVersion>3.0.0-alpha1-10605</SignalRPackageVersion>
|
||||
<TemplateBlazorPackageVersion>0.8.0-preview-19064-0339</TemplateBlazorPackageVersion>
|
||||
|
|
@ -20,7 +20,8 @@
|
|||
<TemplateRazorDesignPackageVersion>2.1.2</TemplateRazorDesignPackageVersion>
|
||||
<MicrosoftAspNetCoreBlazorMonoPackageVersion>0.8.0-preview1-20181126.1</MicrosoftAspNetCoreBlazorMonoPackageVersion>
|
||||
|
||||
<!-- When updating this, ensure you also update Browser.JS/package.json to reference the corresponding version of @dotnet/jsinterop -->
|
||||
<JSInteropPackageVersion>0.8.0-preview1-20181126.4</JSInteropPackageVersion>
|
||||
<MicrosoftJSInteropPackageVersion>3.0.0-preview.19059.5</MicrosoftJSInteropPackageVersion>
|
||||
|
||||
<MonoWebAssemblyInteropPackageVersion>0.8.0-preview1-20181126.4</MonoWebAssemblyInteropPackageVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Description>Support for rendering ASP.NET Core components in browsers.</Description>
|
||||
<Description>Support for rendering ASP.NET Core components for browsers.</Description>
|
||||
<IsProductPackage>true</IsProductPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,3 +2,5 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Blazor, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Server, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Components.Server.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
<GenerateRazorAssemblyInfo>false</GenerateRazorAssemblyInfo>
|
||||
<GenerateRazorHostingAssemblyInfo>false</GenerateRazorHostingAssemblyInfo>
|
||||
<GenerateProvideApplicationPartFactoryAttribute>false</GenerateProvideApplicationPartFactoryAttribute>
|
||||
<_RazorComponentInclude>**\*.cshtml</_RazorComponentInclude>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -24,8 +25,4 @@
|
|||
</RazorExtension>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<RazorComponent Include="@(Content->WithMetadataValue('Extension', '.cshtml'))" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
{
|
||||
internal class CircuitHost : IDisposable
|
||||
{
|
||||
private static AsyncLocal<CircuitHost> _current = new AsyncLocal<CircuitHost>();
|
||||
private static readonly AsyncLocal<CircuitHost> _current = new AsyncLocal<CircuitHost>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current <see cref="Circuit"/>, if any.
|
||||
|
|
@ -24,23 +24,18 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
public static CircuitHost Current => _current.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current <see cref="Circuit"/>.
|
||||
/// Sets the current <see cref="Circuits.Circuit"/>.
|
||||
/// </summary>
|
||||
/// <param name="circuitHost">The <see cref="Circuit"/>.</param>
|
||||
/// <param name="circuitHost">The <see cref="Circuits.Circuit"/>.</param>
|
||||
/// <remarks>
|
||||
/// Calling <see cref="SetCurrentCircuitHost(CircuitHost)"/> will store the circuit
|
||||
/// and other related values such as the <see cref="IJSRuntime"/> and <see cref="Renderer"/>
|
||||
/// in the local execution context. Application code should not need to call this method,
|
||||
/// it is primarily used by the Server-Side Blazor infrastructure.
|
||||
/// it is primarily used by the Server-Side Components infrastructure.
|
||||
/// </remarks>
|
||||
public static void SetCurrentCircuitHost(CircuitHost circuitHost)
|
||||
{
|
||||
if (circuitHost == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(circuitHost));
|
||||
}
|
||||
|
||||
_current.Value = circuitHost;
|
||||
_current.Value = circuitHost ?? throw new ArgumentNullException(nameof(circuitHost));
|
||||
|
||||
Microsoft.JSInterop.JSRuntime.SetCurrentJSRuntime(circuitHost.JSRuntime);
|
||||
RendererRegistry.SetCurrentRendererRegistry(circuitHost.RendererRegistry);
|
||||
|
|
@ -134,6 +129,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
public void Dispose()
|
||||
{
|
||||
Scope.Dispose();
|
||||
Renderer.Dispose();
|
||||
}
|
||||
|
||||
private void AssertInitialized()
|
||||
|
|
|
|||
|
|
@ -120,11 +120,10 @@ namespace Microsoft.AspNetCore.Components.Browser.Rendering
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the instance.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
/// <inheritdoc />
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(true);
|
||||
_rendererRegistry.TryRemove(_id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.JSInterop" Version="$(JSInteropPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.JSInterop" Version="$(MicrosoftJSInteropPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -12,19 +12,17 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
/// Provides mechanisms for rendering hierarchies of <see cref="IComponent"/> instances,
|
||||
/// dispatching events to them, and notifying when the user interface is being updated.
|
||||
/// </summary>
|
||||
public abstract class Renderer
|
||||
public abstract class Renderer : IDisposable
|
||||
{
|
||||
private readonly ComponentFactory _componentFactory;
|
||||
private int _nextComponentId = 0; // TODO: change to 'long' when Mono .NET->JS interop supports it
|
||||
private readonly Dictionary<int, ComponentState> _componentStateById
|
||||
= new Dictionary<int, ComponentState>();
|
||||
|
||||
private readonly Dictionary<int, ComponentState> _componentStateById = new Dictionary<int, ComponentState>();
|
||||
private readonly RenderBatchBuilder _batchBuilder = new RenderBatchBuilder();
|
||||
private bool _isBatchInProgress;
|
||||
|
||||
private int _lastEventHandlerId = 0;
|
||||
private readonly Dictionary<int, EventHandlerInvoker> _eventBindings = new Dictionary<int, EventHandlerInvoker>();
|
||||
|
||||
private int _nextComponentId = 0; // TODO: change to 'long' when Mono .NET->JS interop supports it
|
||||
private bool _isBatchInProgress;
|
||||
private int _lastEventHandlerId = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of <see cref="Renderer"/>.
|
||||
/// </summary>
|
||||
|
|
@ -175,7 +173,7 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
|
||||
if (frame.AttributeValue is MulticastDelegate @delegate)
|
||||
{
|
||||
_eventBindings.Add(id, new EventHandlerInvoker(@delegate));
|
||||
_eventBindings.Add(id, new EventHandlerInvoker(@delegate));
|
||||
}
|
||||
|
||||
frame = frame.WithAttributeEventHandlerId(id);
|
||||
|
|
@ -295,5 +293,44 @@ namespace Microsoft.AspNetCore.Components.Rendering
|
|||
RemoveEventHandlerIds(eventHandlerIdsClone, Task.CompletedTask));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources currently used by this <see cref="Renderer"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="disposing"><see langword="true"/> if this method is being invoked by <see cref="IDisposable.Dispose"/>, otherwise <see langword="false"/>.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
List<Exception> exceptions = null;
|
||||
|
||||
foreach (var componentState in _componentStateById.Values)
|
||||
{
|
||||
if (componentState.Component is IDisposable disposable)
|
||||
{
|
||||
try
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
// Capture exceptions thrown by individual components and rethrow as an aggregate.
|
||||
exceptions = exceptions ?? new List<Exception>();
|
||||
exceptions.Add(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exceptions != null)
|
||||
{
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resources currently used by this <see cref="Renderer"/> instance.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// 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.Threading;
|
||||
using Microsoft.AspNetCore.Components.Browser;
|
||||
using Microsoft.AspNetCore.Components.Browser.Rendering;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.JSInterop;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Server.Circuits
|
||||
{
|
||||
public class CircuitHostTest
|
||||
{
|
||||
[Fact]
|
||||
public void Dispose_DisposesResources()
|
||||
{
|
||||
// Arrange
|
||||
var serviceScope = new Mock<IServiceScope>();
|
||||
var clientProxy = Mock.Of<IClientProxy>();
|
||||
var renderRegistry = new RendererRegistry();
|
||||
var jsRuntime = Mock.Of<IJSRuntime>();
|
||||
var syncContext = new CircuitSynchronizationContext();
|
||||
|
||||
var remoteRenderer = new TestRemoteRenderer(
|
||||
Mock.Of<IServiceProvider>(),
|
||||
renderRegistry,
|
||||
jsRuntime,
|
||||
clientProxy,
|
||||
syncContext);
|
||||
|
||||
var circuitHost = new CircuitHost(serviceScope.Object, clientProxy, renderRegistry, remoteRenderer, configure: _ => { }, jsRuntime: jsRuntime, synchronizationContext: syncContext);
|
||||
|
||||
// Act
|
||||
circuitHost.Dispose();
|
||||
|
||||
// Assert
|
||||
serviceScope.Verify(s => s.Dispose(), Times.Once());
|
||||
Assert.True(remoteRenderer.Disposed);
|
||||
}
|
||||
|
||||
private class TestRemoteRenderer : RemoteRenderer
|
||||
{
|
||||
public TestRemoteRenderer(IServiceProvider serviceProvider, RendererRegistry rendererRegistry, IJSRuntime jsRuntime, IClientProxy client, SynchronizationContext syncContext)
|
||||
: base(serviceProvider, rendererRegistry, jsRuntime, client, syncContext)
|
||||
{
|
||||
}
|
||||
|
||||
public bool Disposed { get; set; }
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="Moq" Version="4.10.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Rendering;
|
||||
using Microsoft.AspNetCore.Components.RenderTree;
|
||||
using Microsoft.AspNetCore.Components.Test.Helpers;
|
||||
|
|
@ -1139,6 +1138,78 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
Assert.Equal(2, numEventsFired);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisposingRenderer_DisposesTopLevelComponents()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new TestRenderer();
|
||||
var component = new DisposableComponent();
|
||||
renderer.AssignRootComponentId(component);
|
||||
|
||||
// Act
|
||||
renderer.Dispose();
|
||||
|
||||
// Assert
|
||||
Assert.True(component.Disposed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisposingRenderer_DisposesNestedComponents()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new TestRenderer();
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<DisposableComponent>(1);
|
||||
builder.CloseComponent();
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
var batch = renderer.Batches.Single();
|
||||
var componentFrame = batch.ReferenceFrames
|
||||
.Single(frame => frame.FrameType == RenderTreeFrameType.Component);
|
||||
var nestedComponent = Assert.IsType<DisposableComponent>(componentFrame.Component);
|
||||
|
||||
// Act
|
||||
renderer.Dispose();
|
||||
|
||||
// Assert
|
||||
Assert.True(component.Disposed);
|
||||
Assert.True(nestedComponent.Disposed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DisposingRenderer_CapturesExceptionsFromAllRegisteredComponents()
|
||||
{
|
||||
// Arrange
|
||||
var renderer = new TestRenderer();
|
||||
var exception1 = new Exception();
|
||||
var exception2 = new Exception();
|
||||
var component = new TestComponent(builder =>
|
||||
{
|
||||
builder.AddContent(0, "Hello");
|
||||
builder.OpenComponent<DisposableComponent>(1);
|
||||
builder.AddAttribute(1, nameof(DisposableComponent.DisposeAction), (Action)(() => throw exception1));
|
||||
builder.CloseComponent();
|
||||
|
||||
builder.OpenComponent<DisposableComponent>(2);
|
||||
builder.AddAttribute(1, nameof(DisposableComponent.DisposeAction), (Action)(() => throw exception2));
|
||||
builder.CloseComponent();
|
||||
});
|
||||
var componentId = renderer.AssignRootComponentId(component);
|
||||
component.TriggerRender();
|
||||
|
||||
// Act &A Assert
|
||||
var aggregate = Assert.Throws<AggregateException>(renderer.Dispose);
|
||||
|
||||
// All components must be disposed even if some throw as part of being diposed.
|
||||
Assert.True(component.Disposed);
|
||||
Assert.Equal(2, aggregate.InnerExceptions.Count);
|
||||
Assert.Contains(exception1, aggregate.InnerExceptions);
|
||||
Assert.Contains(exception2, aggregate.InnerExceptions);
|
||||
}
|
||||
|
||||
private class NoOpRenderer : Renderer
|
||||
{
|
||||
public NoOpRenderer() : base(new TestServiceProvider())
|
||||
|
|
@ -1152,7 +1223,7 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
=> Task.CompletedTask;
|
||||
}
|
||||
|
||||
private class TestComponent : IComponent
|
||||
private class TestComponent : IComponent, IDisposable
|
||||
{
|
||||
private RenderHandle _renderHandle;
|
||||
private RenderFragment _renderFragment;
|
||||
|
|
@ -1172,6 +1243,10 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
|
||||
public void TriggerRender()
|
||||
=> _renderHandle.Render(_renderFragment);
|
||||
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
void IDisposable.Dispose() => Disposed = true;
|
||||
}
|
||||
|
||||
private class MessageComponent : AutoRenderComponent
|
||||
|
|
@ -1398,6 +1473,24 @@ namespace Microsoft.AspNetCore.Components.Test
|
|||
}
|
||||
}
|
||||
|
||||
private class DisposableComponent : AutoRenderComponent, IDisposable
|
||||
{
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
[Parameter]
|
||||
public Action DisposeAction { get; private set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Disposed = true;
|
||||
DisposeAction?.Invoke();
|
||||
}
|
||||
|
||||
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class TestAsyncRenderer : TestRenderer
|
||||
{
|
||||
public Task NextUpdateDisplayReturnTask { get; set; }
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
<Dependency Include="Microsoft.AspNetCore.Authentication" Version="$(MicrosoftAspNetCoreAuthenticationPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.Authorization.Policy" Version="$(MicrosoftAspNetCoreAuthorizationPolicyPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.Authorization" Version="$(MicrosoftAspNetCoreAuthorizationPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.Components" Version="$(MicrosoftAspNetCoreComponentsPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.Components.Browser" Version="$(MicrosoftAspNetCoreComponentsBrowserPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.Connections.Abstractions" Version="$(MicrosoftAspNetCoreConnectionsAbstractionsPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.CookiePolicy" Version="$(MicrosoftAspNetCoreCookiePolicyPackageVersion)" />
|
||||
<Dependency Include="Microsoft.AspNetCore.Cors" Version="$(MicrosoftAspNetCoreCorsPackageVersion)" />
|
||||
|
|
@ -127,6 +129,7 @@
|
|||
<Dependency Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPackageVersion)" />
|
||||
<Dependency Include="Microsoft.Extensions.Primitives" Version="$(MicrosoftExtensionsPrimitivesPackageVersion)" />
|
||||
<Dependency Include="Microsoft.Extensions.WebEncoders" Version="$(MicrosoftExtensionsWebEncodersPackageVersion)" />
|
||||
<Dependency Include="Microsoft.JSInterop" Version="$(MicrosoftJSInteropPackageVersion)" />
|
||||
<Dependency Include="Microsoft.Net.Http.Headers" Version="$(MicrosoftNetHttpHeadersPackageVersion)" />
|
||||
<Dependency Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
|
||||
<Dependency Include="System.IO.Pipelines" Version="$(SystemIOPipelinesPackageVersion)" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
// 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.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.TestHost
|
||||
{
|
||||
internal class AsyncStreamWrapper : Stream
|
||||
{
|
||||
private Stream _inner;
|
||||
private Func<bool> _allowSynchronousIO;
|
||||
|
||||
internal AsyncStreamWrapper(Stream inner, Func<bool> allowSynchronousIO)
|
||||
{
|
||||
_inner = inner;
|
||||
_allowSynchronousIO = allowSynchronousIO;
|
||||
}
|
||||
|
||||
public override bool CanRead => _inner.CanRead;
|
||||
|
||||
public override bool CanSeek => _inner.CanSeek;
|
||||
|
||||
public override bool CanWrite => _inner.CanWrite;
|
||||
|
||||
public override long Length => _inner.Length;
|
||||
|
||||
public override long Position { get => _inner.Position; set => _inner.Position = value; }
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
// Not blocking Flush because things like StreamWriter.Dispose() always call it.
|
||||
_inner.Flush();
|
||||
}
|
||||
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return _inner.FlushAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_allowSynchronousIO())
|
||||
{
|
||||
throw new InvalidOperationException("Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true.");
|
||||
}
|
||||
|
||||
return _inner.Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return _inner.ReadAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
|
||||
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _inner.ReadAsync(buffer, cancellationToken);
|
||||
}
|
||||
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
return _inner.BeginRead(buffer, offset, count, callback, state);
|
||||
}
|
||||
|
||||
public override int EndRead(IAsyncResult asyncResult)
|
||||
{
|
||||
return _inner.EndRead(asyncResult);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
return _inner.Seek(offset, origin);
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
_inner.SetLength(value);
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_allowSynchronousIO())
|
||||
{
|
||||
throw new InvalidOperationException("Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true.");
|
||||
}
|
||||
|
||||
_inner.Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
return _inner.BeginWrite(buffer, offset, count, callback, state);
|
||||
}
|
||||
|
||||
public override void EndWrite(IAsyncResult asyncResult)
|
||||
{
|
||||
_inner.EndWrite(asyncResult);
|
||||
}
|
||||
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return _inner.WriteAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
|
||||
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _inner.WriteAsync(buffer, cancellationToken);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
_inner.Close();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_inner.Dispose();
|
||||
}
|
||||
|
||||
public override ValueTask DisposeAsync()
|
||||
{
|
||||
return _inner.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,8 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
_pathBase = pathBase;
|
||||
}
|
||||
|
||||
internal bool AllowSynchronousIO { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This adapts HttpRequestMessages to ASP.NET Core requests, dispatches them through the pipeline, and returns the
|
||||
/// associated HttpResponseMessage.
|
||||
|
|
@ -59,7 +61,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
var contextBuilder = new HttpContextBuilder(_application);
|
||||
var contextBuilder = new HttpContextBuilder(_application, AllowSynchronousIO);
|
||||
|
||||
Stream responseBody = null;
|
||||
var requestContent = request.Content ?? new StreamContent(Stream.Null);
|
||||
|
|
@ -110,7 +112,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
// This body may have been consumed before, rewind it.
|
||||
body.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
req.Body = body;
|
||||
req.Body = new AsyncStreamWrapper(body, () => contextBuilder.AllowSynchronousIO);
|
||||
|
||||
responseBody = context.Response.Body;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -11,7 +11,7 @@ using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
|
|||
|
||||
namespace Microsoft.AspNetCore.TestHost
|
||||
{
|
||||
internal class HttpContextBuilder
|
||||
internal class HttpContextBuilder : IHttpBodyControlFeature
|
||||
{
|
||||
private readonly IHttpApplication<Context> _application;
|
||||
private readonly HttpContext _httpContext;
|
||||
|
|
@ -23,24 +23,28 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
private bool _pipelineFinished;
|
||||
private Context _testContext;
|
||||
|
||||
internal HttpContextBuilder(IHttpApplication<Context> application)
|
||||
internal HttpContextBuilder(IHttpApplication<Context> application, bool allowSynchronousIO)
|
||||
{
|
||||
_application = application ?? throw new ArgumentNullException(nameof(application));
|
||||
AllowSynchronousIO = allowSynchronousIO;
|
||||
_httpContext = new DefaultHttpContext();
|
||||
|
||||
var request = _httpContext.Request;
|
||||
request.Protocol = "HTTP/1.1";
|
||||
request.Method = HttpMethods.Get;
|
||||
|
||||
_httpContext.Features.Set<IHttpBodyControlFeature>(this);
|
||||
_httpContext.Features.Set<IHttpResponseFeature>(_responseFeature);
|
||||
var requestLifetimeFeature = new HttpRequestLifetimeFeature();
|
||||
requestLifetimeFeature.RequestAborted = _requestAbortedSource.Token;
|
||||
_httpContext.Features.Set<IHttpRequestLifetimeFeature>(requestLifetimeFeature);
|
||||
|
||||
_responseStream = new ResponseStream(ReturnResponseMessageAsync, AbortRequest);
|
||||
_responseStream = new ResponseStream(ReturnResponseMessageAsync, AbortRequest, () => AllowSynchronousIO);
|
||||
_responseFeature.Body = _responseStream;
|
||||
}
|
||||
|
||||
public bool AllowSynchronousIO { get; set; }
|
||||
|
||||
internal void Configure(Action<HttpContext> configureContext)
|
||||
{
|
||||
if (configureContext == null)
|
||||
|
|
@ -136,4 +140,4 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
_responseTcs.TrySetException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,15 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
private Func<Task> _onFirstWriteAsync;
|
||||
private bool _firstWrite;
|
||||
private Action _abortRequest;
|
||||
private Func<bool> _allowSynchronousIO;
|
||||
|
||||
private Pipe _pipe = new Pipe();
|
||||
|
||||
internal ResponseStream(Func<Task> onFirstWriteAsync, Action abortRequest)
|
||||
internal ResponseStream(Func<Task> onFirstWriteAsync, Action abortRequest, Func<bool> allowSynchronousIO)
|
||||
{
|
||||
_onFirstWriteAsync = onFirstWriteAsync ?? throw new ArgumentNullException(nameof(onFirstWriteAsync));
|
||||
_abortRequest = abortRequest ?? throw new ArgumentNullException(nameof(abortRequest));
|
||||
_allowSynchronousIO = allowSynchronousIO ?? throw new ArgumentNullException(nameof(allowSynchronousIO));
|
||||
_firstWrite = true;
|
||||
_writeLock = new SemaphoreSlim(1, 1);
|
||||
}
|
||||
|
|
@ -144,6 +146,11 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
// Write with count 0 will still trigger OnFirstWrite
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_allowSynchronousIO())
|
||||
{
|
||||
throw new InvalidOperationException("Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true.");
|
||||
}
|
||||
|
||||
// The Pipe Write method requires calling FlushAsync to notify the reader. Call WriteAsync instead.
|
||||
WriteAsync(buffer, offset, count).GetAwaiter().GetResult();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
|
||||
public IFeatureCollection Features { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that controls whether synchronous IO is allowed for the <see cref="HttpContext.Request"/> and <see cref="HttpContext.Response"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Defaults to true.
|
||||
/// </remarks>
|
||||
public bool AllowSynchronousIO { get; set; } = true;
|
||||
|
||||
private IHttpApplication<Context> Application
|
||||
{
|
||||
get => _application ?? throw new InvalidOperationException("The server has not been started or no web application was configured.");
|
||||
|
|
@ -85,7 +93,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
public HttpMessageHandler CreateHandler()
|
||||
{
|
||||
var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress);
|
||||
return new ClientHandler(pathBase, Application);
|
||||
return new ClientHandler(pathBase, Application) { AllowSynchronousIO = AllowSynchronousIO };
|
||||
}
|
||||
|
||||
public HttpClient CreateClient()
|
||||
|
|
@ -96,7 +104,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
public WebSocketClient CreateWebSocketClient()
|
||||
{
|
||||
var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress);
|
||||
return new WebSocketClient(pathBase, Application);
|
||||
return new WebSocketClient(pathBase, Application) { AllowSynchronousIO = AllowSynchronousIO };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -120,7 +128,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
throw new ArgumentNullException(nameof(configureContext));
|
||||
}
|
||||
|
||||
var builder = new HttpContextBuilder(Application);
|
||||
var builder = new HttpContextBuilder(Application, AllowSynchronousIO);
|
||||
builder.Configure(context =>
|
||||
{
|
||||
var request = context.Request;
|
||||
|
|
@ -138,6 +146,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
request.PathBase = pathBase;
|
||||
});
|
||||
builder.Configure(configureContext);
|
||||
// TODO: Wrap the request body if any?
|
||||
return await builder.SendAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,10 +46,12 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
set;
|
||||
}
|
||||
|
||||
internal bool AllowSynchronousIO { get; set; }
|
||||
|
||||
public async Task<WebSocket> ConnectAsync(Uri uri, CancellationToken cancellationToken)
|
||||
{
|
||||
WebSocketFeature webSocketFeature = null;
|
||||
var contextBuilder = new HttpContextBuilder(_application);
|
||||
var contextBuilder = new HttpContextBuilder(_application, AllowSynchronousIO);
|
||||
contextBuilder.Configure(context =>
|
||||
{
|
||||
var request = context.Request;
|
||||
|
|
@ -131,4 +133,4 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,13 +92,12 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
public async Task ResubmitRequestWorks()
|
||||
{
|
||||
int requestCount = 1;
|
||||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(context =>
|
||||
var handler = new ClientHandler(PathString.Empty, new DummyApplication(async context =>
|
||||
{
|
||||
int read = context.Request.Body.Read(new byte[100], 0, 100);
|
||||
int read = await context.Request.Body.ReadAsync(new byte[100], 0, 100);
|
||||
Assert.Equal(11, read);
|
||||
|
||||
context.Response.Headers["TestHeader"] = "TestValue:" + requestCount++;
|
||||
return Task.FromResult(0);
|
||||
}));
|
||||
|
||||
HttpMessageInvoker invoker = new HttpMessageInvoker(handler);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
{
|
||||
c.Response.Headers["TestHeader"] = "TestValue";
|
||||
var bytes = Encoding.UTF8.GetBytes("BodyStarted" + Environment.NewLine);
|
||||
c.Features.Get<IHttpBodyControlFeature>().AllowSynchronousIO = true;
|
||||
c.Response.Body.Write(bytes, 0, bytes.Length);
|
||||
await block.Task;
|
||||
bytes = Encoding.UTF8.GetBytes("BodyFinished");
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
public async Task PutAsyncWorks()
|
||||
{
|
||||
// Arrange
|
||||
RequestDelegate appDelegate = ctx =>
|
||||
ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " PUT Response");
|
||||
RequestDelegate appDelegate = async ctx =>
|
||||
await ctx.Response.WriteAsync(await new StreamReader(ctx.Request.Body).ReadToEndAsync() + " PUT Response");
|
||||
var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate));
|
||||
var server = new TestServer(builder);
|
||||
var client = server.CreateClient();
|
||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
{
|
||||
// Arrange
|
||||
RequestDelegate appDelegate = async ctx =>
|
||||
await ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " POST Response");
|
||||
await ctx.Response.WriteAsync(await new StreamReader(ctx.Request.Body).ReadToEndAsync() + " POST Response");
|
||||
var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate));
|
||||
var server = new TestServer(builder);
|
||||
var client = server.CreateClient();
|
||||
|
|
@ -132,16 +132,15 @@ namespace Microsoft.AspNetCore.TestHost
|
|||
}
|
||||
|
||||
var builder = new WebHostBuilder();
|
||||
RequestDelegate app = (ctx) =>
|
||||
RequestDelegate app = async ctx =>
|
||||
{
|
||||
var disposable = new TestDisposable();
|
||||
ctx.Response.RegisterForDispose(disposable);
|
||||
ctx.Response.Body.Write(data, 0, 1024);
|
||||
await ctx.Response.Body.WriteAsync(data, 0, 1024);
|
||||
|
||||
Assert.False(disposable.IsDisposed);
|
||||
|
||||
ctx.Response.Body.Write(data, 1024, 1024);
|
||||
return Task.FromResult(0);
|
||||
await ctx.Response.Body.WriteAsync(data, 1024, 1024);
|
||||
};
|
||||
|
||||
builder.Configure(appBuilder => appBuilder.Run(app));
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ Microsoft.AspNetCore.Http.HttpResponse</Description>
|
|||
<Reference Include="Microsoft.AspNetCore.Http.Features" />
|
||||
<Reference Include="Microsoft.Extensions.ActivatorUtilities.Sources" PrivateAssets="All" />
|
||||
<Reference Include="System.Text.Encodings.Web" />
|
||||
<Reference Include="System.IO.Pipelines" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Http.Features
|
|||
public interface IRequestBodyPipeFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="PipeWriter"/> representing the request body, if any.
|
||||
/// A <see cref="PipeReader"/> representing the request body, if any.
|
||||
/// </summary>
|
||||
PipeReader RequestBodyPipe { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
namespace System.IO.Pipelines
|
||||
{
|
||||
public sealed class BufferSegment : ReadOnlySequenceSegment<byte>
|
||||
internal sealed class BufferSegment : ReadOnlySequenceSegment<byte>
|
||||
{
|
||||
private IMemoryOwner<byte> _memoryOwner;
|
||||
private BufferSegment _next;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>ASP.NET Core default HTTP feature implementations.</Description>
|
||||
|
|
@ -19,7 +19,6 @@
|
|||
<Reference Include="Microsoft.Extensions.ObjectPool" />
|
||||
<Reference Include="Microsoft.Extensions.Options" />
|
||||
<Reference Include="Microsoft.Net.Http.Headers" />
|
||||
<Reference Include="System.IO.Pipelines" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Http.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
// 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.Buffers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.IO.Pipelines
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a read-only Stream backed by a PipeReader
|
||||
/// </summary>
|
||||
public class ReadOnlyPipeStream : Stream
|
||||
{
|
||||
private readonly PipeReader _pipeReader;
|
||||
private bool _allowSynchronousIO = true;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ReadOnlyPipeStream
|
||||
/// </summary>
|
||||
/// <param name="pipeReader">The PipeReader to read from.</param>
|
||||
public ReadOnlyPipeStream(PipeReader pipeReader) :
|
||||
this(pipeReader, allowSynchronousIO: true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ReadOnlyPipeStream
|
||||
/// </summary>
|
||||
/// <param name="pipeReader">The PipeReader to read from.</param>
|
||||
/// <param name="allowSynchronousIO">Whether synchronous IO is allowed.</param>
|
||||
public ReadOnlyPipeStream(PipeReader pipeReader, bool allowSynchronousIO)
|
||||
{
|
||||
_allowSynchronousIO = allowSynchronousIO;
|
||||
_pipeReader = pipeReader;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanSeek => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanRead => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanWrite => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Position
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int WriteTimeout
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Flush()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_allowSynchronousIO)
|
||||
{
|
||||
ThrowHelper.ThrowInvalidOperationException_SynchronousReadsDisallowed();
|
||||
}
|
||||
return ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
var task = ReadAsync(buffer, offset, count, default, state);
|
||||
if (callback != null)
|
||||
{
|
||||
task.ContinueWith(t => callback.Invoke(t));
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int EndRead(IAsyncResult asyncResult)
|
||||
{
|
||||
return ((Task<int>)asyncResult).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<int>(state);
|
||||
var task = ReadAsync(buffer, offset, count, cancellationToken);
|
||||
task.ContinueWith((task2, state2) =>
|
||||
{
|
||||
var tcs2 = (TaskCompletionSource<int>)state2;
|
||||
if (task2.IsCanceled)
|
||||
{
|
||||
tcs2.SetCanceled();
|
||||
}
|
||||
else if (task2.IsFaulted)
|
||||
{
|
||||
tcs2.SetException(task2.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs2.SetResult(task2.Result);
|
||||
}
|
||||
}, tcs, cancellationToken);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return ReadAsyncInternal(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ValueTask<int> ReadAsync(Memory<byte> destination, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return ReadAsyncInternal(destination, cancellationToken);
|
||||
}
|
||||
|
||||
private async ValueTask<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var result = await _pipeReader.ReadAsync(cancellationToken);
|
||||
var readableBuffer = result.Buffer;
|
||||
var readableBufferLength = readableBuffer.Length;
|
||||
|
||||
var consumed = readableBuffer.End;
|
||||
var actual = 0;
|
||||
try
|
||||
{
|
||||
if (readableBufferLength != 0)
|
||||
{
|
||||
actual = (int)Math.Min(readableBufferLength, buffer.Length);
|
||||
|
||||
var slice = actual == readableBufferLength ? readableBuffer : readableBuffer.Slice(0, actual);
|
||||
consumed = slice.End;
|
||||
slice.CopyTo(buffer.Span);
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
if (result.IsCompleted)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_pipeReader.AdvanceTo(consumed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
|
||||
{
|
||||
if (destination == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(destination));
|
||||
}
|
||||
|
||||
if (bufferSize <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(bufferSize));
|
||||
}
|
||||
|
||||
return CopyToAsyncInternal(destination, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task CopyToAsyncInternal(Stream destination, CancellationToken cancellationToken)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var result = await _pipeReader.ReadAsync(cancellationToken);
|
||||
var readableBuffer = result.Buffer;
|
||||
var readableBufferLength = readableBuffer.Length;
|
||||
|
||||
try
|
||||
{
|
||||
if (readableBufferLength != 0)
|
||||
{
|
||||
foreach (var memory in readableBuffer)
|
||||
{
|
||||
await destination.WriteAsync(memory, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.IsCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_pipeReader.AdvanceTo(readableBuffer.End);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,8 @@ namespace System.IO.Pipelines
|
|||
private readonly MemoryPool<byte> _pool;
|
||||
|
||||
private CancellationTokenSource _internalTokenSource;
|
||||
private bool _isCompleted;
|
||||
private bool _isReaderCompleted;
|
||||
private bool _isWriterCompleted;
|
||||
private ExceptionDispatchInfo _exceptionInfo;
|
||||
|
||||
private BufferSegment _readHead;
|
||||
|
|
@ -182,12 +183,12 @@ namespace System.IO.Pipelines
|
|||
/// <inheritdoc />
|
||||
public override void Complete(Exception exception = null)
|
||||
{
|
||||
if (_isCompleted)
|
||||
if (_isReaderCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isCompleted = true;
|
||||
_isReaderCompleted = true;
|
||||
if (exception != null)
|
||||
{
|
||||
_exceptionInfo = ExceptionDispatchInfo.Capture(exception);
|
||||
|
|
@ -248,6 +249,11 @@ namespace System.IO.Pipelines
|
|||
|
||||
_readTail.End += length;
|
||||
_bufferedBytes += length;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
_isWriterCompleted = true;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
|
@ -275,7 +281,7 @@ namespace System.IO.Pipelines
|
|||
|
||||
private void ThrowIfCompleted()
|
||||
{
|
||||
if (_isCompleted)
|
||||
if (_isReaderCompleted)
|
||||
{
|
||||
ThrowHelper.ThrowInvalidOperationException_NoReadingAllowed();
|
||||
}
|
||||
|
|
@ -357,7 +363,7 @@ namespace System.IO.Pipelines
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool IsCompletedOrThrow()
|
||||
{
|
||||
if (!_isCompleted)
|
||||
if (!_isWriterCompleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace System.IO.Pipelines
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the inner stream that is being read from.
|
||||
/// Gets the inner stream that is being written to.
|
||||
/// </summary>
|
||||
public Stream InnerStream => _writingStream;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,5 +19,17 @@ namespace System.IO.Pipelines
|
|||
public static void ThrowInvalidOperationException_NoDataRead() => throw CreateInvalidOperationException_NoDataRead();
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Exception CreateInvalidOperationException_NoDataRead() => new InvalidOperationException("No data has been read into the StreamPipeReader.");
|
||||
|
||||
public static void ThrowInvalidOperationException_SynchronousReadsDisallowed() => throw CreateInvalidOperationException_SynchronousReadsDisallowed();
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Exception CreateInvalidOperationException_SynchronousReadsDisallowed() => new InvalidOperationException("Synchronous operations are disallowed. Call ReadAsync or set allowSynchronousIO to true instead.");
|
||||
|
||||
public static void ThrowInvalidOperationException_SynchronousWritesDisallowed() => throw CreateInvalidOperationException_SynchronousWritesDisallowed();
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Exception CreateInvalidOperationException_SynchronousWritesDisallowed() => new InvalidOperationException("Synchronous operations are disallowed. Call WriteAsync or set allowSynchronousIO to true instead.");
|
||||
|
||||
public static void ThrowInvalidOperationException_SynchronousFlushesDisallowed() => throw CreateInvalidOperationException_SynchronousFlushesDisallowed();
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Exception CreateInvalidOperationException_SynchronousFlushesDisallowed() => new InvalidOperationException("Synchronous operations are disallowed. Call FlushAsync or set allowSynchronousIO to true instead.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
// 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.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.IO.Pipelines
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a WriteOnlyStream backed by a PipeWriter
|
||||
/// </summary>
|
||||
public class WriteOnlyPipeStream : Stream
|
||||
{
|
||||
private PipeWriter _pipeWriter;
|
||||
private bool _allowSynchronousIO = true;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new WriteOnlyStream
|
||||
/// </summary>
|
||||
/// <param name="pipeWriter">The PipeWriter to write to.</param>
|
||||
public WriteOnlyPipeStream(PipeWriter pipeWriter) :
|
||||
this(pipeWriter, allowSynchronousIO: true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new WriteOnlyStream
|
||||
/// </summary>
|
||||
/// <param name="pipeWriter">The PipeWriter to write to.</param>
|
||||
/// <param name="allowSynchronousIO">Whether synchronous IO is allowed.</param>
|
||||
public WriteOnlyPipeStream(PipeWriter pipeWriter, bool allowSynchronousIO)
|
||||
{
|
||||
_pipeWriter = pipeWriter;
|
||||
_allowSynchronousIO = allowSynchronousIO;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanSeek => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanRead => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanWrite => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Position
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int ReadTimeout
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Flush()
|
||||
{
|
||||
if (!_allowSynchronousIO)
|
||||
{
|
||||
ThrowHelper.ThrowInvalidOperationException_SynchronousFlushesDisallowed();
|
||||
}
|
||||
|
||||
FlushAsync(default).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task FlushAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _pipeWriter.FlushAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_allowSynchronousIO)
|
||||
{
|
||||
ThrowHelper.ThrowInvalidOperationException_SynchronousWritesDisallowed();
|
||||
}
|
||||
WriteAsync(buffer, offset, count, default).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
var task = WriteAsync(buffer, offset, count, default, state);
|
||||
if (callback != null)
|
||||
{
|
||||
task.ContinueWith(t => callback.Invoke(t));
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void EndWrite(IAsyncResult asyncResult)
|
||||
{
|
||||
((Task<object>)asyncResult).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
private Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>(state);
|
||||
var task = WriteAsync(buffer, offset, count, cancellationToken);
|
||||
task.ContinueWith((task2, state2) =>
|
||||
{
|
||||
var tcs2 = (TaskCompletionSource<object>)state2;
|
||||
if (task2.IsCanceled)
|
||||
{
|
||||
tcs2.SetCanceled();
|
||||
}
|
||||
else if (task2.IsFaulted)
|
||||
{
|
||||
tcs2.SetException(task2.Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs2.SetResult(null);
|
||||
}
|
||||
}, tcs, cancellationToken);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
{
|
||||
return WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _pipeWriter.WriteAsync(source, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ using Xunit;
|
|||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class FlushResultCancellationTests : PipeTest
|
||||
public class FlushResultCancellationTests : StreamPipeTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task FlushAsyncWithNewCancellationTokenNotAffectedByPrevious()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
// 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.Buffers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class PipeStreamTest : IDisposable
|
||||
{
|
||||
public Stream ReadingStream { get; set; }
|
||||
public Stream WritingStream { get; set; }
|
||||
|
||||
public Pipe Pipe { get; set; }
|
||||
|
||||
public PipeReader Reader => Pipe.Reader;
|
||||
|
||||
public PipeWriter Writer => Pipe.Writer;
|
||||
|
||||
public PipeStreamTest()
|
||||
{
|
||||
Pipe = new Pipe();
|
||||
ReadingStream = new ReadOnlyPipeStream(Reader);
|
||||
WritingStream = new WriteOnlyPipeStream(Writer);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Writer.Complete();
|
||||
Reader.Complete();
|
||||
}
|
||||
|
||||
public async Task WriteStringToStreamAsync(string input)
|
||||
{
|
||||
await WritingStream.WriteAsync(Encoding.ASCII.GetBytes(input));
|
||||
}
|
||||
|
||||
public async Task WriteStringToPipeAsync(string input)
|
||||
{
|
||||
await Writer.WriteAsync(Encoding.ASCII.GetBytes(input));
|
||||
}
|
||||
|
||||
public async Task WriteByteArrayToPipeAsync(byte[] input)
|
||||
{
|
||||
await Writer.WriteAsync(input);
|
||||
}
|
||||
|
||||
public async Task<string> ReadFromPipeAsStringAsync()
|
||||
{
|
||||
var readResult = await Reader.ReadAsync();
|
||||
var result = Encoding.ASCII.GetString(readResult.Buffer.ToArray());
|
||||
Reader.AdvanceTo(readResult.Buffer.End);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<string> ReadFromStreamAsStringAsync()
|
||||
{
|
||||
var memory = new Memory<byte>(new byte[4096]);
|
||||
var readLength = await ReadingStream.ReadAsync(memory);
|
||||
var result = Encoding.ASCII.GetString(memory.ToArray(), 0, readLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<byte[]> ReadFromPipeAsByteArrayAsync()
|
||||
{
|
||||
var readResult = await Reader.ReadAsync();
|
||||
var result = readResult.Buffer.ToArray();
|
||||
Reader.AdvanceTo(readResult.Buffer.End);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Task<byte[]> ReadFromStreamAsByteArrayAsync(int size)
|
||||
{
|
||||
return ReadFromStreamAsByteArrayAsync(size, ReadingStream);
|
||||
}
|
||||
|
||||
public async Task<byte[]> ReadFromStreamAsByteArrayAsync(int size, Stream stream)
|
||||
{
|
||||
var memory = new Memory<byte>(new byte[size]);
|
||||
var readLength = await stream.ReadAsync(memory);
|
||||
return memory.Slice(0, readLength).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ using Xunit;
|
|||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class PipeWriterTests : PipeTest
|
||||
public class PipeWriterTests : StreamPipeTest
|
||||
{
|
||||
|
||||
[Theory]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -12,7 +12,7 @@ using Xunit;
|
|||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class ReadAsyncCancellationTests : PipeTest
|
||||
public class ReadAsyncCancellationTests : StreamPipeTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task AdvanceShouldResetStateIfReadCanceled()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
// 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.Buffers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class ReadOnlyPipeStreamTests : PipeStreamTest
|
||||
{
|
||||
[Fact]
|
||||
public void CanSeekFalse()
|
||||
{
|
||||
Assert.False(ReadingStream.CanSeek);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReadTrue()
|
||||
{
|
||||
Assert.True(ReadingStream.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteFalse()
|
||||
{
|
||||
Assert.False(ReadingStream.CanWrite);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LengthThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PositionThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.Position);
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.Position = 1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SeekThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.Seek(0, SeekOrigin.Begin));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetLengthThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.SetLength(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.Write(new byte[1], 0, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsyncThrows()
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await ReadingStream.WriteAsync(new byte[1], 0, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTimeoutThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.WriteTimeout = 1);
|
||||
Assert.Throws<NotSupportedException>(() => ReadingStream.WriteTimeout);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncWorks()
|
||||
{
|
||||
var expected = "Hello World!";
|
||||
|
||||
await WriteStringToPipeAsync(expected);
|
||||
|
||||
Assert.Equal(expected, await ReadFromStreamAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BasicLargeRead()
|
||||
{
|
||||
var expected = new byte[8000];
|
||||
|
||||
await WriteByteArrayToPipeAsync(expected);
|
||||
|
||||
Assert.Equal(expected, await ReadFromStreamAsByteArrayAsync(8000));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncIsCalledFromCallingRead()
|
||||
{
|
||||
var pipeReader = await SetupMockPipeReader();
|
||||
var stream = new ReadOnlyPipeStream(pipeReader.Object);
|
||||
|
||||
stream.Read(new byte[1]);
|
||||
|
||||
pipeReader.Verify(m => m.ReadAsync(It.IsAny<CancellationToken>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncIsCalledFromCallingReadAsync()
|
||||
{
|
||||
var pipeReader = await SetupMockPipeReader();
|
||||
var stream = new ReadOnlyPipeStream(pipeReader.Object);
|
||||
|
||||
await stream.ReadAsync(new byte[1]);
|
||||
|
||||
pipeReader.Verify(m => m.ReadAsync(It.IsAny<CancellationToken>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncCancellationTokenIsPassedIntoReadAsync()
|
||||
{
|
||||
var pipeReader = await SetupMockPipeReader();
|
||||
var stream = new ReadOnlyPipeStream(pipeReader.Object);
|
||||
var token = new CancellationToken();
|
||||
|
||||
await stream.ReadAsync(new byte[1], token);
|
||||
|
||||
pipeReader.Verify(m => m.ReadAsync(token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CopyToAsyncWorks()
|
||||
{
|
||||
const int expectedSize = 8000;
|
||||
var expected = new byte[expectedSize];
|
||||
|
||||
await WriteByteArrayToPipeAsync(expected);
|
||||
|
||||
Writer.Complete();
|
||||
var destStream = new MemoryStream();
|
||||
|
||||
await ReadingStream.CopyToAsync(destStream);
|
||||
|
||||
Assert.Equal(expectedSize, destStream.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BlockSyncIOThrows()
|
||||
{
|
||||
var readOnlyPipeStream = new ReadOnlyPipeStream(Reader, allowSynchronousIO: false);
|
||||
Assert.Throws<InvalidOperationException>(() => readOnlyPipeStream.Read(new byte[0], 0, 0));
|
||||
}
|
||||
|
||||
private async Task<Mock<PipeReader>> SetupMockPipeReader()
|
||||
{
|
||||
await WriteByteArrayToPipeAsync(new byte[1]);
|
||||
|
||||
var pipeReader = new Mock<PipeReader>();
|
||||
pipeReader
|
||||
.Setup(m => m.ReadAsync(It.IsAny<CancellationToken>()))
|
||||
.Returns(new ValueTask<ReadResult>(new ReadResult(new ReadOnlySequence<byte>(new byte[1]), false, false)));
|
||||
return pipeReader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
// 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.Buffers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class ReadingAdaptersInteropTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task CheckBasicReadPipeApi()
|
||||
{
|
||||
var pipe = new Pipe();
|
||||
var readStream = new ReadOnlyPipeStream(pipe.Reader);
|
||||
var pipeReader = new StreamPipeReader(readStream);
|
||||
|
||||
await pipe.Writer.WriteAsync(new byte[10]);
|
||||
var res = await pipeReader.ReadAsync();
|
||||
Assert.Equal(new byte[10], res.Buffer.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckNestedPipeApi()
|
||||
{
|
||||
var pipe = new Pipe();
|
||||
var reader = pipe.Reader;
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var readStream = new ReadOnlyPipeStream(reader);
|
||||
reader = new StreamPipeReader(readStream);
|
||||
}
|
||||
|
||||
await pipe.Writer.WriteAsync(new byte[10]);
|
||||
var res = await reader.ReadAsync();
|
||||
Assert.Equal(new byte[10], res.Buffer.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckBasicReadStreamApi()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
await stream.WriteAsync(new byte[10]);
|
||||
stream.Position = 0;
|
||||
|
||||
var pipeReader = new StreamPipeReader(stream);
|
||||
var readOnlyStream = new ReadOnlyPipeStream(pipeReader);
|
||||
|
||||
var resSize = await readOnlyStream.ReadAsync(new byte[10]);
|
||||
|
||||
Assert.Equal(10, resSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckNestedStreamApi()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
await stream.WriteAsync(new byte[10]);
|
||||
stream.Position = 0;
|
||||
|
||||
Stream readOnlyStream = stream;
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var pipeReader = new StreamPipeReader(readOnlyStream);
|
||||
readOnlyStream = new ReadOnlyPipeStream(pipeReader);
|
||||
}
|
||||
|
||||
var resSize = await readOnlyStream.ReadAsync(new byte[10]);
|
||||
|
||||
Assert.Equal(10, resSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadsCanBeCanceledViaProvidedCancellationToken()
|
||||
{
|
||||
var readOnlyStream = new ReadOnlyPipeStream(new HangingPipeReader());
|
||||
var pipeReader = new StreamPipeReader(readOnlyStream);
|
||||
|
||||
var cts = new CancellationTokenSource(1);
|
||||
await Task.Delay(1);
|
||||
await Assert.ThrowsAsync<TaskCanceledException>(async () => await pipeReader.ReadAsync(cts.Token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadCanBeCancelledViaCancelPendingReadWhenReadIsAsync()
|
||||
{
|
||||
var readOnlyStream = new ReadOnlyPipeStream(new HangingPipeReader());
|
||||
var pipeReader = new StreamPipeReader(readOnlyStream);
|
||||
|
||||
var result = new ReadResult();
|
||||
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
var readingTask = pipeReader.ReadAsync();
|
||||
tcs.SetResult(0);
|
||||
result = await readingTask;
|
||||
});
|
||||
await tcs.Task;
|
||||
pipeReader.CancelPendingRead();
|
||||
await task;
|
||||
|
||||
Assert.True(result.IsCanceled);
|
||||
}
|
||||
|
||||
private class HangingPipeReader : PipeReader
|
||||
{
|
||||
public override void AdvanceTo(SequencePosition consumed)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void AdvanceTo(SequencePosition consumed, SequencePosition examined)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void CancelPendingRead()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Complete(Exception exception = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void OnWriterCompleted(Action<Exception, object> callback, object state)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await Task.Delay(30000, cancellationToken);
|
||||
return new ReadResult();
|
||||
}
|
||||
|
||||
public override bool TryRead(out ReadResult result)
|
||||
{
|
||||
result = new ReadResult();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ using Xunit;
|
|||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public partial class StreamPipeReaderTests : PipeTest
|
||||
public partial class StreamPipeReaderTests : StreamPipeTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task CanRead()
|
||||
|
|
@ -198,6 +198,8 @@ namespace System.IO.Pipelines.Tests
|
|||
[Fact]
|
||||
public async Task ReadAsyncReturnsCanceledInterleaved()
|
||||
{
|
||||
Write(new byte[10000]);
|
||||
|
||||
// Cancel and Read interleaved to confirm cancellations are independent
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
|
|
@ -501,22 +503,6 @@ namespace System.IO.Pipelines.Tests
|
|||
Assert.False(readResult.Buffer.IsSingleSegment);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetMinimumReadThresholdToMiminumSegmentSizeOnlyGetNewBlockWhenDataIsWritten()
|
||||
{
|
||||
CreateReader(minimumReadThreshold: 16);
|
||||
WriteByteArray(0);
|
||||
|
||||
var readResult = await Reader.ReadAsync();
|
||||
Reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
|
||||
|
||||
WriteByteArray(16);
|
||||
readResult = await Reader.ReadAsync();
|
||||
|
||||
Assert.Equal(16, readResult.Buffer.Length);
|
||||
Assert.True(readResult.Buffer.IsSingleSegment);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetMinimumReadThresholdOfZeroThrows()
|
||||
{
|
||||
|
|
@ -595,6 +581,24 @@ namespace System.IO.Pipelines.Tests
|
|||
Assert.Equal("c", ReadFromStreamAsString(buffer));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncWithNoDataCompletesReader()
|
||||
{
|
||||
var readResult = await Reader.ReadAsync();
|
||||
|
||||
Assert.True(readResult.IsCompleted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncWithEmptyDataCompletesStream()
|
||||
{
|
||||
WriteByteArray(0);
|
||||
|
||||
var readResult = await Reader.ReadAsync();
|
||||
|
||||
Assert.True(readResult.IsCompleted);
|
||||
}
|
||||
|
||||
private async Task<string> ReadFromPipeAsString()
|
||||
{
|
||||
var readResult = await Reader.ReadAsync();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
// 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.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public abstract class PipeTest : IDisposable
|
||||
public abstract class StreamPipeTest : IDisposable
|
||||
{
|
||||
protected const int MaximumSizeHigh = 65;
|
||||
|
||||
|
|
@ -20,7 +17,7 @@ namespace System.IO.Pipelines.Tests
|
|||
|
||||
public PipeReader Reader { get; set; }
|
||||
|
||||
protected PipeTest()
|
||||
protected StreamPipeTest()
|
||||
{
|
||||
MemoryStream = new MemoryStream();
|
||||
Writer = new StreamPipeWriter(MemoryStream, MinimumSegmentSize, new TestMemoryPool());
|
||||
|
|
@ -12,7 +12,7 @@ using Xunit;
|
|||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class StreamPipeWriterTests : PipeTest
|
||||
public class StreamPipeWriterTests : StreamPipeTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task CanWriteAsyncMultipleTimesIntoSameBlock()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,199 @@
|
|||
// 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.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class WriteOnlyPipeStreamTests : PipeStreamTest
|
||||
{
|
||||
[Fact]
|
||||
public void CanSeekFalse()
|
||||
{
|
||||
Assert.False(WritingStream.CanSeek);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReadFalse()
|
||||
{
|
||||
Assert.False(WritingStream.CanRead);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteTrue()
|
||||
{
|
||||
Assert.True(WritingStream.CanWrite);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LengthThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PositionThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.Position);
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.Position = 1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SeekThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.Seek(0, SeekOrigin.Begin));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetLengthThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.SetLength(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.Read(new byte[1], 0, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsyncThrows()
|
||||
{
|
||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await WritingStream.ReadAsync(new byte[1], 0, 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadTimeoutThrows()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.ReadTimeout = 1);
|
||||
Assert.Throws<NotSupportedException>(() => WritingStream.ReadTimeout);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsyncWithReadOnlyMemoryWorks()
|
||||
{
|
||||
var expected = "Hello World!";
|
||||
|
||||
await WriteStringToStreamAsync(expected);
|
||||
|
||||
Assert.Equal(expected, await ReadFromPipeAsStringAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsyncWithArrayWorks()
|
||||
{
|
||||
var expected = new byte[1];
|
||||
|
||||
await WritingStream.WriteAsync(expected, 0, expected.Length);
|
||||
|
||||
Assert.Equal(expected, await ReadFromPipeAsByteArrayAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BasicLargeWrite()
|
||||
{
|
||||
var expected = new byte[8000];
|
||||
|
||||
await WritingStream.WriteAsync(expected);
|
||||
|
||||
Assert.Equal(expected, await ReadFromPipeAsByteArrayAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FlushAsyncIsCalledFromCallingFlush()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
|
||||
stream.Flush();
|
||||
|
||||
pipeWriter.Verify(m => m.FlushAsync(default));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FlushAsyncIsCalledFromCallingFlushAsync()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
|
||||
await stream.FlushAsync();
|
||||
|
||||
pipeWriter.Verify(m => m.FlushAsync(default));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FlushAsyncCancellationTokenIsPassedIntoFlushAsync()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
var token = new CancellationToken();
|
||||
|
||||
await stream.FlushAsync(token);
|
||||
|
||||
pipeWriter.Verify(m => m.FlushAsync(token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAsyncIsCalledFromCallingWrite()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
|
||||
stream.Write(new byte[1]);
|
||||
|
||||
pipeWriter.Verify(m => m.WriteAsync(It.IsAny<ReadOnlyMemory<byte>>(), It.IsAny<CancellationToken>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsyncIsCalledFromCallingWriteAsync()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
|
||||
await stream.WriteAsync(new byte[1]);
|
||||
|
||||
pipeWriter.Verify(m => m.WriteAsync(It.IsAny<ReadOnlyMemory<byte>>(), It.IsAny<CancellationToken>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsyncCancellationTokenIsPassedIntoWriteAsync()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
var token = new CancellationToken();
|
||||
|
||||
await stream.WriteAsync(new byte[1], token);
|
||||
|
||||
pipeWriter.Verify(m => m.WriteAsync(It.IsAny<ReadOnlyMemory<byte>>(), token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAsyncIsCalledFromBeginWrite()
|
||||
{
|
||||
var pipeWriter = new Mock<PipeWriter>();
|
||||
var stream = new WriteOnlyPipeStream(pipeWriter.Object);
|
||||
stream.BeginWrite(new byte[1], 0, 1, null, this);
|
||||
pipeWriter.Verify(m => m.WriteAsync(It.IsAny<ReadOnlyMemory<byte>>(), It.IsAny<CancellationToken>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BeginAndEndWriteWork()
|
||||
{
|
||||
var expected = new byte[1];
|
||||
var asyncResult = WritingStream.BeginWrite(expected, 0, 1, null, this);
|
||||
WritingStream.EndWrite(asyncResult);
|
||||
Assert.Equal(expected, await ReadFromPipeAsByteArrayAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BlockSyncIOThrows()
|
||||
{
|
||||
var writeOnlyPipeStream = new WriteOnlyPipeStream(Writer, allowSynchronousIO: false);
|
||||
Assert.Throws<InvalidOperationException>(() => writeOnlyPipeStream.Write(new byte[0], 0, 0));
|
||||
Assert.Throws<InvalidOperationException>(() => writeOnlyPipeStream.Flush());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
// 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.Buffers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace System.IO.Pipelines.Tests
|
||||
{
|
||||
public class WritingAdaptersInteropTests : PipeStreamTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task CheckBasicWritePipeApi()
|
||||
{
|
||||
var pipe = new Pipe();
|
||||
var writeOnlyStream = new WriteOnlyPipeStream(pipe.Writer);
|
||||
var pipeWriter = new StreamPipeWriter(writeOnlyStream);
|
||||
await pipeWriter.WriteAsync(new byte[10]);
|
||||
|
||||
var res = await pipe.Reader.ReadAsync();
|
||||
Assert.Equal(new byte[10], res.Buffer.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckNestedPipeApi()
|
||||
{
|
||||
var pipe = new Pipe();
|
||||
var writer = pipe.Writer;
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var writeOnlyStream = new WriteOnlyPipeStream(writer);
|
||||
writer = new StreamPipeWriter(writeOnlyStream);
|
||||
}
|
||||
|
||||
await writer.WriteAsync(new byte[10]);
|
||||
|
||||
var res = await pipe.Reader.ReadAsync();
|
||||
Assert.Equal(new byte[10], res.Buffer.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckBasicWriteStreamApi()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var pipeWriter = new StreamPipeWriter(stream);
|
||||
var writeOnlyStream = new WriteOnlyPipeStream(pipeWriter);
|
||||
|
||||
await writeOnlyStream.WriteAsync(new byte[10]);
|
||||
|
||||
stream.Position = 0;
|
||||
var res = await ReadFromStreamAsByteArrayAsync(10, stream);
|
||||
Assert.Equal(new byte[10], res);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CheckNestedStreamApi()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
Stream writeOnlyStream = stream;
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var pipeWriter = new StreamPipeWriter(writeOnlyStream);
|
||||
writeOnlyStream = new WriteOnlyPipeStream(pipeWriter);
|
||||
}
|
||||
|
||||
await writeOnlyStream.WriteAsync(new byte[10]);
|
||||
|
||||
stream.Position = 0;
|
||||
var res = await ReadFromStreamAsByteArrayAsync(10, stream);
|
||||
Assert.Equal(new byte[10], res);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WritesCanBeCanceledViaProvidedCancellationToken()
|
||||
{
|
||||
var writeOnlyStream = new WriteOnlyPipeStream(new HangingPipeWriter());
|
||||
var pipeWriter = new StreamPipeWriter(writeOnlyStream);
|
||||
var cts = new CancellationTokenSource(1);
|
||||
await Assert.ThrowsAsync<TaskCanceledException>(async () => await pipeWriter.WriteAsync(new byte[1], cts.Token));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteCanBeCanceledViaCancelPendingFlushWhenFlushIsAsync()
|
||||
{
|
||||
var writeOnlyStream = new WriteOnlyPipeStream(new HangingPipeWriter());
|
||||
var pipeWriter = new StreamPipeWriter(writeOnlyStream);
|
||||
|
||||
FlushResult flushResult = new FlushResult();
|
||||
var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var writingTask = pipeWriter.WriteAsync(new byte[1]);
|
||||
tcs.SetResult(0);
|
||||
flushResult = await writingTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
|
||||
await tcs.Task;
|
||||
|
||||
pipeWriter.CancelPendingFlush();
|
||||
|
||||
await task;
|
||||
|
||||
Assert.True(flushResult.IsCanceled);
|
||||
}
|
||||
|
||||
private class HangingPipeWriter : PipeWriter
|
||||
{
|
||||
public override void Advance(int bytes)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CancelPendingFlush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Complete(Exception exception = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override async ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await Task.Delay(30000, cancellationToken);
|
||||
return new FlushResult();
|
||||
}
|
||||
|
||||
public override Memory<byte> GetMemory(int sizeHint = 0)
|
||||
{
|
||||
return new Memory<byte>(new byte[4096]);
|
||||
}
|
||||
|
||||
public override Span<byte> GetSpan(int sizeHint = 0)
|
||||
{
|
||||
return new Span<byte>(new byte[4096]);
|
||||
}
|
||||
|
||||
public override void OnReaderCompleted(Action<Exception, object> callback, object state)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -352,12 +352,12 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
{
|
||||
Describe(res, AuthenticateResult.Success(new AuthenticationTicket(context.User, null, "Application")));
|
||||
await DescribeAsync(res, AuthenticateResult.Success(new AuthenticationTicket(context.User, null, "Application")));
|
||||
}
|
||||
else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder))
|
||||
{
|
||||
var auth = await context.AuthenticateAsync(remainder.Value.Substring(1));
|
||||
Describe(res, auth);
|
||||
await DescribeAsync(res, auth);
|
||||
}
|
||||
else if (req.Path == new PathString("/testpath") && testpath != null)
|
||||
{
|
||||
|
|
@ -393,7 +393,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
return server;
|
||||
}
|
||||
|
||||
private static void Describe(HttpResponse res, AuthenticateResult result)
|
||||
private static async Task DescribeAsync(HttpResponse res, AuthenticateResult result)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
|
|
@ -412,7 +412,7 @@ namespace Microsoft.AspNetCore.Identity.InMemory
|
|||
{
|
||||
xml.WriteTo(writer);
|
||||
}
|
||||
res.Body.Write(memory.ToArray(), 0, memory.ToArray().Length);
|
||||
await res.Body.WriteAsync(memory.ToArray(), 0, memory.ToArray().Length);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ namespace SampleDestination
|
|||
|
||||
context.Response.ContentType = "text/plain; charset=utf-8";
|
||||
context.Response.ContentLength = content.Length;
|
||||
context.Response.Body.Write(content, 0, content.Length);
|
||||
|
||||
return Task.CompletedTask;
|
||||
return context.Response.Body.WriteAsync(content, 0, content.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,9 +86,7 @@ namespace SampleDestination
|
|||
|
||||
context.Response.ContentType = "text/plain; charset=utf-8";
|
||||
context.Response.ContentLength = content.Length;
|
||||
context.Response.Body.Write(content, 0, content.Length);
|
||||
|
||||
return Task.CompletedTask;
|
||||
return context.Response.Body.WriteAsync(content, 0, content.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -81,6 +81,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests
|
|||
var uniqueId = Guid.NewGuid().ToString();
|
||||
if (TestRequestDelegate(context, uniqueId))
|
||||
{
|
||||
var feature = context.Features.Get<IHttpBodyControlFeature>();
|
||||
if (feature != null)
|
||||
{
|
||||
feature.AllowSynchronousIO = true;
|
||||
}
|
||||
context.Response.Write(uniqueId);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
|
|
|
|||
|
|
@ -548,6 +548,12 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
app.UseResponseCompression();
|
||||
app.Run(context =>
|
||||
{
|
||||
var feature = context.Features.Get<IHttpBodyControlFeature>();
|
||||
if (feature != null)
|
||||
{
|
||||
feature.AllowSynchronousIO = true;
|
||||
}
|
||||
|
||||
context.Response.Headers[HeaderNames.ContentMD5] = "MD5";
|
||||
context.Response.ContentType = TextPlain;
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
|
|
@ -652,6 +658,12 @@ namespace Microsoft.AspNetCore.ResponseCompression.Tests
|
|||
context.Response.ContentType = TextPlain;
|
||||
context.Features.Get<IHttpBufferingFeature>()?.DisableResponseBuffering();
|
||||
|
||||
var feature = context.Features.Get<IHttpBodyControlFeature>();
|
||||
if (feature != null)
|
||||
{
|
||||
feature.AllowSynchronousIO = true;
|
||||
}
|
||||
|
||||
foreach (var signal in responseReceived)
|
||||
{
|
||||
context.Response.Body.Write(new byte[1], 0, 1);
|
||||
|
|
|
|||
|
|
@ -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.Text;
|
||||
|
|
@ -31,6 +31,11 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
|
|||
|
||||
if (!string.IsNullOrEmpty(StatusDescription))
|
||||
{
|
||||
var feature = context.HttpContext.Features.Get<IHttpBodyControlFeature>();
|
||||
if (feature != null)
|
||||
{
|
||||
feature.AllowSynchronousIO = true;
|
||||
}
|
||||
var content = Encoding.UTF8.GetBytes(StatusDescription);
|
||||
response.ContentLength = content.Length;
|
||||
response.ContentType = "text/plain; charset=utf-8";
|
||||
|
|
@ -42,4 +47,4 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
|
|||
context.Logger?.CustomResponse(context.HttpContext.Request.GetEncodedUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,28 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://localhost/Login/Index", "Login", "Index", "http://localhost/Login")]
|
||||
[InlineData("http://localhost/Login/Sso", "Login", "Sso", "http://localhost/Login/Sso")]
|
||||
[InlineData("http://localhost/Contact/Index", "Contact", "Index", "http://localhost/Contact")]
|
||||
[InlineData("http://localhost/Contact/Sso", "Contact", "Sso", "http://localhost/Contact/Sso")]
|
||||
public async Task ConventionalRoutedAction_RouteUrl_AmbientValues(string requestUrl, string controller, string action, string expectedUrl)
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync(requestUrl);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal(controller, result.Controller);
|
||||
Assert.Equal(action, result.Action);
|
||||
|
||||
Assert.Equal(expectedUrl, Assert.Single(result.ExpectedUrls));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_RouteContainsPage_RouteNotMatched()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace RoutingWebSite
|
||||
{
|
||||
// This controller is reachable via traditional routing.
|
||||
public class ContactController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public ContactController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("ActionAsMethod", null, Url.ActionContext.HttpContext.Request.Scheme));
|
||||
}
|
||||
|
||||
public IActionResult Sso()
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("ActionAsMethod", null, Url.ActionContext.HttpContext.Request.Scheme));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// 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 Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace RoutingWebSite
|
||||
{
|
||||
// This controller is reachable via traditional routing.
|
||||
public class LoginController : Controller
|
||||
{
|
||||
private readonly TestResponseGenerator _generator;
|
||||
|
||||
public LoginController(TestResponseGenerator generator)
|
||||
{
|
||||
_generator = generator;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("ActionAsMethod", null, Url.ActionContext.HttpContext.Request.Scheme));
|
||||
}
|
||||
|
||||
public IActionResult Sso()
|
||||
{
|
||||
return _generator.Generate(Url.RouteUrl("ActionAsMethod", null, Url.ActionContext.HttpContext.Request.Scheme));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -92,5 +92,10 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
return new HandleRequestResult() { Skipped = true };
|
||||
}
|
||||
|
||||
public new static HandleRequestResult NoResult()
|
||||
{
|
||||
return new HandleRequestResult() { None = true };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
return HandleRequestResult.Handle();
|
||||
}
|
||||
|
||||
return HandleRequestResult.Fail("Access was denied by the resource owner or by the remote server.", properties);
|
||||
return HandleRequestResult.NoResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,9 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
// Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information.
|
||||
if (StringValues.Equals(error, "access_denied"))
|
||||
{
|
||||
return await HandleAccessDeniedErrorAsync(properties);
|
||||
var result = await HandleAccessDeniedErrorAsync(properties);
|
||||
return !result.None ? result
|
||||
: HandleRequestResult.Fail("Access was denied by the resource owner or by the remote server.", properties);
|
||||
}
|
||||
|
||||
var failureMessage = new StringBuilder();
|
||||
|
|
|
|||
|
|
@ -560,7 +560,11 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
// Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information.
|
||||
if (string.Equals(authorizationResponse.Error, "access_denied", StringComparison.Ordinal))
|
||||
{
|
||||
return await HandleAccessDeniedErrorAsync(properties);
|
||||
var result = await HandleAccessDeniedErrorAsync(properties);
|
||||
if (!result.None)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return HandleRequestResult.Fail(CreateOpenIdConnectProtocolException(authorizationResponse, response: null), properties);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
// approve the authorization demand requested by the remote authorization server.
|
||||
// Since it's a frequent scenario (that is not caused by incorrect configuration),
|
||||
// denied errors are handled differently using HandleAccessDeniedErrorAsync().
|
||||
return await HandleAccessDeniedErrorAsync(properties);
|
||||
var result = await HandleAccessDeniedErrorAsync(properties);
|
||||
return !result.None ? result
|
||||
: HandleRequestResult.Fail("Access was denied by the resource owner or by the remote server.", properties);
|
||||
}
|
||||
|
||||
var returnedToken = query["oauth_token"];
|
||||
|
|
@ -311,4 +313,4 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1302,7 +1302,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
app.Use(async (context, next) =>
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Cookies");
|
||||
Describe(context.Response, result);
|
||||
await DescribeAsync(context.Response, result);
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services => services.AddAuthentication().AddCookie("Cookies", o =>
|
||||
|
|
@ -1478,12 +1478,12 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
{
|
||||
Describe(res, AuthenticateResult.Success(new AuthenticationTicket(context.User, new AuthenticationProperties(), CookieAuthenticationDefaults.AuthenticationScheme)));
|
||||
await DescribeAsync(res, AuthenticateResult.Success(new AuthenticationTicket(context.User, new AuthenticationProperties(), CookieAuthenticationDefaults.AuthenticationScheme)));
|
||||
}
|
||||
else if (req.Path.StartsWithSegments(new PathString("/me"), out remainder))
|
||||
{
|
||||
var ticket = await context.AuthenticateAsync(remainder.Value.Substring(1));
|
||||
Describe(res, ticket);
|
||||
await DescribeAsync(res, ticket);
|
||||
}
|
||||
else if (req.Path == new PathString("/testpath") && testpath != null)
|
||||
{
|
||||
|
|
@ -1510,7 +1510,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
return server;
|
||||
}
|
||||
|
||||
private static void Describe(HttpResponse res, AuthenticateResult result)
|
||||
private static Task DescribeAsync(HttpResponse res, AuthenticateResult result)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
|
|
@ -1524,7 +1524,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
|||
xml.Add(result.Ticket.Properties.Items.Select(extra => new XElement("extra", new XAttribute("type", extra.Key), new XAttribute("value", extra.Value))));
|
||||
}
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xml.ToString());
|
||||
res.Body.Write(xmlBytes, 0, xmlBytes.Length);
|
||||
return res.Body.WriteAsync(xmlBytes, 0, xmlBytes.Length);
|
||||
}
|
||||
|
||||
private static async Task<Transaction> SendAsync(TestServer server, string uri, string cookieHeader = null)
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
var name = (remainder.Value.Length > 0) ? remainder.Value.Substring(1) : null;
|
||||
var result = await context.AuthenticateAsync(name);
|
||||
res.Describe(result?.Ticket?.Principal);
|
||||
await res.DescribeAsync(result?.Ticket?.Principal);
|
||||
}
|
||||
else if (req.Path.StartsWithSegments(new PathString("/remove"), out remainder))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1177,26 +1177,26 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
|||
{
|
||||
var result = await context.AuthenticateAsync(TestExtensions.CookieAuthenticationScheme);
|
||||
var tokens = result.Properties.GetTokens();
|
||||
res.Describe(tokens);
|
||||
await res.DescribeAsync(tokens);
|
||||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
{
|
||||
res.Describe(context.User);
|
||||
await res.DescribeAsync(context.User);
|
||||
}
|
||||
else if (req.Path == new PathString("/authenticate"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync(TestExtensions.CookieAuthenticationScheme);
|
||||
res.Describe(result.Principal);
|
||||
await res.DescribeAsync(result.Principal);
|
||||
}
|
||||
else if (req.Path == new PathString("/authenticateGoogle"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Google");
|
||||
res.Describe(result?.Principal);
|
||||
await res.DescribeAsync(result?.Principal);
|
||||
}
|
||||
else if (req.Path == new PathString("/authenticateFacebook"))
|
||||
{
|
||||
var result = await context.AuthenticateAsync("Facebook");
|
||||
res.Describe(result?.Principal);
|
||||
await res.DescribeAsync(result?.Principal);
|
||||
}
|
||||
else if (req.Path == new PathString("/unauthorized"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
|
|||
}
|
||||
else if (req.Path == new PathString("/me"))
|
||||
{
|
||||
res.Describe(context.User);
|
||||
await res.DescribeAsync(context.User);
|
||||
}
|
||||
else if (req.Path == new PathString("/signIn"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
{
|
||||
var name = (remainder.Value.Length > 0) ? remainder.Value.Substring(1) : null;
|
||||
var result = await context.AuthenticateAsync(name);
|
||||
res.Describe(result?.Ticket?.Principal);
|
||||
await res.DescribeAsync(result?.Ticket?.Principal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
return transaction;
|
||||
}
|
||||
|
||||
public static void Describe(this HttpResponse res, ClaimsPrincipal principal)
|
||||
public static Task DescribeAsync(this HttpResponse res, ClaimsPrincipal principal)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
|
|
@ -62,10 +62,10 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
}
|
||||
}
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xml.ToString());
|
||||
res.Body.Write(xmlBytes, 0, xmlBytes.Length);
|
||||
return res.Body.WriteAsync(xmlBytes, 0, xmlBytes.Length);
|
||||
}
|
||||
|
||||
public static void Describe(this HttpResponse res, IEnumerable<AuthenticationToken> tokens)
|
||||
public static Task DescribeAsync(this HttpResponse res, IEnumerable<AuthenticationToken> tokens)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
|
|
@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
}
|
||||
}
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xml.ToString());
|
||||
res.Body.Write(xmlBytes, 0, xmlBytes.Length);
|
||||
return res.Body.WriteAsync(xmlBytes, 0, xmlBytes.Length);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,24 +45,5 @@ namespace Microsoft.AspNetCore.CookiePolicy
|
|||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public static void Describe(this HttpResponse res, ClaimsPrincipal principal)
|
||||
{
|
||||
res.StatusCode = 200;
|
||||
res.ContentType = "text/xml";
|
||||
var xml = new XElement("xml");
|
||||
if (principal != null)
|
||||
{
|
||||
foreach (var identity in principal.Identities)
|
||||
{
|
||||
xml.Add(identity.Claims.Select(claim =>
|
||||
new XElement("claim", new XAttribute("type", claim.Type),
|
||||
new XAttribute("value", claim.Value),
|
||||
new XAttribute("issuer", claim.Issuer))));
|
||||
}
|
||||
}
|
||||
var xmlBytes = Encoding.UTF8.GetBytes(xml.ToString());
|
||||
res.Body.Write(xmlBytes, 0, xmlBytes.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
|
|||
|
||||
context = await server.AcceptAsync(Utilities.DefaultTimeout).Before(responseTask);
|
||||
// First write sends headers
|
||||
context.AllowSynchronousIO = true;
|
||||
context.Response.Body.Write(new byte[10], 0, 10);
|
||||
|
||||
var response = await responseTask;
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests
|
|||
httpContext.Response.Headers["x-request-count"] = (requestCount++).ToString();
|
||||
httpContext.Response.Headers["Cache-Control"] = "public, max-age=10";
|
||||
httpContext.Response.ContentLength = 10;
|
||||
httpContext.Response.Body.Flush();
|
||||
httpContext.Response.Body.FlushAsync();
|
||||
return httpContext.Response.Body.WriteAsync(new byte[10], 0, 10);
|
||||
}))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -214,9 +214,7 @@ try
|
|||
DWORD dwBufferSize = s_initialGetNativeSearchDirectoriesBufferSize;
|
||||
DWORD dwRequiredBufferSize = 0;
|
||||
|
||||
RETURN_LAST_ERROR_IF_NULL(m_hHostFxrDll = LoadLibraryW(hostfxrOptions.GetHostFxrLocation().c_str()));
|
||||
|
||||
auto const hostFxr = HostFxr::CreateFromLoadedModule();
|
||||
m_hHostFxrDll.Load(hostfxrOptions.GetHostFxrLocation());
|
||||
|
||||
{
|
||||
auto redirectionOutput = LoggingHelpers::CreateOutputs(
|
||||
|
|
@ -227,7 +225,7 @@ try
|
|||
);
|
||||
|
||||
StandardStreamRedirection stdOutRedirection(*redirectionOutput.get(), m_pServer.IsCommandLineLaunch());
|
||||
auto hostFxrErrorRedirection = hostFxr.RedirectOutput(redirectionOutput.get());
|
||||
auto hostFxrErrorRedirection = m_hHostFxrDll.RedirectOutput(redirectionOutput.get());
|
||||
|
||||
struNativeSearchPaths.resize(dwBufferSize);
|
||||
while (TRUE)
|
||||
|
|
@ -237,7 +235,7 @@ try
|
|||
|
||||
hostfxrOptions.GetArguments(hostfxrArgc, hostfxrArgv);
|
||||
|
||||
const auto intHostFxrExitCode = hostFxr.GetNativeSearchDirectories(
|
||||
const auto intHostFxrExitCode = m_hHostFxrDll.GetNativeSearchDirectories(
|
||||
hostfxrArgc,
|
||||
hostfxrArgv.get(),
|
||||
struNativeSearchPaths.data(),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "HandleWrapper.h"
|
||||
#include "ApplicationFactory.h"
|
||||
#include "RedirectionOutput.h"
|
||||
#include "HostFxr.h"
|
||||
|
||||
class HandlerResolver
|
||||
{
|
||||
|
|
@ -35,7 +36,7 @@ private:
|
|||
SRWLOCK m_requestHandlerLoadLock {};
|
||||
std::wstring m_loadedApplicationId;
|
||||
APP_HOSTING_MODEL m_loadedApplicationHostingModel;
|
||||
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
|
||||
HostFxr m_hHostFxrDll;
|
||||
|
||||
static const PCWSTR s_pwzAspnetcoreInProcessRequestHandlerName;
|
||||
static const PCWSTR s_pwzAspnetcoreOutOfProcessRequestHandlerName;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,61 @@ void HostFxrErrorRedirector::HostFxrErrorRedirectorCallback(const WCHAR* message
|
|||
m_writeFunction->Append(std::wstring(message) + L"\r\n");
|
||||
}
|
||||
|
||||
|
||||
void HostFxr::Load()
|
||||
{
|
||||
HMODULE hModule;
|
||||
THROW_LAST_ERROR_IF(!GetModuleHandleEx(0, L"hostfxr.dll", &hModule));
|
||||
Load(hModule);
|
||||
}
|
||||
|
||||
void HostFxr::Load(HMODULE moduleHandle)
|
||||
{
|
||||
m_hHostFxrDll = moduleHandle;
|
||||
try
|
||||
{
|
||||
m_hostfxr_main_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(moduleHandle, "hostfxr_main");
|
||||
m_hostfxr_get_native_search_directories_fn = ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(moduleHandle, "hostfxr_get_native_search_directories");
|
||||
m_corehost_set_error_writer_fn = ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(moduleHandle, "hostfxr_set_error_writer", /* optional */ true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_GENERAL_ERROR,
|
||||
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
|
||||
ModuleHelpers::GetModuleFileNameValue(moduleHandle).c_str()
|
||||
);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HostFxr::Load(const std::wstring& location)
|
||||
{
|
||||
try
|
||||
{
|
||||
HMODULE hModule;
|
||||
THROW_LAST_ERROR_IF_NULL(hModule = LoadLibraryW(location.c_str()));
|
||||
Load(hModule);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_GENERAL_ERROR,
|
||||
ASPNETCORE_EVENT_HOSTFXR_DLL_UNABLE_TO_LOAD_MSG,
|
||||
location.c_str()
|
||||
);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void HostFxr::SetMain(hostfxr_main_fn hostfxr_main_fn)
|
||||
{
|
||||
m_hostfxr_main_fn = hostfxr_main_fn;
|
||||
}
|
||||
|
||||
int HostFxr::Main(DWORD argc, const PCWSTR* argv) const noexcept(false)
|
||||
{
|
||||
return m_hostfxr_main_fn(argc, argv);
|
||||
|
|
@ -44,27 +99,3 @@ HostFxrErrorRedirector HostFxr::RedirectOutput(RedirectionOutput* writer) const
|
|||
{
|
||||
return HostFxrErrorRedirector(m_corehost_set_error_writer_fn, writer);
|
||||
}
|
||||
|
||||
HostFxr HostFxr::CreateFromLoadedModule()
|
||||
{
|
||||
HMODULE hModule;
|
||||
THROW_LAST_ERROR_IF_NULL(hModule = GetModuleHandle(L"hostfxr.dll"));
|
||||
|
||||
try
|
||||
{
|
||||
return HostFxr(
|
||||
ModuleHelpers::GetKnownProcAddress<hostfxr_main_fn>(hModule, "hostfxr_main"),
|
||||
ModuleHelpers::GetKnownProcAddress<hostfxr_get_native_search_directories_fn>(hModule, "hostfxr_get_native_search_directories"),
|
||||
ModuleHelpers::GetKnownProcAddress<corehost_set_error_writer_fn>(hModule, "hostfxr_set_error_writer", /* optional */ true));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
EventLog::Error(
|
||||
ASPNETCORE_EVENT_GENERAL_ERROR,
|
||||
ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG,
|
||||
ModuleHelpers::GetModuleFileNameValue(hModule).c_str()
|
||||
);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,13 @@ private:
|
|||
static inline thread_local RedirectionOutput* m_writeFunction;
|
||||
};
|
||||
|
||||
class HostFxr
|
||||
class HostFxr: NonCopyable
|
||||
{
|
||||
public:
|
||||
HostFxr() : HostFxr(nullptr, nullptr, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
HostFxr(
|
||||
hostfxr_main_fn hostfxr_main_fn,
|
||||
hostfxr_get_native_search_directories_fn hostfxr_get_native_search_directories_fn,
|
||||
|
|
@ -39,18 +43,22 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void Load();
|
||||
void Load(HMODULE moduleHandle);
|
||||
void Load(const std::wstring& location);
|
||||
|
||||
~HostFxr() = default;
|
||||
|
||||
void SetMain(hostfxr_main_fn hostfxr_main_fn);
|
||||
|
||||
int Main(DWORD argc, CONST PCWSTR* argv) const noexcept(false);
|
||||
|
||||
int GetNativeSearchDirectories(INT argc, CONST PCWSTR* argv, PWSTR buffer, DWORD buffer_size, DWORD* required_buffer_size) const noexcept;
|
||||
|
||||
HostFxrErrorRedirector RedirectOutput(RedirectionOutput* writer) const noexcept;
|
||||
|
||||
static
|
||||
HostFxr CreateFromLoadedModule();
|
||||
|
||||
private:
|
||||
HandleWrapper<ModuleHandleTraits> m_hHostFxrDll;
|
||||
hostfxr_main_fn m_hostfxr_main_fn;
|
||||
hostfxr_get_native_search_directories_fn m_hostfxr_get_native_search_directories_fn;
|
||||
corehost_set_error_writer_fn m_corehost_set_error_writer_fn;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#define ASPNETCORE_EVENT_RECYCLE_FAILURE_CONFIGURATION_MSG L"Failed to recycle application due to a configuration change at '%s'. Recycling worker process."
|
||||
#define ASPNETCORE_EVENT_MODULE_DISABLED_MSG L"AspNetCore Module is disabled"
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_DLL_INVALID_VERSION_MSG L"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '%s'."
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_DLL_UNABLE_TO_LOAD_MSG L"Unable to load '%s'. This might be caused by a bitness mismatch between IIS application pool and published application."
|
||||
#define ASPNETCORE_EVENT_HOSTFXR_FAILURE_MSG L"Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. This most likely means the app is misconfigured, please check the versions of Microsoft.NetCore.App and Microsoft.AspNetCore.App that are targeted by the application and are installed on the machine."
|
||||
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, exception code = '0x%x'. Please check the stderr logs for more information."
|
||||
#define ASPNETCORE_EVENT_INPROCESS_THREAD_EXCEPTION_STDOUT_MSG L"Application '%s' with physical root '%s' hit unexpected managed exception, exception code = '0x%x'. Last 4KB characters of captured stdout and stderr logs:\r\n%s"
|
||||
|
|
|
|||
|
|
@ -189,11 +189,11 @@ IN_PROCESS_APPLICATION::ExecuteApplication()
|
|||
|
||||
hostFxrResolutionResult->GetArguments(context->m_argc, context->m_argv);
|
||||
THROW_IF_FAILED(SetEnvironmentVariablesOnWorkerProcess());
|
||||
context->m_hostFxr = HostFxr::CreateFromLoadedModule();
|
||||
context->m_hostFxr.Load();
|
||||
}
|
||||
else
|
||||
{
|
||||
context->m_hostFxr = HostFxr(s_fMainCallback, nullptr, nullptr);
|
||||
context->m_hostFxr.SetMain(s_fMainCallback);
|
||||
}
|
||||
|
||||
// There can only ever be a single instance of .NET Core
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core
|
|||
_options = options;
|
||||
_server = server;
|
||||
_logger = logger;
|
||||
|
||||
((IHttpBodyControlFeature)this).AllowSynchronousIO = _options.AllowSynchronousIO;
|
||||
}
|
||||
|
||||
public Version HttpVersion { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
// 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 Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public class IISServerOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value that controls whether synchronous IO is allowed for the <see cref="HttpContext.Request"/> and <see cref="HttpContext.Response"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Defaults to true.
|
||||
/// </remarks>
|
||||
public bool AllowSynchronousIO { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true the server should set HttpContext.User. If false the server will only provide an
|
||||
/// identity when explicitly requested by the AuthenticationScheme.
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
|
||||
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("identity", 0));
|
||||
client.DefaultRequestHeaders.Add("Response-Content-Type", "text/event-stream");
|
||||
var messages = "Message1\r\nMessage2\r\n";
|
||||
var messages = "Message1\r\nMessage2\r\n\r\n";
|
||||
|
||||
// Send messages with terminator
|
||||
var response = await client.PostAsync("ReadAndWriteEchoLines", new StringContent(messages + "\r\n"));
|
||||
var response = await client.PostAsync("ReadAndWriteEchoLines", new StringContent(messages));
|
||||
Assert.Equal(messages, await response.Content.ReadAsStringAsync());
|
||||
Assert.True(response.Content.Headers.TryGetValues("Content-Type", out var contentTypes));
|
||||
Assert.Single(contentTypes, "text/event-stream");
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
[ConditionalTheory]
|
||||
[InlineData(RuntimeArchitecture.x64)]
|
||||
[InlineData(RuntimeArchitecture.x86)]
|
||||
[SkipIfNotAdmin]
|
||||
[RequiresNewShim]
|
||||
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||
public async Task StartsWithDotnetInstallLocation(RuntimeArchitecture runtimeArchitecture)
|
||||
|
|
@ -256,7 +257,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RemoveHostfxrFromApp_InProcessHostfxrInvalid()
|
||||
public async Task RemoveHostfxrFromApp_InProcessHostfxrAPIAbsent()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||
|
|
@ -271,6 +272,20 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrInvalid(deploymentResult), Logger);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task RemoveHostfxrFromApp_InProcessHostfxrLoadFailure()
|
||||
{
|
||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||
deploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||
|
||||
// We don't distinguish between load failure types so making dll empty should be enough
|
||||
File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "hostfxr.dll"), "");
|
||||
await AssertSiteFailsToStartWithInProcessStaticContent(deploymentResult);
|
||||
|
||||
EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.InProcessHostfxrUnableToLoad(deploymentResult), Logger);
|
||||
}
|
||||
|
||||
[ConditionalFact]
|
||||
public async Task TargedDifferenceSharedFramework_FailedToFindNativeDependencies()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -185,6 +185,11 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
|||
return $"Hostfxr version used does not support 'hostfxr_get_native_search_directories', update the version of hostfxr to a higher version. Path to hostfxr: '(.*)'.";
|
||||
}
|
||||
|
||||
public static string InProcessHostfxrUnableToLoad(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return $"Unable to load '(.*)'. This might be caused by a bitness mismatch between IIS application pool and published application.";
|
||||
}
|
||||
|
||||
public static string InProcessFailedToFindNativeDependencies(IISDeploymentResult deploymentResult)
|
||||
{
|
||||
return "Invoking hostfxr to find the inprocess request handler failed without finding any native dependencies. " +
|
||||
|
|
|
|||
|
|
@ -331,10 +331,10 @@ namespace TestSite
|
|||
await ctx.Response.Body.FlushAsync();
|
||||
|
||||
var reader = new StreamReader(ctx.Request.Body);
|
||||
while (!reader.EndOfStream)
|
||||
while (true)
|
||||
{
|
||||
var line = await reader.ReadLineAsync();
|
||||
if (line == "")
|
||||
if (line == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -357,10 +357,10 @@ namespace TestSite
|
|||
await ctx.Response.Body.FlushAsync();
|
||||
|
||||
var reader = new StreamReader(ctx.Request.Body);
|
||||
while (!reader.EndOfStream)
|
||||
while (true)
|
||||
{
|
||||
var line = await reader.ReadLineAsync();
|
||||
if (line == "")
|
||||
if (line == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -438,8 +438,8 @@ namespace TestSite
|
|||
private async Task TestReadOffsetWorks(HttpContext ctx)
|
||||
{
|
||||
var buffer = new byte[11];
|
||||
ctx.Request.Body.Read(buffer, 0, 6);
|
||||
ctx.Request.Body.Read(buffer, 6, 5);
|
||||
await ctx.Request.Body.ReadAsync(buffer, 0, 6);
|
||||
await ctx.Request.Body.ReadAsync(buffer, 6, 5);
|
||||
|
||||
await ctx.Response.WriteAsync(Encoding.UTF8.GetString(buffer));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
var task = ReadAsync(buffer, offset, count, default(CancellationToken), state);
|
||||
var task = ReadAsync(buffer, offset, count, default, state);
|
||||
if (callback != null)
|
||||
{
|
||||
task.ContinueWith(t => callback.Invoke(t));
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
public override void Flush()
|
||||
{
|
||||
FlushAsync(default(CancellationToken)).GetAwaiter().GetResult();
|
||||
FlushAsync(default).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override Task FlushAsync(CancellationToken cancellationToken)
|
||||
|
|
@ -64,12 +64,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
throw new InvalidOperationException(CoreStrings.SynchronousWritesDisallowed);
|
||||
}
|
||||
|
||||
WriteAsync(buffer, offset, count, default(CancellationToken)).GetAwaiter().GetResult();
|
||||
WriteAsync(buffer, offset, count, default).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
||||
{
|
||||
var task = WriteAsync(buffer, offset, count, default(CancellationToken), state);
|
||||
var task = WriteAsync(buffer, offset, count, default, state);
|
||||
if (callback != null)
|
||||
{
|
||||
task.ContinueWith(t => callback.Invoke(t));
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
try
|
||||
{
|
||||
if (!readableBuffer.IsEmpty)
|
||||
if (readableBufferLength != 0)
|
||||
{
|
||||
// buffer.Length is int
|
||||
actual = (int)Math.Min(readableBufferLength, buffer.Length);
|
||||
|
|
@ -69,8 +69,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
// Make sure we don't double-count bytes on the next read.
|
||||
_alreadyTimedBytes = readableBufferLength - actual;
|
||||
|
||||
var slice = readableBuffer.Slice(0, actual);
|
||||
consumed = readableBuffer.GetPosition(actual);
|
||||
var slice = actual == readableBufferLength ? readableBuffer : readableBuffer.Slice(0, actual);
|
||||
consumed = slice.End;
|
||||
slice.CopyTo(buffer.Span);
|
||||
|
||||
return actual;
|
||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
try
|
||||
{
|
||||
if (!readableBuffer.IsEmpty)
|
||||
if (readableBufferLength != 0)
|
||||
{
|
||||
foreach (var memory in readableBuffer)
|
||||
{
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue