Merge branch 'master' into merge/release/3.0-preview4-to-master
This commit is contained in:
commit
de39ededfa
|
|
@ -303,15 +303,10 @@ jobs:
|
||||||
displayName: Install SQL Server 2016 Express LocalDB
|
displayName: Install SQL Server 2016 Express LocalDB
|
||||||
- powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1"
|
- powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1"
|
||||||
displayName: Setup IISExpress test certificates and schema
|
displayName: Setup IISExpress test certificates and schema
|
||||||
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Setup signalrclienttests.exe"
|
|
||||||
displayName: Start AppVerifier
|
|
||||||
afterBuild:
|
afterBuild:
|
||||||
- powershell: "& ./build.ps1 -CI -NoBuild -Test /p:RunFlakyTests=true"
|
- powershell: "& ./build.ps1 -CI -NoBuild -Test /p:RunFlakyTests=true"
|
||||||
displayName: Run Flaky Tests
|
displayName: Run Flaky Tests
|
||||||
continueOnError: true
|
continueOnError: true
|
||||||
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Shutdown signalrclienttests.exe"
|
|
||||||
displayName: Stop AppVerifier
|
|
||||||
condition: always()
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- name: Windows_Test_Logs
|
- name: Windows_Test_Logs
|
||||||
path: artifacts/logs/
|
path: artifacts/logs/
|
||||||
|
|
|
||||||
|
|
@ -189,13 +189,21 @@ jobs:
|
||||||
buildConfiguration: $(BuildConfiguration)
|
buildConfiguration: $(BuildConfiguration)
|
||||||
buildPlatform: $(AgentOsName)
|
buildPlatform: $(AgentOsName)
|
||||||
- task: PublishTestResults@2
|
- task: PublishTestResults@2
|
||||||
displayName: Publish junit test results
|
displayName: Publish js test results
|
||||||
condition: always()
|
condition: always()
|
||||||
inputs:
|
inputs:
|
||||||
testRunner: junit
|
testRunner: junit
|
||||||
testResultsFiles: '**/artifacts/logs/**/*.junit.xml'
|
testResultsFiles: '**/artifacts/logs/**/*.junit.xml'
|
||||||
buildConfiguration: $(BuildConfiguration)
|
buildConfiguration: $(BuildConfiguration)
|
||||||
buildPlatform: $(AgentOsName)
|
buildPlatform: $(AgentOsName)
|
||||||
|
- task: PublishTestResults@2
|
||||||
|
displayName: Publish Java test results
|
||||||
|
condition: always()
|
||||||
|
inputs:
|
||||||
|
testRunner: junit
|
||||||
|
testResultsFiles: '**/TEST-com.microsoft.signalr*.xml'
|
||||||
|
buildConfiguration: $(BuildConfiguration)
|
||||||
|
buildPlatform: $(AgentOsName)
|
||||||
- ${{ each artifact in parameters.artifacts }}:
|
- ${{ each artifact in parameters.artifacts }}:
|
||||||
- task: PublishBuildArtifacts@1
|
- task: PublishBuildArtifacts@1
|
||||||
displayName: Upload artifacts from ${{ artifact.path }}
|
displayName: Upload artifacts from ${{ artifact.path }}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,4 @@ jobs:
|
||||||
agentOs: Windows
|
agentOs: Windows
|
||||||
jobName: SignalRDailyTests
|
jobName: SignalRDailyTests
|
||||||
jobDisplayName: "SignalR Daily Tests"
|
jobDisplayName: "SignalR Daily Tests"
|
||||||
beforeBuild:
|
|
||||||
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Setup signalrclienttests.exe"
|
|
||||||
displayName: Start AppVerifier
|
|
||||||
afterBuild:
|
|
||||||
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Shutdown signalrclienttests.exe"
|
|
||||||
displayName: Stop AppVerifier
|
|
||||||
condition: always()
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
# Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths.
|
# Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths.
|
||||||
# See https://help.github.com/articles/about-code-owners/
|
# See https://help.github.com/articles/about-code-owners/
|
||||||
|
|
||||||
/.azure/ @dougbu
|
/.azure/ @aspnet/build
|
||||||
/.config/ @dougbu
|
/.config/ @aspnet/build
|
||||||
/build/ @dougbu
|
/build/ @aspnet/build
|
||||||
/eng/ @dougbu
|
/eng/ @aspnet/build
|
||||||
/src/Components/ @SteveSandersonMS
|
/src/Components/ @SteveSandersonMS
|
||||||
/src/DefaultBuilder/ @tratcher @anurse
|
/src/DefaultBuilder/ @tratcher @anurse
|
||||||
/src/Hosting/ @tratcher @anurse
|
/src/Hosting/ @tratcher @anurse
|
||||||
/src/Http/ @tratcher @jkotalik @anurse
|
/src/Http/ @tratcher @jkotalik @anurse
|
||||||
/src/Middleware/ @tratcher @anurse
|
/src/Middleware/ @tratcher @anurse
|
||||||
/src/ProjectTemplates/ @ryanbrandenburg
|
/src/ProjectTemplates/ @ryanbrandenburg
|
||||||
/src/Security/ @tratcher @anurse
|
/src/Security/ @tratcher @anurse
|
||||||
/src/Servers/ @tratcher @jkotalik @anurse
|
/src/Servers/ @tratcher @jkotalik @anurse
|
||||||
/src/Middleware/Rewrite @jkotalik @anurse
|
/src/Middleware/Rewrite @jkotalik @anurse
|
||||||
/src/Middleware/HttpsPolicy @jkotalik @anurse
|
/src/Middleware/HttpsPolicy @jkotalik @anurse
|
||||||
/src/SignalR/ @mikaelm12 @BrennanConroy @halter73 @anurse
|
/src/SignalR/ @mikaelm12 @BrennanConroy @halter73 @anurse
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,6 @@
|
||||||
$(RepositoryRoot)src\Tools\dotnet-watch\test\TestProjects\**\*.csproj;
|
$(RepositoryRoot)src\Tools\dotnet-watch\test\TestProjects\**\*.csproj;
|
||||||
$(RepositoryRoot)src\Razor\Razor.Design\test\testassets\**\*.*proj;
|
$(RepositoryRoot)src\Razor\Razor.Design\test\testassets\**\*.*proj;
|
||||||
$(RepositoryRoot)src\submodules\**\*.*proj;
|
$(RepositoryRoot)src\submodules\**\*.*proj;
|
||||||
$(RepositoryRoot)src\SignalR\clients\cpp\samples\**\*.*proj;
|
|
||||||
$(RepositoryRoot)src\SignalR\clients\cpp\test\signalrclient-testhost\**\*.*proj;
|
|
||||||
$(RepositoryRoot)src\Installers\**\*.*proj;
|
$(RepositoryRoot)src\Installers\**\*.*proj;
|
||||||
$(RepositoryRoot)src\SignalR\clients\ts\**\node_modules\**\*.*proj;
|
$(RepositoryRoot)src\SignalR\clients\ts\**\node_modules\**\*.*proj;
|
||||||
$(RepositoryRoot)src\Components\Blazor\Templates\src\content\**\*.*proj;
|
$(RepositoryRoot)src\Components\Blazor\Templates\src\content\**\*.*proj;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||||
https://dotnet.myget.org/F/blazor-dev/api/v3/index.json;
|
https://dotnet.myget.org/F/blazor-dev/api/v3/index.json;
|
||||||
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
|
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
|
||||||
|
https://dotnet.myget.org/F/nuget-build/api/v3/index.json;
|
||||||
https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json;
|
https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json;
|
||||||
https://dotnet.myget.org/F/roslyn/api/v3/index.json;
|
https://dotnet.myget.org/F/roslyn/api/v3/index.json;
|
||||||
https://vside.myget.org/F/devcore/api/v3/index.json;
|
https://vside.myget.org/F/devcore/api/v3/index.json;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Remove="Internal.AspNetCore.Sdk" />
|
<PackageReference Remove="Internal.AspNetCore.Sdk" />
|
||||||
<PackageReference Include="NuGet.Build.Tasks" Version="4.9.3" />
|
<PackageReference Include="NuGet.Build.Tasks" Version="5.1.0-rtm.5921" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.1.0" />
|
||||||
<PackageReference Include="Yarn.MSBuild" Version="1.13.0" />
|
<PackageReference Include="Yarn.MSBuild" Version="1.13.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,8 @@ Building ASP.NET Core on Windows requires:
|
||||||
PS> ./eng/scripts/InstallVisualStudio.ps1
|
PS> ./eng/scripts/InstallVisualStudio.ps1
|
||||||
```
|
```
|
||||||
* Git. <https://git-scm.org>
|
* Git. <https://git-scm.org>
|
||||||
* (Optional) some optional components, like the SignalR Java client, may require
|
* NodeJS. LTS version of 10.14.2 or newer <https://nodejs.org>
|
||||||
* NodeJS. LTS version of 10.14.2 or newer recommended <https://nodejs.org>
|
* Java Development Kit (JDK) v8 with Java Runtime Environment (JRE) v8. See https://www.oracle.com/technetwork/java/javase/downloads/index.html
|
||||||
* Java Development Kit (JDK) v8 with Java Runtime Environment (JRE) v8. See https://www.oracle.com/technetwork/java/javase/downloads/index.html
|
|
||||||
|
|
||||||
### macOS/Linux
|
### macOS/Linux
|
||||||
|
|
||||||
|
|
@ -31,11 +30,10 @@ Building ASP.NET Core on macOS or Linux requires:
|
||||||
* If using Linux, you need a machine with all .NET Core Linux prerequisites: <https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites>
|
* If using Linux, you need a machine with all .NET Core Linux prerequisites: <https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites>
|
||||||
* At least 10 GB of disk space and a good internet connection (our build scripts download a lot of tools and dependencies)
|
* At least 10 GB of disk space and a good internet connection (our build scripts download a lot of tools and dependencies)
|
||||||
* Git <https://git-scm.org>
|
* Git <https://git-scm.org>
|
||||||
* (Optional) some optional components, like the SignalR Java client, may require
|
* NodeJS. LTS version of 10.14.2 or newer <https://nodejs.org>
|
||||||
* NodeJS. LTS version of 10.14.2 or newer recommended <https://nodejs.org>
|
* Java Development Kit 10 or newer. Either:
|
||||||
* Java Development Kit 10 or newer. Either:
|
* OpenJDK <http://jdk.java.net/10/>
|
||||||
* OpenJDK <http://jdk.java.net/10/>
|
* Oracle's JDK <https://www.oracle.com/technetwork/java/javase/downloads/index.html>
|
||||||
* Oracle's JDK <https://www.oracle.com/technetwork/java/javase/downloads/index.html>
|
|
||||||
|
|
||||||
## Clone the source code
|
## Clone the source code
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ If you want to download the latest daily build and use it in a project, then you
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<clear />
|
<clear />
|
||||||
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
|
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
|
||||||
|
<add key="extensions" value="https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json" />
|
||||||
|
<add key="entityframeworkcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-entityframeworkcore/index.json" />
|
||||||
|
<add key="aspnetcore-tooling" value="https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore-tooling/index.json" />
|
||||||
|
<add key="aspnetcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore/index.json" />
|
||||||
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
|
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
||||||
|
|
@ -9,384 +9,384 @@
|
||||||
-->
|
-->
|
||||||
<Dependencies>
|
<Dependencies>
|
||||||
<ProductDependencies>
|
<ProductDependencies>
|
||||||
<Dependency Name="Microsoft.AspNetCore.Razor.Language" Version="3.0.0-preview4.19210.8">
|
<Dependency Name="Microsoft.AspNetCore.Razor.Language" Version="3.0.0-preview5.19210.2">
|
||||||
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
||||||
<Sha>1bb6a910e854d806c445cd981b8ef665250373a5</Sha>
|
<Sha>290f4850d326ab8699fec33e2cf6268bd61d67b3</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="3.0.0-preview4.19210.8">
|
<Dependency Name="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="3.0.0-preview5.19210.2">
|
||||||
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
||||||
<Sha>1bb6a910e854d806c445cd981b8ef665250373a5</Sha>
|
<Sha>290f4850d326ab8699fec33e2cf6268bd61d67b3</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.CodeAnalysis.Razor" Version="3.0.0-preview4.19210.8">
|
<Dependency Name="Microsoft.CodeAnalysis.Razor" Version="3.0.0-preview5.19210.2">
|
||||||
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
||||||
<Sha>1bb6a910e854d806c445cd981b8ef665250373a5</Sha>
|
<Sha>290f4850d326ab8699fec33e2cf6268bd61d67b3</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.NET.Sdk.Razor" Version="3.0.0-preview4.19210.8">
|
<Dependency Name="Microsoft.NET.Sdk.Razor" Version="3.0.0-preview5.19210.2">
|
||||||
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
<Uri>https://github.com/aspnet/AspNetCore-Tooling</Uri>
|
||||||
<Sha>1bb6a910e854d806c445cd981b8ef665250373a5</Sha>
|
<Sha>290f4850d326ab8699fec33e2cf6268bd61d67b3</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="dotnet-ef" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="dotnet-ef" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.EntityFrameworkCore" Version="3.0.0-preview4.19210.5">
|
<Dependency Name="Microsoft.EntityFrameworkCore" Version="3.0.0-preview5.19210.7">
|
||||||
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
<Uri>https://github.com/aspnet/EntityFrameworkCore</Uri>
|
||||||
<Sha>9bbef00839d4724ce31021dd7eabf91f388f138e</Sha>
|
<Sha>dbf9f7cbc2a119dbb14fc8beb21bd8ed41927922</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.AspNetCore.Analyzer.Testing" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.AspNetCore.Analyzer.Testing" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.ActivatorUtilities.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.ActivatorUtilities.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Caching.SqlServer" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Caching.SqlServer" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.CommandLineUtils.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.CommandLineUtils.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.KeyPerFile" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.KeyPerFile" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Configuration" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Configuration" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.DiagnosticAdapter" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.DiagnosticAdapter" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Diagnostics.HealthChecks" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.HashCodeCombiner.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.HashCodeCombiner.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Hosting" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Hosting" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.HostFactoryResolver.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Http" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Http" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Localization.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Localization.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Localization" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Localization" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.AzureAppServices" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.AzureAppServices" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging.Testing" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging.Testing" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Logging" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Logging" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.ObjectPool" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.ObjectPool" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Options" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Options" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.ParameterDefaultValue.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.ParameterDefaultValue.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.Primitives" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.Primitives" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.TypeNameHelper.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.TypeNameHelper.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.ValueStopwatch.Sources" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.ValueStopwatch.Sources" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.WebEncoders" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Extensions.WebEncoders" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Internal.Extensions.Refs" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.Internal.Extensions.Refs" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.JSInterop" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.JSInterop" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Mono.WebAssembly.Interop" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Mono.WebAssembly.Interop" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Bcl.Json.Sources" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="Microsoft.Bcl.Json.Sources" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.CSharp" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="Microsoft.CSharp" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Win32.Registry" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="Microsoft.Win32.Registry" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.ComponentModel.Annotations" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.ComponentModel.Annotations" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Data.SqlClient" Version="4.7.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Data.SqlClient" Version="4.7.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Diagnostics.EventLog" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Diagnostics.EventLog" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.IO.Pipelines" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.IO.Pipelines" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Net.Http.WinHttpHandler" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Net.Http.WinHttpHandler" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Reflection.Metadata" Version="1.7.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Reflection.Metadata" Version="1.7.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Security.Cryptography.Cng" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Security.Cryptography.Cng" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Security.Cryptography.Pkcs" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Security.Cryptography.Pkcs" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Security.Cryptography.Xml" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Security.Cryptography.Xml" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Security.Permissions" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Security.Permissions" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Security.Principal.Windows" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Security.Principal.Windows" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.ServiceProcess.ServiceController" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.ServiceProcess.ServiceController" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Text.Encodings.Web" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Text.Encodings.Web" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="System.Threading.Channels" Version="4.6.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="System.Threading.Channels" Version="4.6.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="3.0.0-preview4-27610-06" CoherentParentDependency="Microsoft.Extensions.Logging">
|
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="3.0.0-preview5-27608-16" CoherentParentDependency="Microsoft.Extensions.Logging">
|
||||||
<Uri>https://github.com/dotnet/core-setup</Uri>
|
<Uri>https://github.com/dotnet/core-setup</Uri>
|
||||||
<Sha>38eae75ec209bb6aa7df29871164dbbf249e1465</Sha>
|
<Sha>59c193bd93deafba5926cb827872b80338aca7c0</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.NETCore.App" Version="3.0.0-preview4-27610-06" CoherentParentDependency="Microsoft.Extensions.Logging">
|
<Dependency Name="Microsoft.NETCore.App" Version="3.0.0-preview5-27608-16" CoherentParentDependency="Microsoft.Extensions.Logging">
|
||||||
<Uri>https://github.com/dotnet/core-setup</Uri>
|
<Uri>https://github.com/dotnet/core-setup</Uri>
|
||||||
<Sha>38eae75ec209bb6aa7df29871164dbbf249e1465</Sha>
|
<Sha>59c193bd93deafba5926cb827872b80338aca7c0</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
</ProductDependencies>
|
</ProductDependencies>
|
||||||
<ToolsetDependencies>
|
<ToolsetDependencies>
|
||||||
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
||||||
<Dependency Name="Microsoft.NETCore.Platforms" Version="3.0.0-preview4.19208.6" CoherentParentDependency="Microsoft.NETCore.App">
|
<Dependency Name="Microsoft.NETCore.Platforms" Version="3.0.0-preview5.19208.5" CoherentParentDependency="Microsoft.NETCore.App">
|
||||||
<Uri>https://github.com/dotnet/corefx</Uri>
|
<Uri>https://github.com/dotnet/corefx</Uri>
|
||||||
<Sha>e0a01a12c2676d69cefa61aa2526a414d7f2dabb</Sha>
|
<Sha>6ca16758a5d454c1f1b04975bf55f259dd71fc49</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Internal.AspNetCore.Analyzers" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Internal.AspNetCore.Analyzers" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19207.1">
|
<Dependency Name="Microsoft.DotNet.GenAPI" Version="1.0.0-beta.19210.7">
|
||||||
<Uri>https://github.com/dotnet/arcade</Uri>
|
<Uri>https://github.com/dotnet/arcade</Uri>
|
||||||
<Sha>b1f9e12fe3ee71c48ea60b15968745850ac0a4a7</Sha>
|
<Sha>4f645e4a5385eb96cad3f72f5ded239761c7d075</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
<Dependency Name="Microsoft.AspNetCore.Testing" Version="3.0.0-preview4.19210.5" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
<Dependency Name="Microsoft.AspNetCore.Testing" Version="3.0.0-preview5.19210.2" CoherentParentDependency="Microsoft.EntityFrameworkCore">
|
||||||
<Uri>https://github.com/aspnet/Extensions</Uri>
|
<Uri>https://github.com/aspnet/Extensions</Uri>
|
||||||
<Sha>f5af65902e4e453dd9871ae61c6c61ed3c61730f</Sha>
|
<Sha>17cb5265d011311233c2795727532d5c8eb22b5f</Sha>
|
||||||
</Dependency>
|
</Dependency>
|
||||||
</ToolsetDependencies>
|
</ToolsetDependencies>
|
||||||
</Dependencies>
|
</Dependencies>
|
||||||
|
|
|
||||||
|
|
@ -17,106 +17,106 @@
|
||||||
-->
|
-->
|
||||||
<PropertyGroup Label="Automated">
|
<PropertyGroup Label="Automated">
|
||||||
<!-- Packages from dotnet/arcade -->
|
<!-- Packages from dotnet/arcade -->
|
||||||
<MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19207.1</MicrosoftDotNetGenAPIPackageVersion>
|
<MicrosoftDotNetGenAPIPackageVersion>1.0.0-beta.19210.7</MicrosoftDotNetGenAPIPackageVersion>
|
||||||
<!-- Packages from dotnet/core-setup -->
|
<!-- Packages from dotnet/core-setup -->
|
||||||
<MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview4-27610-06</MicrosoftExtensionsDependencyModelPackageVersion>
|
<MicrosoftExtensionsDependencyModelPackageVersion>3.0.0-preview5-27608-16</MicrosoftExtensionsDependencyModelPackageVersion>
|
||||||
<MicrosoftNETCoreAppPackageVersion>3.0.0-preview4-27610-06</MicrosoftNETCoreAppPackageVersion>
|
<MicrosoftNETCoreAppPackageVersion>3.0.0-preview5-27608-16</MicrosoftNETCoreAppPackageVersion>
|
||||||
<!-- Packages from dotnet/corefx -->
|
<!-- Packages from dotnet/corefx -->
|
||||||
<MicrosoftBclJsonSourcesPackageVersion>4.6.0-preview4.19208.6</MicrosoftBclJsonSourcesPackageVersion>
|
<MicrosoftBclJsonSourcesPackageVersion>4.6.0-preview5.19208.5</MicrosoftBclJsonSourcesPackageVersion>
|
||||||
<MicrosoftCSharpPackageVersion>4.6.0-preview4.19208.6</MicrosoftCSharpPackageVersion>
|
<MicrosoftCSharpPackageVersion>4.6.0-preview5.19208.5</MicrosoftCSharpPackageVersion>
|
||||||
<MicrosoftWin32RegistryPackageVersion>4.6.0-preview4.19208.6</MicrosoftWin32RegistryPackageVersion>
|
<MicrosoftWin32RegistryPackageVersion>4.6.0-preview5.19208.5</MicrosoftWin32RegistryPackageVersion>
|
||||||
<SystemComponentModelAnnotationsPackageVersion>4.6.0-preview4.19208.6</SystemComponentModelAnnotationsPackageVersion>
|
<SystemComponentModelAnnotationsPackageVersion>4.6.0-preview5.19208.5</SystemComponentModelAnnotationsPackageVersion>
|
||||||
<SystemDataSqlClientPackageVersion>4.7.0-preview4.19208.6</SystemDataSqlClientPackageVersion>
|
<SystemDataSqlClientPackageVersion>4.7.0-preview5.19208.5</SystemDataSqlClientPackageVersion>
|
||||||
<SystemDiagnosticsEventLogPackageVersion>4.6.0-preview4.19208.6</SystemDiagnosticsEventLogPackageVersion>
|
<SystemDiagnosticsEventLogPackageVersion>4.6.0-preview5.19208.5</SystemDiagnosticsEventLogPackageVersion>
|
||||||
<SystemIOPipelinesPackageVersion>4.6.0-preview4.19208.6</SystemIOPipelinesPackageVersion>
|
<SystemIOPipelinesPackageVersion>4.6.0-preview5.19208.5</SystemIOPipelinesPackageVersion>
|
||||||
<SystemNetHttpWinHttpHandlerPackageVersion>4.6.0-preview4.19208.6</SystemNetHttpWinHttpHandlerPackageVersion>
|
<SystemNetHttpWinHttpHandlerPackageVersion>4.6.0-preview5.19208.5</SystemNetHttpWinHttpHandlerPackageVersion>
|
||||||
<SystemNetWebSocketsWebSocketProtocolPackageVersion>4.6.0-preview4.19208.6</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
<SystemNetWebSocketsWebSocketProtocolPackageVersion>4.6.0-preview5.19208.5</SystemNetWebSocketsWebSocketProtocolPackageVersion>
|
||||||
<SystemReflectionMetadataPackageVersion>1.7.0-preview4.19208.6</SystemReflectionMetadataPackageVersion>
|
<SystemReflectionMetadataPackageVersion>1.7.0-preview5.19208.5</SystemReflectionMetadataPackageVersion>
|
||||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.6.0-preview4.19208.6</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.6.0-preview5.19208.5</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||||
<SystemSecurityCryptographyCngPackageVersion>4.6.0-preview4.19208.6</SystemSecurityCryptographyCngPackageVersion>
|
<SystemSecurityCryptographyCngPackageVersion>4.6.0-preview5.19208.5</SystemSecurityCryptographyCngPackageVersion>
|
||||||
<SystemSecurityCryptographyPkcsPackageVersion>4.6.0-preview4.19208.6</SystemSecurityCryptographyPkcsPackageVersion>
|
<SystemSecurityCryptographyPkcsPackageVersion>4.6.0-preview5.19208.5</SystemSecurityCryptographyPkcsPackageVersion>
|
||||||
<SystemSecurityCryptographyXmlPackageVersion>4.6.0-preview4.19208.6</SystemSecurityCryptographyXmlPackageVersion>
|
<SystemSecurityCryptographyXmlPackageVersion>4.6.0-preview5.19208.5</SystemSecurityCryptographyXmlPackageVersion>
|
||||||
<SystemSecurityPermissionsPackageVersion>4.6.0-preview4.19208.6</SystemSecurityPermissionsPackageVersion>
|
<SystemSecurityPermissionsPackageVersion>4.6.0-preview5.19208.5</SystemSecurityPermissionsPackageVersion>
|
||||||
<SystemSecurityPrincipalWindowsPackageVersion>4.6.0-preview4.19208.6</SystemSecurityPrincipalWindowsPackageVersion>
|
<SystemSecurityPrincipalWindowsPackageVersion>4.6.0-preview5.19208.5</SystemSecurityPrincipalWindowsPackageVersion>
|
||||||
<SystemServiceProcessServiceControllerPackageVersion>4.6.0-preview4.19208.6</SystemServiceProcessServiceControllerPackageVersion>
|
<SystemServiceProcessServiceControllerPackageVersion>4.6.0-preview5.19208.5</SystemServiceProcessServiceControllerPackageVersion>
|
||||||
<SystemTextEncodingsWebPackageVersion>4.6.0-preview4.19208.6</SystemTextEncodingsWebPackageVersion>
|
<SystemTextEncodingsWebPackageVersion>4.6.0-preview5.19208.5</SystemTextEncodingsWebPackageVersion>
|
||||||
<SystemThreadingChannelsPackageVersion>4.6.0-preview4.19208.6</SystemThreadingChannelsPackageVersion>
|
<SystemThreadingChannelsPackageVersion>4.6.0-preview5.19208.5</SystemThreadingChannelsPackageVersion>
|
||||||
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
|
||||||
<MicrosoftNETCorePlatformsPackageVersion>3.0.0-preview4.19208.6</MicrosoftNETCorePlatformsPackageVersion>
|
<MicrosoftNETCorePlatformsPackageVersion>3.0.0-preview5.19208.5</MicrosoftNETCorePlatformsPackageVersion>
|
||||||
<!-- Packages from aspnet/Extensions -->
|
<!-- Packages from aspnet/Extensions -->
|
||||||
<InternalAspNetCoreAnalyzersPackageVersion>3.0.0-preview4.19210.5</InternalAspNetCoreAnalyzersPackageVersion>
|
<InternalAspNetCoreAnalyzersPackageVersion>3.0.0-preview5.19210.2</InternalAspNetCoreAnalyzersPackageVersion>
|
||||||
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-preview4.19210.5</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
|
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>3.0.0-preview5.19210.2</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
|
||||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||||
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview4.19210.5</MicrosoftAspNetCoreTestingPackageVersion>
|
<MicrosoftAspNetCoreTestingPackageVersion>3.0.0-preview5.19210.2</MicrosoftAspNetCoreTestingPackageVersion>
|
||||||
<MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>
|
<MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsActivatorUtilitiesSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsCachingAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
<MicrosoftExtensionsCachingAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsCachingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsCachingMemoryPackageVersion>
|
<MicrosoftExtensionsCachingMemoryPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsCachingMemoryPackageVersion>
|
||||||
<MicrosoftExtensionsCachingSqlServerPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsCachingSqlServerPackageVersion>
|
<MicrosoftExtensionsCachingSqlServerPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsCachingSqlServerPackageVersion>
|
||||||
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
|
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
|
||||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>
|
<MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationAzureKeyVaultPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
<MicrosoftExtensionsConfigurationBinderPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationIniPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationIniPackageVersion>
|
<MicrosoftExtensionsConfigurationIniPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationIniPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
<MicrosoftExtensionsConfigurationJsonPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>
|
<MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationKeyPerFilePackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationPackageVersion>
|
<MicrosoftExtensionsConfigurationPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||||
<MicrosoftExtensionsConfigurationXmlPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
<MicrosoftExtensionsConfigurationXmlPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsConfigurationXmlPackageVersion>
|
||||||
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
<MicrosoftExtensionsDependencyInjectionPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||||
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
|
||||||
<MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>
|
<MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsDiagnosticsHealthChecksAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>
|
<MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsDiagnosticsHealthChecksPackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
<MicrosoftExtensionsFileProvidersCompositePackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsFileProvidersCompositePackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
|
||||||
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
|
||||||
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
|
||||||
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
<MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsHashCodeCombinerSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsHostingAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
<MicrosoftExtensionsHostingAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsHostingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsHostingPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsHostingPackageVersion>
|
<MicrosoftExtensionsHostingPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsHostingPackageVersion>
|
||||||
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
<MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsHostFactoryResolverSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsHttpPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsHttpPackageVersion>
|
<MicrosoftExtensionsHttpPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsHttpPackageVersion>
|
||||||
<MicrosoftExtensionsLocalizationAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLocalizationAbstractionsPackageVersion>
|
<MicrosoftExtensionsLocalizationAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLocalizationAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsLocalizationPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLocalizationPackageVersion>
|
<MicrosoftExtensionsLocalizationPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLocalizationPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>
|
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingConfigurationPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
<MicrosoftExtensionsLoggingConfigurationPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingConfigurationPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingConsolePackageVersion>
|
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingConsolePackageVersion>
|
||||||
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingDebugPackageVersion>
|
<MicrosoftExtensionsLoggingDebugPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingDebugPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingEventSourcePackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
<MicrosoftExtensionsLoggingEventSourcePackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingEventSourcePackageVersion>
|
||||||
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingPackageVersion>
|
<MicrosoftExtensionsLoggingPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingTestingPackageVersion>
|
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||||
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
|
||||||
<MicrosoftExtensionsObjectPoolPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsObjectPoolPackageVersion>
|
<MicrosoftExtensionsObjectPoolPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsObjectPoolPackageVersion>
|
||||||
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
|
||||||
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
|
||||||
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsOptionsPackageVersion>
|
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsOptionsPackageVersion>
|
||||||
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
|
<MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsParameterDefaultValueSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsPrimitivesPackageVersion>
|
<MicrosoftExtensionsPrimitivesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsPrimitivesPackageVersion>
|
||||||
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
<MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsTypeNameHelperSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
<MicrosoftExtensionsValueStopwatchSourcesPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsValueStopwatchSourcesPackageVersion>
|
||||||
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-preview4.19210.5</MicrosoftExtensionsWebEncodersPackageVersion>
|
<MicrosoftExtensionsWebEncodersPackageVersion>3.0.0-preview5.19210.2</MicrosoftExtensionsWebEncodersPackageVersion>
|
||||||
<MicrosoftInternalExtensionsRefsPackageVersion>3.0.0-preview4.19210.5</MicrosoftInternalExtensionsRefsPackageVersion>
|
<MicrosoftInternalExtensionsRefsPackageVersion>3.0.0-preview5.19210.2</MicrosoftInternalExtensionsRefsPackageVersion>
|
||||||
<MicrosoftJSInteropPackageVersion>3.0.0-preview4.19210.5</MicrosoftJSInteropPackageVersion>
|
<MicrosoftJSInteropPackageVersion>3.0.0-preview5.19210.2</MicrosoftJSInteropPackageVersion>
|
||||||
<MonoWebAssemblyInteropPackageVersion>3.0.0-preview4.19210.5</MonoWebAssemblyInteropPackageVersion>
|
<MonoWebAssemblyInteropPackageVersion>3.0.0-preview5.19210.2</MonoWebAssemblyInteropPackageVersion>
|
||||||
<!-- Packages from aspnet/EntityFrameworkCore -->
|
<!-- Packages from aspnet/EntityFrameworkCore -->
|
||||||
<dotnetefPackageVersion>3.0.0-preview4.19210.5</dotnetefPackageVersion>
|
<dotnetefPackageVersion>3.0.0-preview5.19210.7</dotnetefPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>3.0.0-preview4.19210.5</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>3.0.0-preview5.19210.7</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>3.0.0-preview4.19210.5</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>3.0.0-preview5.19210.7</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>3.0.0-preview4.19210.5</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>3.0.0-preview5.19210.7</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>3.0.0-preview4.19210.5</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>3.0.0-preview5.19210.7</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCoreToolsPackageVersion>3.0.0-preview4.19210.5</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
<MicrosoftEntityFrameworkCoreToolsPackageVersion>3.0.0-preview5.19210.7</MicrosoftEntityFrameworkCoreToolsPackageVersion>
|
||||||
<MicrosoftEntityFrameworkCorePackageVersion>3.0.0-preview4.19210.5</MicrosoftEntityFrameworkCorePackageVersion>
|
<MicrosoftEntityFrameworkCorePackageVersion>3.0.0-preview5.19210.7</MicrosoftEntityFrameworkCorePackageVersion>
|
||||||
<!-- Packages from aspnet/AspNetCore-Tooling -->
|
<!-- Packages from aspnet/AspNetCore-Tooling -->
|
||||||
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-preview4.19210.8</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
|
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>3.0.0-preview5.19210.2</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
|
||||||
<MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-preview4.19210.8</MicrosoftAspNetCoreRazorLanguagePackageVersion>
|
<MicrosoftAspNetCoreRazorLanguagePackageVersion>3.0.0-preview5.19210.2</MicrosoftAspNetCoreRazorLanguagePackageVersion>
|
||||||
<MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-preview4.19210.8</MicrosoftCodeAnalysisRazorPackageVersion>
|
<MicrosoftCodeAnalysisRazorPackageVersion>3.0.0-preview5.19210.2</MicrosoftCodeAnalysisRazorPackageVersion>
|
||||||
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview4.19210.8</MicrosoftNETSdkRazorPackageVersion>
|
<MicrosoftNETSdkRazorPackageVersion>3.0.0-preview5.19210.2</MicrosoftNETSdkRazorPackageVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "3.0.100-preview4-010309"
|
"version": "3.0.100-preview4-011136"
|
||||||
},
|
},
|
||||||
"msbuild-sdks": {
|
"msbuild-sdks": {
|
||||||
"Yarn.MSBuild": "1.13.0"
|
"Yarn.MSBuild": "1.13.0"
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
version:3.0.0-build-20190322.1
|
version:3.0.0-build-20190408.1
|
||||||
commithash:c38761a564c72b5bc96356ec99c89de5f281a358
|
commithash:8b533cbfa5357e5785f4c4231231c1234cfc2c5f
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,10 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
{
|
{
|
||||||
host.Initialize();
|
host.Initialize();
|
||||||
|
|
||||||
|
// resolve configuration explicitly once to mark it as resolved within the
|
||||||
|
// service provider, ensuring it will be properly disposed with the provider
|
||||||
|
_ = host.Services.GetService<IConfiguration>();
|
||||||
|
|
||||||
var logger = host.Services.GetRequiredService<ILogger<WebHost>>();
|
var logger = host.Services.GetRequiredService<ILogger<WebHost>>();
|
||||||
|
|
||||||
// Warn about duplicate HostingStartupAssemblies
|
// Warn about duplicate HostingStartupAssemblies
|
||||||
|
|
@ -264,12 +268,13 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
|
|
||||||
var builder = new ConfigurationBuilder()
|
var builder = new ConfigurationBuilder()
|
||||||
.SetBasePath(_hostingEnvironment.ContentRootPath)
|
.SetBasePath(_hostingEnvironment.ContentRootPath)
|
||||||
.AddConfiguration(_config);
|
.AddConfiguration(_config, shouldDisposeConfiguration: true);
|
||||||
|
|
||||||
_configureAppConfigurationBuilder?.Invoke(_context, builder);
|
_configureAppConfigurationBuilder?.Invoke(_context, builder);
|
||||||
|
|
||||||
var configuration = builder.Build();
|
var configuration = builder.Build();
|
||||||
services.AddSingleton<IConfiguration>(configuration);
|
// register configuration as factory to make it dispose with the service provider
|
||||||
|
services.AddSingleton<IConfiguration>(_ => configuration);
|
||||||
_context.Configuration = configuration;
|
_context.Configuration = configuration;
|
||||||
|
|
||||||
var listener = new DiagnosticListener("Microsoft.AspNetCore");
|
var listener = new DiagnosticListener("Microsoft.AspNetCore");
|
||||||
|
|
|
||||||
|
|
@ -975,6 +975,54 @@ namespace Microsoft.AspNetCore.Hosting
|
||||||
Assert.Contains("ConfigureServices", ex.Message);
|
Assert.Contains("ConfigureServices", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Dispose_DisposesAppConfiguration()
|
||||||
|
{
|
||||||
|
var providerMock = new Mock<ConfigurationProvider>().As<IDisposable>();
|
||||||
|
providerMock.Setup(d => d.Dispose());
|
||||||
|
|
||||||
|
var sourceMock = new Mock<IConfigurationSource>();
|
||||||
|
sourceMock.Setup(s => s.Build(It.IsAny<IConfigurationBuilder>()))
|
||||||
|
.Returns((ConfigurationProvider)providerMock.Object);
|
||||||
|
|
||||||
|
var host = CreateBuilder()
|
||||||
|
.ConfigureAppConfiguration(configuration =>
|
||||||
|
{
|
||||||
|
configuration.Add(sourceMock.Object);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
providerMock.Verify(c => c.Dispose(), Times.Never);
|
||||||
|
|
||||||
|
host.Dispose();
|
||||||
|
|
||||||
|
providerMock.Verify(c => c.Dispose(), Times.AtLeastOnce());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task DisposeAsync_DisposesAppConfiguration()
|
||||||
|
{
|
||||||
|
var providerMock = new Mock<ConfigurationProvider>().As<IDisposable>();
|
||||||
|
providerMock.Setup(d => d.Dispose());
|
||||||
|
|
||||||
|
var sourceMock = new Mock<IConfigurationSource>();
|
||||||
|
sourceMock.Setup(s => s.Build(It.IsAny<IConfigurationBuilder>()))
|
||||||
|
.Returns((ConfigurationProvider)providerMock.Object);
|
||||||
|
|
||||||
|
var host = CreateBuilder()
|
||||||
|
.ConfigureAppConfiguration(configuration =>
|
||||||
|
{
|
||||||
|
configuration.Add(sourceMock.Object);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
providerMock.Verify(c => c.Dispose(), Times.Never);
|
||||||
|
|
||||||
|
await ((IAsyncDisposable)host).DisposeAsync();
|
||||||
|
|
||||||
|
providerMock.Verify(c => c.Dispose(), Times.AtLeastOnce());
|
||||||
|
}
|
||||||
|
|
||||||
public class BadConfigureServicesStartup
|
public class BadConfigureServicesStartup
|
||||||
{
|
{
|
||||||
public void ConfigureServices(IServiceCollection services, int gunk) { }
|
public void ConfigureServices(IServiceCollection services, int gunk) { }
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
<SuppressIces>ICE03</SuppressIces>
|
<SuppressIces>ICE03</SuppressIces>
|
||||||
<DisableGuidGeneration>true</DisableGuidGeneration>
|
<DisableGuidGeneration>true</DisableGuidGeneration>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<TempPlatform Condition="'$(Platform)' == 'x64'">x64</TempPlatform>
|
||||||
|
<TempPlatform Condition="'$(Platform)' == 'x86'">Win32</TempPlatform>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -51,6 +53,15 @@
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="CopyBuildOutputToArtifactDirectory"
|
||||||
|
Condition=" '$(IsProductInstaller)' == 'true' "
|
||||||
|
AfterTargets="Build">
|
||||||
|
<ItemGroup>
|
||||||
|
<BuildContentForAncm Include="$(RepositoryRoot)src\Servers\IIS\AspNetCoreModuleV2\AspNetCore\bin\$(Configuration)\$(TempPlatform)\*.*" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Copy SourceFiles="@(BuildContentForAncm)" DestinationFolder="$(InstallersOutputPath)\IISExpressSymbols\$(TempPlatform)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" />
|
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" />
|
||||||
<Import Project="..\build\settings.props" />
|
<Import Project="..\build\settings.props" />
|
||||||
<Import Project="..\build\versions.props" />
|
<Import Project="..\build\versions.props" />
|
||||||
|
|
|
||||||
|
|
@ -366,66 +366,25 @@
|
||||||
Value=""[IISEXPRESS_INSTALL_PATH]appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[\[]mimeType='text/event-stream',enabled='FALSE'[\]]" /apphostconfig:"[IISEXPRESS_APPHOST_CONFIG_TMP]""/>
|
Value=""[IISEXPRESS_INSTALL_PATH]appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[\[]mimeType='text/event-stream',enabled='FALSE'[\]]" /apphostconfig:"[IISEXPRESS_APPHOST_CONFIG_TMP]""/>
|
||||||
<CustomAction Id="CA_UPDATE_DYNAMIC_COMPRESSION_TMP" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
<CustomAction Id="CA_UPDATE_DYNAMIC_COMPRESSION_TMP" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||||
|
|
||||||
<!-- CA to add config section to applicationhost.config -->
|
|
||||||
<CustomAction Id="CA_ADD_CONFIGSECTION_PROPERTY"
|
<CustomAction Id="CA_ADD_CONFIGSECTION_PROPERTY"
|
||||||
Property="CA_ADD_CONFIGSECTION"
|
Property="CA_ADD_CONFIGSECTION"
|
||||||
Value="[IISEXPRESS_APPHOST_CONFIG];[IISEXPRESS_APPHOST_CONFIG_TMP]"/>
|
Value="[IISEXPRESS_APPHOST_CONFIG]"/>
|
||||||
<CustomAction Id="CA_ADD_CONFIGSECTION" Script="jscript" Execute="deferred" Return="check" Impersonate="no">
|
<CustomAction BinaryKey="IISCustomActionDll" Id="CA_ADD_CONFIGSECTION" DllEntry="AddConfigSection" Execute="deferred" Return="check" Impersonate="no"/>
|
||||||
<![CDATA[
|
|
||||||
var caData = Session.Property("CustomActionData");
|
<CustomAction Id="CA_ADD_CONFIGSECTION_PROPERTY_TMP"
|
||||||
configfiles = caData.split(';');
|
Property="CA_ADD_CONFIGSECTION_TMP"
|
||||||
for (var i = 0; i < configfiles.length; i++) {
|
Value="[IISEXPRESS_APPHOST_CONFIG_TMP]"/>
|
||||||
var configfile = configfiles[i];
|
<CustomAction BinaryKey="IISCustomActionDll" Id="CA_ADD_CONFIGSECTION_TMP" DllEntry="AddConfigSection" Execute="deferred" Return="check" Impersonate="no"/>
|
||||||
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
|
|
||||||
xmlDoc.async = false;
|
|
||||||
xmlDoc.preserveWhiteSpace = true;
|
|
||||||
xmlDoc.load(configfile );
|
|
||||||
if (xmlDoc.parseError.errorCode == 0) {
|
|
||||||
xmlDoc.setProperty("SelectionLanguage", "XPath");
|
|
||||||
var websvrNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]");
|
|
||||||
if (websvrNode != null) {
|
|
||||||
var ancmNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"$(var.AspNetCoreSectionName)\"]");
|
|
||||||
if (ancmNode == null) {
|
|
||||||
ancmNode = xmlDoc.createElement("section");
|
|
||||||
ancmNode.setAttribute("name", "$(var.AspNetCoreSectionName)");
|
|
||||||
ancmNode.setAttribute("overrideModeDefault", "Allow");
|
|
||||||
websvrNode.appendChild(ancmNode);
|
|
||||||
xmlDoc.save(configfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</CustomAction>
|
|
||||||
|
|
||||||
<!-- CA to remove config section to applicationhost.config -->
|
|
||||||
<CustomAction Id="CA_REMOVE_CONFIGSECTION_PROPERTY"
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION_PROPERTY"
|
||||||
Property="CA_REMOVE_CONFIGSECTION"
|
Property="CA_REMOVE_CONFIGSECTION"
|
||||||
Value="[IISEXPRESS_APPHOST_CONFIG];[IISEXPRESS_APPHOST_CONFIG_TMP]"/>
|
Value="[IISEXPRESS_APPHOST_CONFIG]"/>
|
||||||
<CustomAction Id="CA_REMOVE_CONFIGSECTION" Script="jscript" Execute="deferred" Return="check" Impersonate="no">
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION" BinaryKey="IISCustomActionDll" DllEntry="RemoveConfigSection" Execute="deferred" Return="check" Impersonate="no" />
|
||||||
<![CDATA[
|
|
||||||
var caData = Session.Property("CustomActionData");
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION_PROPERTY_TMP"
|
||||||
configfiles = caData.split(';');
|
Property="CA_REMOVE_CONFIGSECTION_TMP"
|
||||||
for (var i = 0; i < configfiles.length; i++) {
|
Value="[IISEXPRESS_APPHOST_CONFIG_TMP]"/>
|
||||||
var configfile = configfiles[i];
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION_TMP" BinaryKey="IISCustomActionDll" DllEntry="RemoveConfigSection" Execute="deferred" Return="check" Impersonate="no" />
|
||||||
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
|
|
||||||
xmlDoc.async = false;
|
|
||||||
xmlDoc.preserveWhiteSpace = true;
|
|
||||||
xmlDoc.load(configfile );
|
|
||||||
if (xmlDoc.parseError.errorCode == 0) {
|
|
||||||
xmlDoc.setProperty("SelectionLanguage", "XPath");
|
|
||||||
var websvrNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]");
|
|
||||||
if (websvrNode != null) {
|
|
||||||
var ancmNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"$(var.AspNetCoreSectionName)\"]");
|
|
||||||
if (ancmNode != null) {
|
|
||||||
websvrNode.removeChild(ancmNode);
|
|
||||||
xmlDoc.save(configfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</CustomAction>
|
|
||||||
|
|
||||||
<?if $(var.Platform) = "x64" ?>
|
<?if $(var.Platform) = "x64" ?>
|
||||||
<CustomAction Id="CA_UNLOCK_HANDLER32_PROPERTY"
|
<CustomAction Id="CA_UNLOCK_HANDLER32_PROPERTY"
|
||||||
|
|
@ -520,68 +479,25 @@
|
||||||
Value=""[IISEXPRESS_INSTALL_PATH32]appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[\[]mimeType='text/event-stream',enabled='FALSE'[\]]" /apphostconfig:"[IISEXPRESS_APPHOST_CONFIG32]""/>
|
Value=""[IISEXPRESS_INSTALL_PATH32]appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[\[]mimeType='text/event-stream',enabled='FALSE'[\]]" /apphostconfig:"[IISEXPRESS_APPHOST_CONFIG32]""/>
|
||||||
<CustomAction Id="CA_UPDATE_DYNAMIC_COMPRESSION_TMP32" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
<CustomAction Id="CA_UPDATE_DYNAMIC_COMPRESSION_TMP32" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- CA to add config section to applicationhost.config -->
|
|
||||||
<CustomAction Id="CA_ADD_CONFIGSECTION32_PROPERTY"
|
<CustomAction Id="CA_ADD_CONFIGSECTION32_PROPERTY"
|
||||||
Property="CA_ADD_CONFIGSECTION32"
|
Property="CA_ADD_CONFIGSECTION32"
|
||||||
Value="[IISEXPRESS_APPHOST_CONFIG32];[IISEXPRESS_APPHOST_CONFIG_TMP32]"/>
|
Value="[IISEXPRESS_APPHOST_CONFIG32]"/>
|
||||||
<CustomAction Id="CA_ADD_CONFIGSECTION32" Script="jscript" Execute="deferred" Return="check" Impersonate="no">
|
<CustomAction BinaryKey="IISCustomActionDll" Id="CA_ADD_CONFIGSECTION32" DllEntry="AddConfigSection" Execute="deferred" Return="check" Impersonate="no"/>
|
||||||
<!-- Warning LGHT1076: ICE03: String overflow. Orca.exe inspection shows the custom action value is populated correctly -->
|
|
||||||
<![CDATA[
|
<CustomAction Id="CA_ADD_CONFIGSECTION32_PROPERTY_TMP"
|
||||||
var caData = Session.Property("CustomActionData");
|
Property="CA_ADD_CONFIGSECTION32_TMP"
|
||||||
configfiles = caData.split(';');
|
Value="[IISEXPRESS_APPHOST_CONFIG_TMP32]"/>
|
||||||
for (var i = 0; i < configfiles.length; i++) {
|
<CustomAction BinaryKey="IISCustomActionDll" Id="CA_ADD_CONFIGSECTION32_TMP" DllEntry="AddConfigSection" Execute="deferred" Return="check" Impersonate="no"/>
|
||||||
var configfile = configfiles[i];
|
|
||||||
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
|
|
||||||
xmlDoc.async = false;
|
|
||||||
xmlDoc.preserveWhiteSpace = true;
|
|
||||||
xmlDoc.load(configfile);
|
|
||||||
if (xmlDoc.parseError.errorCode == 0) {
|
|
||||||
xmlDoc.setProperty("SelectionLanguage", "XPath");
|
|
||||||
var websvrNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]");
|
|
||||||
if (websvrNode != null) {
|
|
||||||
var ancmNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"$(var.AspNetCoreSectionName)\"]");
|
|
||||||
if (ancmNode == null) {
|
|
||||||
ancmNode = xmlDoc.createElement("section");
|
|
||||||
ancmNode.setAttribute("name", "$(var.AspNetCoreSectionName)");
|
|
||||||
ancmNode.setAttribute("overrideModeDefault", "Allow");
|
|
||||||
websvrNode.appendChild(ancmNode);
|
|
||||||
xmlDoc.save(configfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</CustomAction>
|
|
||||||
|
|
||||||
<!-- CA to remove config section to applicationhost.config -->
|
|
||||||
<CustomAction Id="CA_REMOVE_CONFIGSECTION32_PROPERTY"
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION32_PROPERTY"
|
||||||
Property="CA_REMOVE_CONFIGSECTION32"
|
Property="CA_REMOVE_CONFIGSECTION32"
|
||||||
Value="[IISEXPRESS_APPHOST_CONFIG32];[IISEXPRESS_APPHOST_CONFIG_TMP32]"/>
|
Value="[IISEXPRESS_APPHOST_CONFIG32]"/>
|
||||||
<CustomAction Id="CA_REMOVE_CONFIGSECTION32" Script="jscript" Execute="deferred" Return="check" Impersonate="no">
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION32" BinaryKey="IISCustomActionDll" DllEntry="RemoveConfigSection" Execute="deferred" Return="check" Impersonate="no" />
|
||||||
<![CDATA[
|
|
||||||
var caData = Session.Property("CustomActionData");
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION32_PROPERTY_TMP"
|
||||||
configfiles = caData.split(';');
|
Property="CA_REMOVE_CONFIGSECTION32_TMP"
|
||||||
for (var i = 0; i < configfiles.length; i++) {
|
Value="[IISEXPRESS_APPHOST_CONFIG_TMP32]"/>
|
||||||
var configfile = configfiles[i];
|
<CustomAction Id="CA_REMOVE_CONFIGSECTION32_TMP" BinaryKey="IISCustomActionDll" DllEntry="RemoveConfigSection" Execute="deferred" Return="check" Impersonate="no" />
|
||||||
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
|
|
||||||
xmlDoc.async = false;
|
|
||||||
xmlDoc.preserveWhiteSpace = true;
|
|
||||||
xmlDoc.load(configfile);
|
|
||||||
if (xmlDoc.parseError.errorCode == 0) {
|
|
||||||
xmlDoc.setProperty("SelectionLanguage", "XPath");
|
|
||||||
var websvrNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]");
|
|
||||||
if (websvrNode != null) {
|
|
||||||
var ancmNode = xmlDoc.selectSingleNode("//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"$(var.AspNetCoreSectionName)\"]");
|
|
||||||
if (ancmNode != null) {
|
|
||||||
websvrNode.removeChild(ancmNode);
|
|
||||||
xmlDoc.save(configfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</CustomAction>
|
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<InstallExecuteSequence>
|
<InstallExecuteSequence>
|
||||||
|
|
@ -600,7 +516,9 @@
|
||||||
<Custom Action="CA_SET_MODULE" After="CA_SET_MODULE_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_SET_MODULE" After="CA_SET_MODULE_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_CONFIGSECTION_PROPERTY" After="CA_SET_MODULE"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_CONFIGSECTION_PROPERTY" After="CA_SET_MODULE"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_CONFIGSECTION" After="CA_ADD_CONFIGSECTION_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_CONFIGSECTION" After="CA_ADD_CONFIGSECTION_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_PROPERTY" After="CA_ADD_CONFIGSECTION"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_CONFIGSECTION_PROPERTY_TMP" After="CA_ADD_CONFIGSECTION"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
|
<Custom Action="CA_ADD_CONFIGSECTION_TMP" After="CA_ADD_CONFIGSECTION_PROPERTY_TMP"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_PROPERTY" After="CA_ADD_CONFIGSECTION_TMP"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION" After="CA_ADD_TRACE_PROVIDER_DEFINITION_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION" After="CA_ADD_TRACE_PROVIDER_DEFINITION_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP_PROPERTY" After="CA_ADD_TRACE_PROVIDER_DEFINITION"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP_PROPERTY" After="CA_ADD_TRACE_PROVIDER_DEFINITION"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP" After="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP" After="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
|
|
@ -610,6 +528,8 @@
|
||||||
<Custom Action="CA_REMOVE_MODULE" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_MODULE" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_CONFIGSECTION_PROPERTY" Before="CA_REMOVE_CONFIGSECTION"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_CONFIGSECTION_PROPERTY" Before="CA_REMOVE_CONFIGSECTION"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_CONFIGSECTION" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_CONFIGSECTION" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
|
<Custom Action="CA_REMOVE_CONFIGSECTION_PROPERTY_TMP" Before="CA_REMOVE_CONFIGSECTION_TMP"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
|
<Custom Action="CA_REMOVE_CONFIGSECTION_TMP" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
|
|
@ -640,7 +560,9 @@
|
||||||
<Custom Action="CA_SET_MODULE32" After="CA_ADD_MODULE32_PROPERTY"><![CDATA[(NOT REMOVE AND IISEXPRESS_INSTALL_PATH32)]]></Custom>
|
<Custom Action="CA_SET_MODULE32" After="CA_ADD_MODULE32_PROPERTY"><![CDATA[(NOT REMOVE AND IISEXPRESS_INSTALL_PATH32)]]></Custom>
|
||||||
<Custom Action="CA_ADD_CONFIGSECTION32_PROPERTY" After="CA_SET_MODULE32"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_CONFIGSECTION32_PROPERTY" After="CA_SET_MODULE32"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_CONFIGSECTION32" After="CA_ADD_CONFIGSECTION32_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_CONFIGSECTION32" After="CA_ADD_CONFIGSECTION32_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION32_PROPERTY" After="CA_ADD_CONFIGSECTION32"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_CONFIGSECTION32_PROPERTY_TMP" After="CA_ADD_CONFIGSECTION32"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
|
<Custom Action="CA_ADD_CONFIGSECTION32_TMP" After="CA_ADD_CONFIGSECTION32_PROPERTY_TMP"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION32_PROPERTY" After="CA_ADD_CONFIGSECTION32_TMP"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION32" After="CA_ADD_TRACE_PROVIDER_DEFINITION32_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION32" After="CA_ADD_TRACE_PROVIDER_DEFINITION32_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP32_PROPERTY" After="CA_ADD_TRACE_PROVIDER_DEFINITION32"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP32_PROPERTY" After="CA_ADD_TRACE_PROVIDER_DEFINITION32"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP32" After="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP32_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
<Custom Action="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP32" After="CA_ADD_TRACE_PROVIDER_DEFINITION_TMP32_PROPERTY"><![CDATA[(NOT REMOVE)]]></Custom>
|
||||||
|
|
@ -650,6 +572,8 @@
|
||||||
<Custom Action="CA_REMOVE_MODULE32" After="CA_REMOVE_MODULE32_PROPERTY"><![CDATA[(REMOVE~="ALL" AND IISEXPRESS_INSTALL_PATH32 AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_MODULE32" After="CA_REMOVE_MODULE32_PROPERTY"><![CDATA[(REMOVE~="ALL" AND IISEXPRESS_INSTALL_PATH32 AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_CONFIGSECTION32_PROPERTY" Before="CA_REMOVE_CONFIGSECTION32"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_CONFIGSECTION32_PROPERTY" Before="CA_REMOVE_CONFIGSECTION32"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_CONFIGSECTION32" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_CONFIGSECTION32" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
|
<Custom Action="CA_REMOVE_CONFIGSECTION32_PROPERTY_TMP" Before="CA_REMOVE_CONFIGSECTION32_TMP"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
|
<Custom Action="CA_REMOVE_CONFIGSECTION32_TMP" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION32_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION32"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION32_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION32"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION32" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION32" Before="RemoveFiles"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP32_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP32"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
<Custom Action="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP32_PROPERTY" Before="CA_REMOVE_TRACE_PROVIDER_DEFINITION_TMP32"><![CDATA[(REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE)]]></Custom>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
#include <precomp.h>
|
#include <precomp.h>
|
||||||
|
#include <MsiQuery.h>
|
||||||
|
#include <msxml6.h>
|
||||||
|
|
||||||
DECLARE_DEBUG_PRINT_OBJECT( "proxyCA.dll" );
|
DECLARE_DEBUG_PRINT_OBJECT( "proxyCA.dll" );
|
||||||
|
|
||||||
|
|
@ -40,6 +42,138 @@ struct COMPRESSION_MIME_TYPE
|
||||||
COMPRESSION_MIME_TYPE gMimeTypes[] =
|
COMPRESSION_MIME_TYPE gMimeTypes[] =
|
||||||
{ { L"text/event-stream", FALSE} };
|
{ { L"text/event-stream", FALSE} };
|
||||||
|
|
||||||
|
#define _HR_RET(hr) __pragma(warning(push)) \
|
||||||
|
__pragma(warning(disable:26498)) /*disable constexpr warning */ \
|
||||||
|
const HRESULT __hrRet = hr; \
|
||||||
|
__pragma(warning(pop))
|
||||||
|
|
||||||
|
#define _GOTO_FINISHED() __pragma(warning(push)) \
|
||||||
|
__pragma(warning(disable:26438)) /*disable avoid goto warning*/ \
|
||||||
|
goto Finished \
|
||||||
|
__pragma(warning(pop))
|
||||||
|
|
||||||
|
#define RETURN_IF_FAILED(hrr) do { _HR_RET(hrr); if (FAILED(__hrRet)) { hr = __hrRet; IISLogWrite(SETUP_LOG_SEVERITY_INFORMATION, L"Exiting hr=0x%x", hr); return hr; }} while (0, 0)
|
||||||
|
|
||||||
|
// Modifies the configSections to include the aspNetCore section
|
||||||
|
UINT
|
||||||
|
WINAPI
|
||||||
|
AddConfigSection(
|
||||||
|
IN MSIHANDLE handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
CComPtr<IXMLDOMDocument2> pXMLDoc;
|
||||||
|
VARIANT_BOOL variantResult;
|
||||||
|
IXMLDOMNode* webServerNode;
|
||||||
|
IXMLDOMNode* aspNetCoreNode;
|
||||||
|
IXMLDOMNode* tempNode;
|
||||||
|
IXMLDOMElement* element;
|
||||||
|
STRU customActionData;
|
||||||
|
|
||||||
|
CComBSTR selectLanguage = SysAllocString(L"SelectionLanguage");
|
||||||
|
CComBSTR xPath = SysAllocString(L"XPath");
|
||||||
|
CComBSTR webServerPath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]");
|
||||||
|
CComBSTR aspNetCorePath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"aspNetCore\"]");
|
||||||
|
CComBSTR section = SysAllocString(L"section");
|
||||||
|
CComBSTR name = SysAllocString(L"name");
|
||||||
|
CComBSTR aspNetCore = SysAllocString(L"aspNetCore");
|
||||||
|
CComBSTR overrideMode = SysAllocString(L"overrideModeDefault");
|
||||||
|
CComBSTR allow = SysAllocString(L"Allow");
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(CoInitialize(NULL));
|
||||||
|
|
||||||
|
hr = MsiUtilGetProperty(handle, TEXT("CustomActionData"), &customActionData);
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc.CoCreateInstance(__uuidof(DOMDocument60)));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->put_async(false));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->load(CComVariant(customActionData.QueryStr()), &variantResult));
|
||||||
|
|
||||||
|
if (variantResult == VARIANT_FALSE)
|
||||||
|
{
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->setProperty(selectLanguage, CComVariant(xPath)));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(webServerPath, &webServerNode));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(aspNetCorePath, &aspNetCoreNode));
|
||||||
|
|
||||||
|
if (aspNetCoreNode == NULL)
|
||||||
|
{
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->createElement(section, &element));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = element->setAttribute(name, CComVariant(aspNetCore)));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = element->setAttribute(overrideMode, CComVariant(allow)));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = webServerNode->appendChild(element, &tempNode));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->save(CComVariant(customActionData.QueryStr())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifies the configSections to remove the aspNetCore section
|
||||||
|
UINT
|
||||||
|
WINAPI
|
||||||
|
RemoveConfigSection(
|
||||||
|
IN MSIHANDLE handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
CComPtr<IXMLDOMDocument2> pXMLDoc;
|
||||||
|
VARIANT_BOOL variantResult;
|
||||||
|
IXMLDOMNode* webServerNode;
|
||||||
|
IXMLDOMNode* aspNetCoreNode;
|
||||||
|
IXMLDOMNode* tempNode;
|
||||||
|
IXMLDOMElement* element;
|
||||||
|
STRU customActionData;
|
||||||
|
|
||||||
|
CComBSTR selectLanguage = SysAllocString(L"SelectionLanguage");
|
||||||
|
CComBSTR xPath = SysAllocString(L"XPath");
|
||||||
|
CComBSTR webServerPath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]");
|
||||||
|
CComBSTR aspNetCorePath = SysAllocString(L"//configuration/configSections/sectionGroup[@name=\"system.webServer\"]/section[@name=\"aspNetCore\"]");
|
||||||
|
CComBSTR section = SysAllocString(L"section");
|
||||||
|
CComBSTR name = SysAllocString(L"name");
|
||||||
|
CComBSTR aspNetCore = SysAllocString(L"aspNetCore");
|
||||||
|
CComBSTR overrideMode = SysAllocString(L"overrideModeDefault");
|
||||||
|
CComBSTR allow = SysAllocString(L"Allow");
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(CoInitialize(NULL));
|
||||||
|
|
||||||
|
hr = MsiUtilGetProperty(handle, TEXT("CustomActionData"), &customActionData);
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc.CoCreateInstance(__uuidof(DOMDocument60)));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->put_async(false));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->load(CComVariant(customActionData.QueryStr()), &variantResult));
|
||||||
|
|
||||||
|
if (variantResult == VARIANT_FALSE)
|
||||||
|
{
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->setProperty(selectLanguage, CComVariant(xPath)));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(webServerPath, &webServerNode));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->selectSingleNode(aspNetCorePath, &aspNetCoreNode));
|
||||||
|
|
||||||
|
if (aspNetCoreNode != NULL)
|
||||||
|
{
|
||||||
|
RETURN_IF_FAILED(webServerNode->removeChild(aspNetCoreNode, &tempNode));
|
||||||
|
|
||||||
|
RETURN_IF_FAILED(hr = pXMLDoc->save(CComVariant(customActionData.QueryStr())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
WINAPI
|
WINAPI
|
||||||
RegisterANCMCompressionCA(
|
RegisterANCMCompressionCA(
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ EXPORTS
|
||||||
ExecuteCleanUpWindowsHotfixCA
|
ExecuteCleanUpWindowsHotfixCA
|
||||||
ScheduleRebootIfRequiredCA
|
ScheduleRebootIfRequiredCA
|
||||||
|
|
||||||
|
AddConfigSection
|
||||||
|
RemoveConfigSection
|
||||||
RegisterANCMCompressionCA
|
RegisterANCMCompressionCA
|
||||||
|
|
||||||
CheckForServicesRunningCA
|
CheckForServicesRunningCA
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -50,7 +50,5 @@ body {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* Set the fixed height of the footer here */
|
|
||||||
height: 60px;
|
|
||||||
line-height: 60px; /* Vertically center the text there */
|
line-height: 60px; /* Vertically center the text there */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,5 @@ body {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* Set the fixed height of the footer here */
|
|
||||||
height: 60px;
|
|
||||||
line-height: 60px; /* Vertically center the text there */
|
line-height: 60px; /* Vertically center the text there */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,5 @@ body {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* Set the fixed height of the footer here */
|
|
||||||
height: 60px;
|
|
||||||
line-height: 60px; /* Vertically center the text there */
|
line-height: 60px; /* Vertically center the text there */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||||
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||||
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.AspNetCore.Testing.xunit;
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -170,6 +171,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2200", FlakyOn.All)]
|
||||||
[MemberData(nameof(TestVariants))]
|
[MemberData(nameof(TestVariants))]
|
||||||
public async Task CheckUTF8File(TestVariant variant)
|
public async Task CheckUTF8File(TestVariant variant)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
||||||
public Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode ApplicationSchedulingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
public Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingMode ApplicationSchedulingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader ConfigurationLoader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader ConfigurationLoader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
|
public bool DisableStringReuse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
|
||||||
public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerLimits Limits { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerLimits Limits { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
|
||||||
public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure() { throw null; }
|
public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure() { throw null; }
|
||||||
public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure(Microsoft.Extensions.Configuration.IConfiguration config) { throw null; }
|
public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure(Microsoft.Extensions.Configuration.IConfiguration config) { throw null; }
|
||||||
|
|
@ -251,6 +252,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public partial interface IHttpHeadersHandler
|
public partial interface IHttpHeadersHandler
|
||||||
{
|
{
|
||||||
void OnHeader(System.Span<byte> name, System.Span<byte> value);
|
void OnHeader(System.Span<byte> name, System.Span<byte> value);
|
||||||
|
void OnHeadersComplete();
|
||||||
}
|
}
|
||||||
public partial interface IHttpParser<TRequestHandler> where TRequestHandler : Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpHeadersHandler, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpRequestLineHandler
|
public partial interface IHttpParser<TRequestHandler> where TRequestHandler : Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpHeadersHandler, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpRequestLineHandler
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
private const byte ByteAsterisk = (byte)'*';
|
private const byte ByteAsterisk = (byte)'*';
|
||||||
private const byte ByteForwardSlash = (byte)'/';
|
private const byte ByteForwardSlash = (byte)'/';
|
||||||
private const string Asterisk = "*";
|
private const string Asterisk = "*";
|
||||||
|
private const string ForwardSlash = "/";
|
||||||
|
|
||||||
private readonly HttpConnectionContext _context;
|
private readonly HttpConnectionContext _context;
|
||||||
private readonly IHttpParser<Http1ParsingHandler> _parser;
|
private readonly IHttpParser<Http1ParsingHandler> _parser;
|
||||||
|
|
@ -268,16 +269,68 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
_requestTargetForm = HttpRequestTarget.OriginForm;
|
_requestTargetForm = HttpRequestTarget.OriginForm;
|
||||||
|
|
||||||
|
if (target.Length == 1)
|
||||||
|
{
|
||||||
|
// If target.Length == 1 it can only be a forward slash (e.g. home page)
|
||||||
|
// and we know RawTarget and Path are the same and QueryString is Empty
|
||||||
|
RawTarget = ForwardSlash;
|
||||||
|
Path = ForwardSlash;
|
||||||
|
QueryString = string.Empty;
|
||||||
|
// Clear parsedData as we won't check it if we come via this path again,
|
||||||
|
// an setting to null is fast as it doesn't need to use a GC write barrier.
|
||||||
|
_parsedRawTarget = _parsedPath = _parsedQueryString = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11
|
// URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11
|
||||||
// Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8;
|
// Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8;
|
||||||
// then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs"
|
// then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs"
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var disableStringReuse = ServerOptions.DisableStringReuse;
|
||||||
// Read raw target before mutating memory.
|
// Read raw target before mutating memory.
|
||||||
RawTarget = target.GetAsciiStringNonNullCharacters();
|
var previousValue = _parsedRawTarget;
|
||||||
QueryString = query.GetAsciiStringNonNullCharacters();
|
if (disableStringReuse ||
|
||||||
Path = PathNormalizer.DecodePath(path, pathEncoded, RawTarget, query.Length);
|
previousValue == null || previousValue.Length != target.Length ||
|
||||||
|
!StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target))
|
||||||
|
{
|
||||||
|
// The previous string does not match what the bytes would convert to,
|
||||||
|
// so we will need to generate a new string.
|
||||||
|
RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
|
previousValue = _parsedQueryString;
|
||||||
|
if (disableStringReuse ||
|
||||||
|
previousValue == null || previousValue.Length != query.Length ||
|
||||||
|
!StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, query))
|
||||||
|
{
|
||||||
|
// The previous string does not match what the bytes would convert to,
|
||||||
|
// so we will need to generate a new string.
|
||||||
|
QueryString = _parsedQueryString = query.GetAsciiStringNonNullCharacters();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Same as previous
|
||||||
|
QueryString = _parsedQueryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.Length == 1)
|
||||||
|
{
|
||||||
|
// If path.Length == 1 it can only be a forward slash (e.g. home page)
|
||||||
|
Path = _parsedPath = ForwardSlash;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Path = _parsedPath = PathNormalizer.DecodePath(path, pathEncoded, RawTarget, query.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// As RawTarget is the same we can reuse the previous parsed values.
|
||||||
|
RawTarget = _parsedRawTarget;
|
||||||
|
Path = _parsedPath;
|
||||||
|
QueryString = _parsedQueryString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException)
|
catch (InvalidOperationException)
|
||||||
{
|
{
|
||||||
|
|
@ -312,9 +365,27 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
//
|
//
|
||||||
// Allowed characters in the 'host + port' section of authority.
|
// Allowed characters in the 'host + port' section of authority.
|
||||||
// See https://tools.ietf.org/html/rfc3986#section-3.2
|
// See https://tools.ietf.org/html/rfc3986#section-3.2
|
||||||
RawTarget = target.GetAsciiStringNonNullCharacters();
|
|
||||||
|
var previousValue = _parsedRawTarget;
|
||||||
|
if (ServerOptions.DisableStringReuse ||
|
||||||
|
previousValue == null || previousValue.Length != target.Length ||
|
||||||
|
!StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target))
|
||||||
|
{
|
||||||
|
// The previous string does not match what the bytes would convert to,
|
||||||
|
// so we will need to generate a new string.
|
||||||
|
RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Reuse previous value
|
||||||
|
RawTarget = _parsedRawTarget;
|
||||||
|
}
|
||||||
|
|
||||||
Path = string.Empty;
|
Path = string.Empty;
|
||||||
QueryString = string.Empty;
|
QueryString = string.Empty;
|
||||||
|
// Clear parsedData for path and queryString as we won't check it if we come via this path again,
|
||||||
|
// an setting to null is fast as it doesn't need to use a GC write barrier.
|
||||||
|
_parsedPath = _parsedQueryString = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAsteriskFormTarget(HttpMethod method)
|
private void OnAsteriskFormTarget(HttpMethod method)
|
||||||
|
|
@ -331,6 +402,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
RawTarget = Asterisk;
|
RawTarget = Asterisk;
|
||||||
Path = string.Empty;
|
Path = string.Empty;
|
||||||
QueryString = string.Empty;
|
QueryString = string.Empty;
|
||||||
|
// Clear parsedData as we won't check it if we come via this path again,
|
||||||
|
// an setting to null is fast as it doesn't need to use a GC write barrier.
|
||||||
|
_parsedRawTarget = _parsedPath = _parsedQueryString = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAbsoluteFormTarget(Span<byte> target, Span<byte> query)
|
private void OnAbsoluteFormTarget(Span<byte> target, Span<byte> query)
|
||||||
|
|
@ -346,21 +420,49 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
// a server MUST accept the absolute-form in requests, even though
|
// a server MUST accept the absolute-form in requests, even though
|
||||||
// HTTP/1.1 clients will only send them in requests to proxies.
|
// HTTP/1.1 clients will only send them in requests to proxies.
|
||||||
|
|
||||||
RawTarget = target.GetAsciiStringNonNullCharacters();
|
var disableStringReuse = ServerOptions.DisableStringReuse;
|
||||||
|
var previousValue = _parsedRawTarget;
|
||||||
// Validation of absolute URIs is slow, but clients
|
if (disableStringReuse ||
|
||||||
// should not be sending this form anyways, so perf optimization
|
previousValue == null || previousValue.Length != target.Length ||
|
||||||
// not high priority
|
!StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target))
|
||||||
|
|
||||||
if (!Uri.TryCreate(RawTarget, UriKind.Absolute, out var uri))
|
|
||||||
{
|
{
|
||||||
ThrowRequestTargetRejected(target);
|
// The previous string does not match what the bytes would convert to,
|
||||||
}
|
// so we will need to generate a new string.
|
||||||
|
RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
_absoluteRequestTarget = uri;
|
// Validation of absolute URIs is slow, but clients
|
||||||
Path = uri.LocalPath;
|
// should not be sending this form anyways, so perf optimization
|
||||||
// don't use uri.Query because we need the unescaped version
|
// not high priority
|
||||||
QueryString = query.GetAsciiStringNonNullCharacters();
|
|
||||||
|
if (!Uri.TryCreate(RawTarget, UriKind.Absolute, out var uri))
|
||||||
|
{
|
||||||
|
ThrowRequestTargetRejected(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
_absoluteRequestTarget = uri;
|
||||||
|
Path = _parsedPath = uri.LocalPath;
|
||||||
|
// don't use uri.Query because we need the unescaped version
|
||||||
|
previousValue = _parsedQueryString;
|
||||||
|
if (disableStringReuse ||
|
||||||
|
previousValue == null || previousValue.Length != query.Length ||
|
||||||
|
!StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, query))
|
||||||
|
{
|
||||||
|
// The previous string does not match what the bytes would convert to,
|
||||||
|
// so we will need to generate a new string.
|
||||||
|
QueryString = _parsedQueryString = query.GetAsciiStringNonNullCharacters();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QueryString = _parsedQueryString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// As RawTarget is the same we can reuse the previous values.
|
||||||
|
RawTarget = _parsedRawTarget;
|
||||||
|
Path = _parsedPath;
|
||||||
|
QueryString = _parsedQueryString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EnsureHostHeaderExists()
|
internal void EnsureHostHeaderExists()
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public void OnHeader(Span<byte> name, Span<byte> value)
|
public void OnHeader(Span<byte> name, Span<byte> value)
|
||||||
=> Connection.OnHeader(name, value);
|
=> Connection.OnHeader(name, value);
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
=> Connection.OnHeadersComplete();
|
||||||
|
|
||||||
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||||
=> Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
=> Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -16,6 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{
|
{
|
||||||
internal abstract class HttpHeaders : IHeaderDictionary
|
internal abstract class HttpHeaders : IHeaderDictionary
|
||||||
{
|
{
|
||||||
|
protected long _bits = 0;
|
||||||
protected long? _contentLength;
|
protected long? _contentLength;
|
||||||
protected bool _isReadOnly;
|
protected bool _isReadOnly;
|
||||||
protected Dictionary<string, StringValues> MaybeUnknown;
|
protected Dictionary<string, StringValues> MaybeUnknown;
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}
|
}
|
||||||
|
|
||||||
done = true;
|
done = true;
|
||||||
|
handler.OnHeadersComplete();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
||||||
ServerOptions = ServiceContext.ServerOptions;
|
ServerOptions = ServiceContext.ServerOptions;
|
||||||
|
HttpRequestHeaders = new HttpRequestHeaders(reuseHeaderValues: !ServerOptions.DisableStringReuse);
|
||||||
HttpResponseControl = this;
|
HttpResponseControl = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,8 +125,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public string Scheme { get; set; }
|
public string Scheme { get; set; }
|
||||||
public HttpMethod Method { get; set; }
|
public HttpMethod Method { get; set; }
|
||||||
public string PathBase { get; set; }
|
public string PathBase { get; set; }
|
||||||
|
|
||||||
|
protected string _parsedPath = null;
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
|
protected string _parsedQueryString = null;
|
||||||
public string QueryString { get; set; }
|
public string QueryString { get; set; }
|
||||||
|
|
||||||
|
protected string _parsedRawTarget = null;
|
||||||
public string RawTarget { get; set; }
|
public string RawTarget { get; set; }
|
||||||
|
|
||||||
public string HttpVersion
|
public string HttpVersion
|
||||||
|
|
@ -275,7 +282,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
public bool HasFlushedHeaders => _requestProcessingStatus == RequestProcessingStatus.HeadersFlushed;
|
public bool HasFlushedHeaders => _requestProcessingStatus == RequestProcessingStatus.HeadersFlushed;
|
||||||
|
|
||||||
protected HttpRequestHeaders HttpRequestHeaders { get; } = new HttpRequestHeaders();
|
protected HttpRequestHeaders HttpRequestHeaders { get; }
|
||||||
|
|
||||||
protected HttpResponseHeaders HttpResponseHeaders { get; } = new HttpResponseHeaders();
|
protected HttpResponseHeaders HttpResponseHeaders { get; } = new HttpResponseHeaders();
|
||||||
|
|
||||||
|
|
@ -492,9 +499,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{
|
{
|
||||||
BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
|
BadHttpRequestException.Throw(RequestRejectionReason.TooManyHeaders);
|
||||||
}
|
}
|
||||||
var valueString = value.GetAsciiOrUTF8StringNonNullCharacters();
|
|
||||||
|
|
||||||
HttpRequestHeaders.Append(name, valueString);
|
HttpRequestHeaders.Append(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
{
|
||||||
|
HttpRequestHeaders.OnHeadersComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> application)
|
public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> application)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers.Text;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
@ -13,6 +14,50 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{
|
{
|
||||||
internal sealed partial class HttpRequestHeaders : HttpHeaders
|
internal sealed partial class HttpRequestHeaders : HttpHeaders
|
||||||
{
|
{
|
||||||
|
private readonly bool _reuseHeaderValues;
|
||||||
|
private long _previousBits = 0;
|
||||||
|
|
||||||
|
public HttpRequestHeaders(bool reuseHeaderValues = true)
|
||||||
|
{
|
||||||
|
_reuseHeaderValues = reuseHeaderValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
{
|
||||||
|
var bitsToClear = _previousBits & ~_bits;
|
||||||
|
_previousBits = 0;
|
||||||
|
|
||||||
|
if (bitsToClear != 0)
|
||||||
|
{
|
||||||
|
// Some previous headers were not reused or overwritten.
|
||||||
|
|
||||||
|
// While they cannot be accessed by the current request (as they were not supplied by it)
|
||||||
|
// there is no point in holding on to them, so clear them now,
|
||||||
|
// to allow them to get collected by the GC.
|
||||||
|
Clear(bitsToClear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearFast()
|
||||||
|
{
|
||||||
|
if (!_reuseHeaderValues)
|
||||||
|
{
|
||||||
|
// If we aren't reusing headers clear them all
|
||||||
|
Clear(_bits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we are reusing headers, store the currently set headers for comparison later
|
||||||
|
_previousBits = _bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark no headers as currently in use
|
||||||
|
_bits = 0;
|
||||||
|
// Clear ContentLength and any unknown headers as we will never reuse them
|
||||||
|
_contentLength = null;
|
||||||
|
MaybeUnknown?.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private static long ParseContentLength(string value)
|
private static long ParseContentLength(string value)
|
||||||
{
|
{
|
||||||
if (!HeaderUtilities.TryParseNonNegativeInt64(value, out var parsed))
|
if (!HeaderUtilities.TryParseNonNegativeInt64(value, out var parsed))
|
||||||
|
|
@ -23,34 +68,45 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
private void AppendContentLength(Span<byte> value)
|
||||||
|
{
|
||||||
|
if (_contentLength.HasValue)
|
||||||
|
{
|
||||||
|
BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Utf8Parser.TryParse(value, out long parsed, out var consumed) ||
|
||||||
|
parsed < 0 ||
|
||||||
|
consumed != value.Length)
|
||||||
|
{
|
||||||
|
BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetAsciiOrUTF8StringNonNullCharacters());
|
||||||
|
}
|
||||||
|
|
||||||
|
_contentLength = parsed;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
private void SetValueUnknown(string key, StringValues value)
|
private void SetValueUnknown(string key, StringValues value)
|
||||||
{
|
{
|
||||||
Unknown[key] = value;
|
Unknown[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Append(Span<byte> name, string value)
|
|
||||||
{
|
|
||||||
fixed (byte* namePtr = name)
|
|
||||||
{
|
|
||||||
Append(namePtr, name.Length, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
private unsafe void AppendUnknownHeaders(byte* pKeyBytes, int keyLength, string value)
|
private unsafe void AppendUnknownHeaders(Span<byte> name, string valueString)
|
||||||
{
|
{
|
||||||
string key = new string('\0', keyLength);
|
string key = new string('\0', name.Length);
|
||||||
|
fixed (byte* pKeyBytes = name)
|
||||||
fixed (char* keyBuffer = key)
|
fixed (char* keyBuffer = key)
|
||||||
{
|
{
|
||||||
if (!StringUtilities.TryGetAsciiString(pKeyBytes, keyBuffer, keyLength))
|
if (!StringUtilities.TryGetAsciiString(pKeyBytes, keyBuffer, name.Length))
|
||||||
{
|
{
|
||||||
BadHttpRequestException.Throw(RequestRejectionReason.InvalidCharactersInHeaderName);
|
BadHttpRequestException.Throw(RequestRejectionReason.InvalidCharactersInHeaderName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unknown.TryGetValue(key, out var existing);
|
Unknown.TryGetValue(key, out var existing);
|
||||||
Unknown[key] = AppendValue(existing, value);
|
Unknown[key] = AppendValue(existing, valueString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumerator GetEnumerator()
|
public Enumerator GetEnumerator()
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
public interface IHttpHeadersHandler
|
public interface IHttpHeadersHandler
|
||||||
{
|
{
|
||||||
void OnHeader(Span<byte> name, Span<byte> value);
|
void OnHeader(Span<byte> name, Span<byte> value);
|
||||||
|
void OnHeadersComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1092,6 +1092,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
=> _currentHeadersStream.OnHeadersComplete();
|
||||||
|
|
||||||
private void ValidateHeader(Span<byte> name, Span<byte> value)
|
private void ValidateHeader(Span<byte> name, Span<byte> value)
|
||||||
{
|
{
|
||||||
// http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.1
|
// http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.1
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,19 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Intrinsics.X86;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
{
|
{
|
||||||
internal class StringUtilities
|
internal class StringUtilities
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
public static unsafe bool TryGetAsciiString(byte* input, char* output, int count)
|
public static unsafe bool TryGetAsciiString(byte* input, char* output, int count)
|
||||||
{
|
{
|
||||||
// Calculate end position
|
// Calculate end position
|
||||||
|
|
@ -109,6 +115,261 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
|
public unsafe static bool BytesOrdinalEqualsStringAndAscii(string previousValue, Span<byte> newValue)
|
||||||
|
{
|
||||||
|
// previousValue is a previously materialized string which *must* have already passed validation.
|
||||||
|
Debug.Assert(IsValidHeaderString(previousValue));
|
||||||
|
|
||||||
|
// Ascii bytes => Utf-16 chars will be the same length.
|
||||||
|
// The caller should have already compared lengths before calling this method.
|
||||||
|
// However; let's double check, and early exit if they are not the same length.
|
||||||
|
if (previousValue.Length != newValue.Length)
|
||||||
|
{
|
||||||
|
// Lengths don't match, so there cannot be an exact ascii conversion between the two.
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use IntPtr values rather than int, to avoid unnecessary 32 -> 64 movs on 64-bit.
|
||||||
|
// Unfortunately this means we also need to cast to byte* for comparisons as IntPtr doesn't
|
||||||
|
// support operator comparisons (e.g. <=, >, etc).
|
||||||
|
//
|
||||||
|
// Note: Pointer comparison is unsigned, so we use the compare pattern (offset + length <= count)
|
||||||
|
// rather than (offset <= count - length) which we'd do with signed comparison to avoid overflow.
|
||||||
|
// This isn't problematic as we know the maximum length is max string length (from test above)
|
||||||
|
// which is a signed value so half the size of the unsigned pointer value so we can safely add
|
||||||
|
// a Vector<byte>.Count to it without overflowing.
|
||||||
|
var count = (IntPtr)newValue.Length;
|
||||||
|
var offset = (IntPtr)0;
|
||||||
|
|
||||||
|
// Get references to the first byte in the span, and the first char in the string.
|
||||||
|
ref var bytes = ref MemoryMarshal.GetReference(newValue);
|
||||||
|
ref var str = ref MemoryMarshal.GetReference(previousValue.AsSpan());
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// If Vector not-accelerated or remaining less than vector size
|
||||||
|
if (!Vector.IsHardwareAccelerated || (byte*)(offset + Vector<byte>.Count) > (byte*)count)
|
||||||
|
{
|
||||||
|
if (IntPtr.Size == 8) // Use Intrinsic switch for branch elimination
|
||||||
|
{
|
||||||
|
// 64-bit: Loop longs by default
|
||||||
|
while ((byte*)(offset + sizeof(long)) <= (byte*)count)
|
||||||
|
{
|
||||||
|
if (!WidenFourAsciiBytesToUtf16AndCompareToChars(
|
||||||
|
ref Unsafe.Add(ref str, offset),
|
||||||
|
Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref bytes, offset))) ||
|
||||||
|
!WidenFourAsciiBytesToUtf16AndCompareToChars(
|
||||||
|
ref Unsafe.Add(ref str, offset + 4),
|
||||||
|
Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref bytes, offset + 4))))
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += sizeof(long);
|
||||||
|
}
|
||||||
|
if ((byte*)(offset + sizeof(int)) <= (byte*)count)
|
||||||
|
{
|
||||||
|
if (!WidenFourAsciiBytesToUtf16AndCompareToChars(
|
||||||
|
ref Unsafe.Add(ref str, offset),
|
||||||
|
Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref bytes, offset))))
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += sizeof(int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 32-bit: Loop ints by default
|
||||||
|
while ((byte*)(offset + sizeof(int)) <= (byte*)count)
|
||||||
|
{
|
||||||
|
if (!WidenFourAsciiBytesToUtf16AndCompareToChars(
|
||||||
|
ref Unsafe.Add(ref str, offset),
|
||||||
|
Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref bytes, offset))))
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += sizeof(int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((byte*)(offset + sizeof(short)) <= (byte*)count)
|
||||||
|
{
|
||||||
|
if (!WidenTwoAsciiBytesToUtf16AndCompareToChars(
|
||||||
|
ref Unsafe.Add(ref str, offset),
|
||||||
|
Unsafe.ReadUnaligned<ushort>(ref Unsafe.Add(ref bytes, offset))))
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += sizeof(short);
|
||||||
|
}
|
||||||
|
if ((byte*)offset < (byte*)count)
|
||||||
|
{
|
||||||
|
var ch = (char)Unsafe.Add(ref bytes, offset);
|
||||||
|
if (((ch & 0x80) != 0) || Unsafe.Add(ref str, offset) != ch)
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// End of input reached, there are no inequalities via widening; so the input bytes are both ascii
|
||||||
|
// and a match to the string if it was converted via Encoding.ASCII.GetString(...)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a comparision vector for all bits being equal
|
||||||
|
var AllTrue = new Vector<short>(-1);
|
||||||
|
// do/while as entry condition already checked, remaining length must be Vector<byte>.Count or larger.
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Read a Vector length from the input as bytes
|
||||||
|
var vector = Unsafe.ReadUnaligned<Vector<sbyte>>(ref Unsafe.Add(ref bytes, offset));
|
||||||
|
if (!CheckBytesInAsciiRange(vector))
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
// Widen the bytes directly to chars (ushort) as if they were ascii.
|
||||||
|
// As widening doubles the size we get two vectors back.
|
||||||
|
Vector.Widen(vector, out var vector0, out var vector1);
|
||||||
|
// Read two char vectors from the string to perform the match.
|
||||||
|
var compare0 = Unsafe.ReadUnaligned<Vector<short>>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref str, offset)));
|
||||||
|
var compare1 = Unsafe.ReadUnaligned<Vector<short>>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref str, offset + Vector<ushort>.Count)));
|
||||||
|
|
||||||
|
// If the string is not ascii, then the widened bytes cannot match
|
||||||
|
// as each widened byte element as chars will be in the range 0-255
|
||||||
|
// so cannot match any higher unicode values.
|
||||||
|
|
||||||
|
// Compare to our all bits true comparision vector
|
||||||
|
if (!AllTrue.Equals(
|
||||||
|
// BitwiseAnd the two equals together
|
||||||
|
Vector.BitwiseAnd(
|
||||||
|
// Check equality for the two widened vectors
|
||||||
|
Vector.Equals(compare0, vector0),
|
||||||
|
Vector.Equals(compare1, vector1))))
|
||||||
|
{
|
||||||
|
goto NotEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += Vector<byte>.Count;
|
||||||
|
} while ((byte*)(offset + Vector<byte>.Count) <= (byte*)count);
|
||||||
|
|
||||||
|
// Vector path done, loop back to do non-Vector
|
||||||
|
// If is a exact multiple of vector size, bail now
|
||||||
|
} while ((byte*)offset < (byte*)count);
|
||||||
|
|
||||||
|
// If we get here (input is exactly a multiple of Vector length) then there are no inequalities via widening;
|
||||||
|
// so the input bytes are both ascii and a match to the string if it was converted via Encoding.ASCII.GetString(...)
|
||||||
|
return true;
|
||||||
|
NotEqual:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a DWORD which represents a buffer of 4 bytes, widens the buffer into 4 WORDs and
|
||||||
|
/// compares them to the WORD buffer with machine endianness.
|
||||||
|
/// </summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
private static bool WidenFourAsciiBytesToUtf16AndCompareToChars(ref char charStart, uint value)
|
||||||
|
{
|
||||||
|
if (!AllBytesInUInt32AreAscii(value))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Bmi2.X64.IsSupported)
|
||||||
|
{
|
||||||
|
// BMI2 will work regardless of the processor's endianness.
|
||||||
|
return Unsafe.ReadUnaligned<ulong>(ref Unsafe.As<char, byte>(ref charStart)) ==
|
||||||
|
Bmi2.X64.ParallelBitDeposit(value, 0x00FF00FF_00FF00FFul);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
return charStart == (char)(byte)value &&
|
||||||
|
Unsafe.Add(ref charStart, 1) == (char)(byte)(value >> 8) &&
|
||||||
|
Unsafe.Add(ref charStart, 2) == (char)(byte)(value >> 16) &&
|
||||||
|
Unsafe.Add(ref charStart, 3) == (char)(value >> 24);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Unsafe.Add(ref charStart, 3) == (char)(byte)value &&
|
||||||
|
Unsafe.Add(ref charStart, 2) == (char)(byte)(value >> 8) &&
|
||||||
|
Unsafe.Add(ref charStart, 1) == (char)(byte)(value >> 16) &&
|
||||||
|
charStart == (char)(value >> 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a WORD which represents a buffer of 2 bytes, widens the buffer into 2 WORDs and
|
||||||
|
/// compares them to the WORD buffer with machine endianness.
|
||||||
|
/// </summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
private static bool WidenTwoAsciiBytesToUtf16AndCompareToChars(ref char charStart, ushort value)
|
||||||
|
{
|
||||||
|
if (!AllBytesInUInt16AreAscii(value))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Bmi2.IsSupported)
|
||||||
|
{
|
||||||
|
// BMI2 will work regardless of the processor's endianness.
|
||||||
|
return Unsafe.ReadUnaligned<uint>(ref Unsafe.As<char, byte>(ref charStart)) ==
|
||||||
|
Bmi2.ParallelBitDeposit(value, 0x00FF00FFu);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
return charStart == (char)(byte)value &&
|
||||||
|
Unsafe.Add(ref charStart, 1) == (char)(byte)(value >> 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Unsafe.Add(ref charStart, 1) == (char)(byte)value &&
|
||||||
|
charStart == (char)(byte)(value >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <see langword="true"/> iff all bytes in <paramref name="value"/> are ASCII.
|
||||||
|
/// </summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static bool AllBytesInUInt32AreAscii(uint value)
|
||||||
|
{
|
||||||
|
return ((value & 0x80808080u) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <see langword="true"/> iff all bytes in <paramref name="value"/> are ASCII.
|
||||||
|
/// </summary>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static bool AllBytesInUInt16AreAscii(ushort value)
|
||||||
|
{
|
||||||
|
return ((value & 0x8080u) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe static bool IsValidHeaderString(string value)
|
||||||
|
{
|
||||||
|
// Method for Debug.Assert to ensure BytesOrdinalEqualsStringAndAscii
|
||||||
|
// is not called with an unvalidated string comparitor.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (value is null) return false;
|
||||||
|
new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true).GetByteCount(value);
|
||||||
|
return !value.Contains('\0');
|
||||||
|
}
|
||||||
|
catch (DecoderFallbackException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly char[] s_encode16Chars = "0123456789ABCDEF".ToCharArray();
|
private static readonly char[] s_encode16Chars = "0123456789ABCDEF".ToCharArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public bool AllowSynchronousIO { get; set; } = false;
|
public bool AllowSynchronousIO { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value that controls whether the string values materialized
|
||||||
|
/// will be reused across requests; if they match, or if the strings will always be reallocated.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Defaults to false.
|
||||||
|
/// </remarks>
|
||||||
|
public bool DisableStringReuse { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables the Listen options callback to resolve and use services registered by the application during startup.
|
/// Enables the Listen options callback to resolve and use services registered by the application during startup.
|
||||||
/// Typically initialized by UseKestrel()"/>.
|
/// Typically initialized by UseKestrel()"/>.
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,28 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
.Concat(byteRange)
|
.Concat(byteRange)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
var s = new Span<byte>(byteArray).GetAsciiStringNonNullCharacters();
|
var span = new Span<byte>(byteArray);
|
||||||
|
|
||||||
Assert.Equal(s.Length, byteArray.Length);
|
for (var i = 0; i <= byteArray.Length; i++)
|
||||||
|
|
||||||
for (var i = 1; i < byteArray.Length; i++)
|
|
||||||
{
|
{
|
||||||
var sb = (byte)s[i];
|
// Test all the lengths to hit all the different length paths e.g. Vector, long, short, char
|
||||||
var b = byteArray[i];
|
Test(span.Slice(i));
|
||||||
|
}
|
||||||
|
|
||||||
Assert.Equal(sb, b);
|
static void Test(Span<byte> asciiBytes)
|
||||||
|
{
|
||||||
|
var s = asciiBytes.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
|
Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes));
|
||||||
|
Assert.Equal(s.Length, asciiBytes.Length);
|
||||||
|
|
||||||
|
for (var i = 0; i < asciiBytes.Length; i++)
|
||||||
|
{
|
||||||
|
var sb = (byte)s[i];
|
||||||
|
var b = asciiBytes[i];
|
||||||
|
|
||||||
|
Assert.Equal(sb, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,8 +71,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
var byteRange = Enumerable.Range(0, 16384 + 64).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray();
|
var byteRange = Enumerable.Range(0, 16384 + 64).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray();
|
||||||
var expectedByteRange = byteRange.Concat(byteRange).ToArray();
|
var expectedByteRange = byteRange.Concat(byteRange).ToArray();
|
||||||
|
|
||||||
var s = new Span<byte>(expectedByteRange).GetAsciiStringNonNullCharacters();
|
var span = new Span<byte>(expectedByteRange);
|
||||||
|
var s = span.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
Assert.Equal(expectedByteRange.Length, s.Length);
|
Assert.Equal(expectedByteRange.Length, s.Length);
|
||||||
|
|
||||||
|
|
@ -68,8 +81,74 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
var sb = (byte)((s[i] & 0x7f) | 0x01);
|
var sb = (byte)((s[i] & 0x7f) | 0x01);
|
||||||
var b = expectedByteRange[i];
|
var b = expectedByteRange[i];
|
||||||
|
}
|
||||||
|
|
||||||
Assert.Equal(sb, b);
|
Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private void DifferentLengthsAreNotEqual()
|
||||||
|
{
|
||||||
|
var byteRange = Enumerable.Range(0, 4096).Select(x => (byte)((x & 0x7f) | 0x01)).ToArray();
|
||||||
|
var expectedByteRange = byteRange.Concat(byteRange).ToArray();
|
||||||
|
|
||||||
|
for (var i = 1; i < byteRange.Length; i++)
|
||||||
|
{
|
||||||
|
var span = new Span<byte>(expectedByteRange);
|
||||||
|
var s = span.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
|
Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span));
|
||||||
|
|
||||||
|
// One off end
|
||||||
|
Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span.Slice(0, span.Length - 1)));
|
||||||
|
Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s.Substring(0, s.Length - 1), span));
|
||||||
|
|
||||||
|
// One off start
|
||||||
|
Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, span.Slice(1, span.Length - 1)));
|
||||||
|
Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s.Substring(1, s.Length - 1), span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private void AsciiBytesEqualAsciiStrings()
|
||||||
|
{
|
||||||
|
var byteRange = Enumerable.Range(1, 127).Select(x => (byte)x);
|
||||||
|
|
||||||
|
var byteArray = byteRange
|
||||||
|
.Concat(byteRange)
|
||||||
|
.Concat(byteRange)
|
||||||
|
.Concat(byteRange)
|
||||||
|
.Concat(byteRange)
|
||||||
|
.Concat(byteRange)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var span = new Span<byte>(byteArray);
|
||||||
|
|
||||||
|
for (var i = 0; i <= byteArray.Length; i++)
|
||||||
|
{
|
||||||
|
// Test all the lengths to hit all the different length paths e.g. Vector, long, short, char
|
||||||
|
Test(span.Slice(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Test(Span<byte> asciiBytes)
|
||||||
|
{
|
||||||
|
var s = asciiBytes.GetAsciiStringNonNullCharacters();
|
||||||
|
|
||||||
|
// Should start as equal
|
||||||
|
Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes));
|
||||||
|
|
||||||
|
for (var i = 0; i < asciiBytes.Length; i++)
|
||||||
|
{
|
||||||
|
var b = asciiBytes[i];
|
||||||
|
|
||||||
|
// Change one byte, ensure is not equal
|
||||||
|
asciiBytes[i] = (byte)(b + 1);
|
||||||
|
Assert.False(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes));
|
||||||
|
|
||||||
|
// Change byte back for next iteration, ensure is equal again
|
||||||
|
asciiBytes[i] = b;
|
||||||
|
Assert.True(StringUtilities.BytesOrdinalEqualsStringAndAscii(s, asciiBytes));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
_decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters();
|
_decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IHttpHeadersHandler.OnHeadersComplete() { }
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void DecodesIndexedHeaderField_StaticTable()
|
public void DecodesIndexedHeaderField_StaticTable()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
Headers[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters();
|
Headers[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IHttpHeadersHandler.OnHeadersComplete() { }
|
||||||
|
|
||||||
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||||
{
|
{
|
||||||
Method = method != HttpMethod.Custom ? HttpUtilities.MethodToString(method) : customMethod.GetAsciiStringNonNullCharacters();
|
Method = method != HttpMethod.Custom ? HttpUtilities.MethodToString(method) : customMethod.GetAsciiStringNonNullCharacters();
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using static CodeGenerator.KnownHeaders;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
{
|
{
|
||||||
|
|
@ -307,8 +309,347 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
|
|
||||||
var encoding = Encoding.GetEncoding("iso-8859-1");
|
var encoding = Encoding.GetEncoding("iso-8859-1");
|
||||||
var exception = Assert.Throws<BadHttpRequestException>(
|
var exception = Assert.Throws<BadHttpRequestException>(
|
||||||
() => headers.Append(encoding.GetBytes(key), "value"));
|
() => headers.Append(encoding.GetBytes(key), Encoding.ASCII.GetBytes("value")));
|
||||||
Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
|
Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void ValueReuseOnlyWhenAllowed(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
const string HeaderValue = "Hello";
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
|
||||||
|
for (var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
var prevName = ChangeNameCase(header.Name, variant: i);
|
||||||
|
var nextName = ChangeNameCase(header.Name, variant: i + 1);
|
||||||
|
|
||||||
|
var values = GetHeaderValues(headers, prevName, nextName, HeaderValue, HeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue, values.PrevHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, values.PrevHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue, values.NextHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
if (reuseValue)
|
||||||
|
{
|
||||||
|
// When materalized string is reused previous and new should be the same object
|
||||||
|
Assert.Same(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// When materalized string is not reused previous and new should be the different objects
|
||||||
|
Assert.NotSame(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void ValueReuseChangedValuesOverwrite(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
const string HeaderValue1 = "Hello1";
|
||||||
|
const string HeaderValue2 = "Hello2";
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
|
||||||
|
for (var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
var prevName = ChangeNameCase(header.Name, variant: i);
|
||||||
|
var nextName = ChangeNameCase(header.Name, variant: i + 1);
|
||||||
|
|
||||||
|
var values = GetHeaderValues(headers, prevName, nextName, HeaderValue1, HeaderValue2);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue1, values.PrevHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue1, values.PrevHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue2, values.NextHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue2, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.NotEqual(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void ValueReuseMissingValuesClear(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
const string HeaderValue1 = "Hello1";
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
|
||||||
|
for (var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
var prevName = ChangeNameCase(header.Name, variant: i);
|
||||||
|
var nextName = ChangeNameCase(header.Name, variant: i + 1);
|
||||||
|
|
||||||
|
var values = GetHeaderValues(headers, prevName, nextName, HeaderValue1, nextValue: null);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue1, values.PrevHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue1, values.PrevHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(string.Empty, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.NotEqual(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void ValueReuseNeverWhenNotAscii(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
const string HeaderValue = "Hello \u03a0";
|
||||||
|
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
|
||||||
|
for (var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
var prevName = ChangeNameCase(header.Name, variant: i);
|
||||||
|
var nextName = ChangeNameCase(header.Name, variant: i + 1);
|
||||||
|
|
||||||
|
var values = GetHeaderValues(headers, prevName, nextName, HeaderValue, HeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue, values.PrevHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, values.PrevHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue, values.NextHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.NotSame(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void ValueReuseLatin1NotConfusedForUtf16AndStillRejected(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
|
||||||
|
var headerValue = new char[127]; // 64 + 32 + 16 + 8 + 4 + 2 + 1
|
||||||
|
for (var i = 0; i < headerValue.Length; i++)
|
||||||
|
{
|
||||||
|
headerValue[i] = 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < headerValue.Length; i++)
|
||||||
|
{
|
||||||
|
// Set non-ascii Latin char that is valid Utf16 when widened; but not a valid utf8 -> utf16 conversion.
|
||||||
|
headerValue[i] = '\u00a3';
|
||||||
|
|
||||||
|
for (var mode = 0; mode <= 1; mode++)
|
||||||
|
{
|
||||||
|
string headerValueUtf16Latin1CrossOver;
|
||||||
|
if (mode == 0)
|
||||||
|
{
|
||||||
|
// Full length
|
||||||
|
headerValueUtf16Latin1CrossOver = new string(headerValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Truncated length (to ensure different paths from changing lengths in matching)
|
||||||
|
headerValueUtf16Latin1CrossOver = new string(headerValue.AsSpan().Slice(0, i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
headers.Reset();
|
||||||
|
|
||||||
|
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
|
||||||
|
var prevSpan = Encoding.UTF8.GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();
|
||||||
|
|
||||||
|
headers.Append(headerName, prevSpan);
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
|
||||||
|
|
||||||
|
Assert.Equal(headerValueUtf16Latin1CrossOver, prevHeaderValue);
|
||||||
|
Assert.NotSame(headerValueUtf16Latin1CrossOver, prevHeaderValue);
|
||||||
|
|
||||||
|
headers.Reset();
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
|
{
|
||||||
|
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
|
||||||
|
var nextSpan = Encoding.GetEncoding("iso-8859-1").GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();
|
||||||
|
|
||||||
|
Assert.False(nextSpan.SequenceEqual(Encoding.ASCII.GetBytes(headerValueUtf16Latin1CrossOver)));
|
||||||
|
|
||||||
|
headers.Append(headerName, nextSpan);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset back to Ascii
|
||||||
|
headerValue[i] = 'a';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ValueReuseNeverWhenUnknownHeader()
|
||||||
|
{
|
||||||
|
const string HeaderName = "An-Unknown-Header";
|
||||||
|
const string HeaderValue = "Hello";
|
||||||
|
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: true);
|
||||||
|
|
||||||
|
for (var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
var prevName = ChangeNameCase(HeaderName, variant: i);
|
||||||
|
var nextName = ChangeNameCase(HeaderName, variant: i + 1);
|
||||||
|
|
||||||
|
var values = GetHeaderValues(headers, prevName, nextName, HeaderValue, HeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue, values.PrevHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, values.PrevHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(HeaderValue, values.NextHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.Equal(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
|
||||||
|
Assert.NotSame(values.PrevHeaderValue, values.NextHeaderValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void ValueReuseEmptyAfterReset(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
const string HeaderValue = "Hello";
|
||||||
|
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
|
||||||
|
var prevSpan = Encoding.UTF8.GetBytes(HeaderValue).AsSpan();
|
||||||
|
|
||||||
|
headers.Append(headerName, prevSpan);
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
|
||||||
|
|
||||||
|
Assert.NotNull(prevHeaderValue);
|
||||||
|
Assert.NotEqual(string.Empty, prevHeaderValue);
|
||||||
|
Assert.Equal(HeaderValue, prevHeaderValue);
|
||||||
|
Assert.NotSame(HeaderValue, prevHeaderValue);
|
||||||
|
Assert.Single(headers);
|
||||||
|
var count = headers.Count;
|
||||||
|
Assert.Equal(1, count);
|
||||||
|
|
||||||
|
headers.Reset();
|
||||||
|
|
||||||
|
// Empty after reset
|
||||||
|
var nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
|
||||||
|
|
||||||
|
Assert.NotNull(nextHeaderValue);
|
||||||
|
Assert.Equal(string.Empty, nextHeaderValue);
|
||||||
|
Assert.NotEqual(HeaderValue, nextHeaderValue);
|
||||||
|
Assert.Empty(headers);
|
||||||
|
count = headers.Count;
|
||||||
|
Assert.Equal(0, count);
|
||||||
|
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
|
||||||
|
// Still empty after complete
|
||||||
|
nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
|
||||||
|
|
||||||
|
Assert.NotNull(nextHeaderValue);
|
||||||
|
Assert.Equal(string.Empty, nextHeaderValue);
|
||||||
|
Assert.NotEqual(HeaderValue, nextHeaderValue);
|
||||||
|
Assert.Empty(headers);
|
||||||
|
count = headers.Count;
|
||||||
|
Assert.Equal(0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(KnownRequestHeaders))]
|
||||||
|
public void MultiValueReuseEmptyAfterReset(bool reuseValue, KnownHeader header)
|
||||||
|
{
|
||||||
|
const string HeaderValue1 = "Hello1";
|
||||||
|
const string HeaderValue2 = "Hello2";
|
||||||
|
|
||||||
|
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
|
||||||
|
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
|
||||||
|
var prevSpan1 = Encoding.UTF8.GetBytes(HeaderValue1).AsSpan();
|
||||||
|
var prevSpan2 = Encoding.UTF8.GetBytes(HeaderValue2).AsSpan();
|
||||||
|
|
||||||
|
headers.Append(headerName, prevSpan1);
|
||||||
|
headers.Append(headerName, prevSpan2);
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name];
|
||||||
|
|
||||||
|
Assert.Equal(2, prevHeaderValue.Count);
|
||||||
|
|
||||||
|
Assert.NotEqual(string.Empty, prevHeaderValue.ToString());
|
||||||
|
Assert.Single(headers);
|
||||||
|
var count = headers.Count;
|
||||||
|
Assert.Equal(1, count);
|
||||||
|
|
||||||
|
headers.Reset();
|
||||||
|
|
||||||
|
// Empty after reset
|
||||||
|
var nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
|
||||||
|
|
||||||
|
Assert.NotNull(nextHeaderValue);
|
||||||
|
Assert.Equal(string.Empty, nextHeaderValue);
|
||||||
|
Assert.Empty(headers);
|
||||||
|
count = headers.Count;
|
||||||
|
Assert.Equal(0, count);
|
||||||
|
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
|
||||||
|
// Still empty after complete
|
||||||
|
nextHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
|
||||||
|
|
||||||
|
Assert.NotNull(nextHeaderValue);
|
||||||
|
Assert.Equal(string.Empty, nextHeaderValue);
|
||||||
|
Assert.Empty(headers);
|
||||||
|
count = headers.Count;
|
||||||
|
Assert.Equal(0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (string PrevHeaderValue, string NextHeaderValue) GetHeaderValues(HttpRequestHeaders headers, string prevName, string nextName, string prevValue, string nextValue)
|
||||||
|
{
|
||||||
|
headers.Reset();
|
||||||
|
var headerName = Encoding.ASCII.GetBytes(prevName).AsSpan();
|
||||||
|
var prevSpan = Encoding.UTF8.GetBytes(prevValue).AsSpan();
|
||||||
|
|
||||||
|
headers.Append(headerName, prevSpan);
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
var prevHeaderValue = ((IHeaderDictionary)headers)[prevName].ToString();
|
||||||
|
|
||||||
|
headers.Reset();
|
||||||
|
|
||||||
|
if (nextValue != null)
|
||||||
|
{
|
||||||
|
headerName = Encoding.ASCII.GetBytes(prevName).AsSpan();
|
||||||
|
var nextSpan = Encoding.UTF8.GetBytes(nextValue).AsSpan();
|
||||||
|
headers.Append(headerName, nextSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
headers.OnHeadersComplete();
|
||||||
|
|
||||||
|
var newHeaderValue = ((IHeaderDictionary)headers)[nextName].ToString();
|
||||||
|
|
||||||
|
return (prevHeaderValue, newHeaderValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ChangeNameCase(string name, int variant)
|
||||||
|
{
|
||||||
|
switch ((variant / 2) % 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return name;
|
||||||
|
case 1:
|
||||||
|
return name.ToLowerInvariant();
|
||||||
|
case 2:
|
||||||
|
return name.ToUpperInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Never reached
|
||||||
|
Assert.False(true);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content-Length is numeric not a string, so we exclude it from the string reuse tests
|
||||||
|
public static IEnumerable<object[]> KnownRequestHeaders =>
|
||||||
|
RequestHeaders.Where(h => h.Name != "Content-Length").Select(h => new object[] { true, h }).Concat(
|
||||||
|
RequestHeaders.Where(h => h.Name != "Content-Length").Select(h => new object[] { false, h }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
<Compile Include="$(SharedSourceRoot)NullScope.cs" />
|
<Compile Include="$(SharedSourceRoot)NullScope.cs" />
|
||||||
<Compile Include="$(SharedSourceRoot)Buffers.Testing\*.cs" />
|
<Compile Include="$(SharedSourceRoot)Buffers.Testing\*.cs" />
|
||||||
<Compile Include="$(KestrelSharedSourceRoot)test\*.cs" LinkBase="shared" />
|
<Compile Include="$(KestrelSharedSourceRoot)test\*.cs" LinkBase="shared" />
|
||||||
|
<Compile Include="$(KestrelSharedSourceRoot)KnownHeaders.cs" LinkBase="shared" />
|
||||||
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
<Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,536 @@
|
||||||
|
// 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.IO.Pipelines;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
||||||
|
{
|
||||||
|
public class StartLineTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly static IKestrelTrace _trace = Mock.Of<IKestrelTrace>();
|
||||||
|
|
||||||
|
private IDuplexPipe Transport { get; }
|
||||||
|
private MemoryPool<byte> MemoryPool { get; }
|
||||||
|
private Http1Connection Http1Connection { get; }
|
||||||
|
private Http1ParsingHandler ParsingHandler {get;}
|
||||||
|
private IHttpParser<Http1ParsingHandler> Parser { get; }
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InOriginForm()
|
||||||
|
{
|
||||||
|
var rawTarget = "/path%20with%20spaces?q=123&w=xyzw1";
|
||||||
|
var path = "/path with spaces";
|
||||||
|
var query = "?q=123&w=xyzw1";
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"POST {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
Assert.NotSame(query, Http1Connection.QueryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InAuthorityForm()
|
||||||
|
{
|
||||||
|
var rawTarget = "example.com:1234";
|
||||||
|
var path = string.Empty;
|
||||||
|
var query = string.Empty;
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
// Empty strings, so interned and the same.
|
||||||
|
Assert.Same(path, Http1Connection.Path);
|
||||||
|
Assert.Same(query, Http1Connection.QueryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InAbsoluteForm()
|
||||||
|
{
|
||||||
|
var rawTarget = "http://localhost/path1?q=123&w=xyzw";
|
||||||
|
var path = "/path1";
|
||||||
|
var query = "?q=123&w=xyzw";
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
Assert.NotSame(query, Http1Connection.QueryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InAsteriskForm()
|
||||||
|
{
|
||||||
|
var rawTarget = "*";
|
||||||
|
var path = string.Empty;
|
||||||
|
var query = string.Empty;
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"OPTIONS {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Asterisk is interned string, so the same.
|
||||||
|
Assert.Same(rawTarget, Http1Connection.RawTarget);
|
||||||
|
// Empty strings, so interned and the same.
|
||||||
|
Assert.Same(path, Http1Connection.Path);
|
||||||
|
Assert.Same(query, Http1Connection.QueryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DifferentFormsWorkTogether()
|
||||||
|
{
|
||||||
|
// InOriginForm
|
||||||
|
var rawTarget = "/a%20path%20with%20spaces?q=123&w=xyzw12";
|
||||||
|
var path = "/a path with spaces";
|
||||||
|
var query = "?q=123&w=xyzw12";
|
||||||
|
Http1Connection.Reset();
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"POST {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
Assert.NotSame(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
InAuthorityForm();
|
||||||
|
|
||||||
|
InOriginForm();
|
||||||
|
InAbsoluteForm();
|
||||||
|
|
||||||
|
InOriginForm();
|
||||||
|
InAsteriskForm();
|
||||||
|
|
||||||
|
InAuthorityForm();
|
||||||
|
InAsteriskForm();
|
||||||
|
|
||||||
|
InAbsoluteForm();
|
||||||
|
InAuthorityForm();
|
||||||
|
|
||||||
|
InAbsoluteForm();
|
||||||
|
InAsteriskForm();
|
||||||
|
|
||||||
|
InAbsoluteForm();
|
||||||
|
InAuthorityForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("/abs/path", "/abs/path", "")]
|
||||||
|
[InlineData("/", "/", "")]
|
||||||
|
[InlineData("/path", "/path", "")]
|
||||||
|
[InlineData("/?q=123&w=xyz", "/", "?q=123&w=xyz")]
|
||||||
|
[InlineData("/path?q=123&w=xyz", "/path", "?q=123&w=xyz")]
|
||||||
|
[InlineData("/path%20with%20space?q=abc%20123", "/path with space", "?q=abc%20123")]
|
||||||
|
public void OriginForms(string rawTarget, string path, string query)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
var prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
var prevPath = Http1Connection.Path;
|
||||||
|
var prevQuery = Http1Connection.QueryString;
|
||||||
|
|
||||||
|
// Identical requests keep same materialized string values
|
||||||
|
for (var i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Parser decodes % encoding in place, so we need to recreate the ROS
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
// string.Empty is used for empty strings, so should be the same.
|
||||||
|
Assert.True(query.Length == 0 || !ReferenceEquals(query, Http1Connection.QueryString));
|
||||||
|
|
||||||
|
// However, materalized strings are reused if generated for previous requests.
|
||||||
|
|
||||||
|
Assert.Same(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.Same(prevPath, Http1Connection.Path);
|
||||||
|
Assert.Same(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
prevPath = Http1Connection.Path;
|
||||||
|
prevQuery = Http1Connection.QueryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different OriginForm request changes values
|
||||||
|
|
||||||
|
rawTarget = "/path1?q=123&w=xyzw";
|
||||||
|
path = "/path1";
|
||||||
|
query = "?q=123&w=xyzw";
|
||||||
|
|
||||||
|
Http1Connection.Reset();
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Parser.ParseRequestLine(ParsingHandler, ros, out _, out _);
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
Assert.NotSame(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Not equal previous request.
|
||||||
|
Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.NotEqual(prevPath, Http1Connection.Path);
|
||||||
|
Assert.NotEqual(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
DifferentFormsWorkTogether();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("http://localhost/abs/path", "/abs/path", "")]
|
||||||
|
[InlineData("https://localhost/abs/path", "/abs/path", "")] // handles mismatch scheme
|
||||||
|
[InlineData("https://localhost:22/abs/path", "/abs/path", "")] // handles mismatched ports
|
||||||
|
[InlineData("https://differenthost/abs/path", "/abs/path", "")] // handles mismatched hostname
|
||||||
|
[InlineData("http://localhost/", "/", "")]
|
||||||
|
[InlineData("http://root@contoso.com/path", "/path", "")]
|
||||||
|
[InlineData("http://root:password@contoso.com/path", "/path", "")]
|
||||||
|
[InlineData("https://localhost/", "/", "")]
|
||||||
|
[InlineData("http://localhost", "/", "")]
|
||||||
|
[InlineData("http://127.0.0.1/", "/", "")]
|
||||||
|
[InlineData("http://[::1]/", "/", "")]
|
||||||
|
[InlineData("http://[::1]:8080/", "/", "")]
|
||||||
|
[InlineData("http://localhost?q=123&w=xyz", "/", "?q=123&w=xyz")]
|
||||||
|
[InlineData("http://localhost/?q=123&w=xyz", "/", "?q=123&w=xyz")]
|
||||||
|
[InlineData("http://localhost/path?q=123&w=xyz", "/path", "?q=123&w=xyz")]
|
||||||
|
[InlineData("http://localhost/path%20with%20space?q=abc%20123", "/path with space", "?q=abc%20123")]
|
||||||
|
public void AbsoluteForms(string rawTarget, string path, string query)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
var prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
var prevPath = Http1Connection.Path;
|
||||||
|
var prevQuery = Http1Connection.QueryString;
|
||||||
|
|
||||||
|
// Identical requests keep same materialized string values
|
||||||
|
for (var i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
// string.Empty is used for empty strings, so should be the same.
|
||||||
|
Assert.True(query.Length == 0 || !ReferenceEquals(query, Http1Connection.QueryString));
|
||||||
|
|
||||||
|
// However, materalized strings are reused if generated for previous requests.
|
||||||
|
|
||||||
|
Assert.Same(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.Same(prevPath, Http1Connection.Path);
|
||||||
|
Assert.Same(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
prevPath = Http1Connection.Path;
|
||||||
|
prevQuery = Http1Connection.QueryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different Absolute Form request changes values
|
||||||
|
|
||||||
|
rawTarget = "http://localhost/path1?q=123&w=xyzw";
|
||||||
|
path = "/path1";
|
||||||
|
query = "?q=123&w=xyzw";
|
||||||
|
|
||||||
|
Http1Connection.Reset();
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Parser.ParseRequestLine(ParsingHandler, ros, out _, out _);
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
Assert.NotSame(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Not equal previous request.
|
||||||
|
Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.NotEqual(prevPath, Http1Connection.Path);
|
||||||
|
Assert.NotEqual(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
DifferentFormsWorkTogether();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AsteriskForms()
|
||||||
|
{
|
||||||
|
var rawTarget = "*";
|
||||||
|
var path = string.Empty;
|
||||||
|
var query = string.Empty;
|
||||||
|
|
||||||
|
Http1Connection.Reset();
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"OPTIONS {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
var prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
var prevPath = Http1Connection.Path;
|
||||||
|
var prevQuery = Http1Connection.QueryString;
|
||||||
|
|
||||||
|
// Identical requests keep same materialized string values
|
||||||
|
for (var i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"OPTIONS {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Also same as the inputs (interned strings).
|
||||||
|
|
||||||
|
Assert.Same(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Same(path, Http1Connection.Path);
|
||||||
|
Assert.Same(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Materalized strings are reused if generated for previous requests.
|
||||||
|
|
||||||
|
Assert.Same(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.Same(prevPath, Http1Connection.Path);
|
||||||
|
Assert.Same(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
prevPath = Http1Connection.Path;
|
||||||
|
prevQuery = Http1Connection.QueryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different request changes values (can't be Astrisk Form as all the same)
|
||||||
|
rawTarget = "http://localhost/path1?q=123&w=xyzw";
|
||||||
|
path = "/path1";
|
||||||
|
query = "?q=123&w=xyzw";
|
||||||
|
|
||||||
|
Http1Connection.Reset();
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"GET {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Parser.ParseRequestLine(ParsingHandler, ros, out _, out _);
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.NotSame(path, Http1Connection.Path);
|
||||||
|
Assert.NotSame(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Not equal previous request.
|
||||||
|
Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.NotEqual(prevPath, Http1Connection.Path);
|
||||||
|
Assert.NotEqual(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
DifferentFormsWorkTogether();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("localhost", "", "")]
|
||||||
|
[InlineData("localhost:22", "", "")] // handles mismatched ports
|
||||||
|
[InlineData("differenthost", "", "")] // handles mismatched hostname
|
||||||
|
[InlineData("127.0.0.1", "", "")]
|
||||||
|
[InlineData("[::1]", "", "")]
|
||||||
|
[InlineData("[::1]:8080", "", "")]
|
||||||
|
public void AuthorityForms(string rawTarget, string path, string query)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
var ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
var prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
var prevPath = Http1Connection.Path;
|
||||||
|
var prevQuery = Http1Connection.QueryString;
|
||||||
|
|
||||||
|
// Identical requests keep same materialized string values
|
||||||
|
for (var i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
Http1Connection.Reset();
|
||||||
|
// RawTarget, Path, QueryString are null after reset
|
||||||
|
Assert.Null(Http1Connection.RawTarget);
|
||||||
|
Assert.Null(Http1Connection.Path);
|
||||||
|
Assert.Null(Http1Connection.QueryString);
|
||||||
|
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Assert.True(Parser.ParseRequestLine(ParsingHandler, ros, out _, out _));
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// RawTarget not the same as the input.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
// Others same as the inputs, empty strings.
|
||||||
|
Assert.Same(path, Http1Connection.Path);
|
||||||
|
Assert.Same(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// However, materalized strings are reused if generated for previous requests.
|
||||||
|
|
||||||
|
Assert.Same(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
Assert.Same(prevPath, Http1Connection.Path);
|
||||||
|
Assert.Same(prevQuery, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
prevRequestUrl = Http1Connection.RawTarget;
|
||||||
|
prevPath = Http1Connection.Path;
|
||||||
|
prevQuery = Http1Connection.QueryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different Authority Form request changes values
|
||||||
|
rawTarget = "example.org:2345";
|
||||||
|
path = "";
|
||||||
|
query = "";
|
||||||
|
|
||||||
|
Http1Connection.Reset();
|
||||||
|
ros = new ReadOnlySequence<byte>(Encoding.ASCII.GetBytes($"CONNECT {rawTarget} HTTP/1.1\r\n"));
|
||||||
|
Parser.ParseRequestLine(ParsingHandler, ros, out _, out _);
|
||||||
|
|
||||||
|
// Equal the inputs.
|
||||||
|
Assert.Equal(rawTarget, Http1Connection.RawTarget);
|
||||||
|
Assert.Equal(path, Http1Connection.Path);
|
||||||
|
Assert.Equal(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// But not the same as the inputs.
|
||||||
|
Assert.NotSame(rawTarget, Http1Connection.RawTarget);
|
||||||
|
// Empty interned strings
|
||||||
|
Assert.Same(path, Http1Connection.Path);
|
||||||
|
Assert.Same(query, Http1Connection.QueryString);
|
||||||
|
|
||||||
|
// Not equal previous request.
|
||||||
|
Assert.NotEqual(prevRequestUrl, Http1Connection.RawTarget);
|
||||||
|
|
||||||
|
DifferentFormsWorkTogether();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StartLineTests()
|
||||||
|
{
|
||||||
|
MemoryPool = KestrelMemoryPool.Create();
|
||||||
|
var options = new PipeOptions(MemoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false);
|
||||||
|
var pair = DuplexPipe.CreateConnectionPair(options, options);
|
||||||
|
Transport = pair.Transport;
|
||||||
|
|
||||||
|
var serviceContext = new ServiceContext
|
||||||
|
{
|
||||||
|
ServerOptions = new KestrelServerOptions(),
|
||||||
|
Log = _trace,
|
||||||
|
HttpParser = new HttpParser<Http1ParsingHandler>()
|
||||||
|
};
|
||||||
|
|
||||||
|
Http1Connection = new Http1Connection(context: new HttpConnectionContext
|
||||||
|
{
|
||||||
|
ServiceContext = serviceContext,
|
||||||
|
ConnectionFeatures = new FeatureCollection(),
|
||||||
|
MemoryPool = MemoryPool,
|
||||||
|
Transport = Transport,
|
||||||
|
TimeoutControl = new TimeoutControl(timeoutHandler: null)
|
||||||
|
});
|
||||||
|
|
||||||
|
Parser = new HttpParser<Http1ParsingHandler>(showErrorDetails: true);
|
||||||
|
ParsingHandler = new Http1ParsingHandler(Http1Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Transport.Input.Complete();
|
||||||
|
Transport.Output.Complete();
|
||||||
|
|
||||||
|
MemoryPool.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -107,6 +107,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
public void OnHeader(Span<byte> name, Span<byte> value)
|
public void OnHeader(Span<byte> name, Span<byte> value)
|
||||||
=> RequestHandler.Connection.OnHeader(name, value);
|
=> RequestHandler.Connection.OnHeader(name, value);
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
=> RequestHandler.Connection.OnHeadersComplete();
|
||||||
|
|
||||||
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||||
=> RequestHandler.Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
=> RequestHandler.Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private struct Adapter : IHttpRequestLineHandler, IHttpHeadersHandler
|
private struct Adapter : IHttpRequestLineHandler, IHttpHeadersHandler
|
||||||
{
|
{
|
||||||
public HttpParserBenchmark RequestHandler;
|
public HttpParserBenchmark RequestHandler;
|
||||||
|
|
@ -84,6 +88,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
public void OnHeader(Span<byte> name, Span<byte> value)
|
public void OnHeader(Span<byte> name, Span<byte> value)
|
||||||
=> RequestHandler.OnHeader(name, value);
|
=> RequestHandler.OnHeader(name, value);
|
||||||
|
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
=> RequestHandler.OnHeadersComplete();
|
||||||
|
|
||||||
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||||
=> RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
=> RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
|
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
|
||||||
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
|
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
|
||||||
handler.OnHeader(new Span<byte>(_connectionHeaderName), new Span<byte>(_connectionHeaderValue));
|
handler.OnHeader(new Span<byte>(_connectionHeaderName), new Span<byte>(_connectionHeaderValue));
|
||||||
|
handler.OnHeadersComplete();
|
||||||
|
|
||||||
consumedBytes = 0;
|
consumedBytes = 0;
|
||||||
consumed = buffer.Start;
|
consumed = buffer.Start;
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,12 @@ namespace PlatformBenchmarks
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NETCOREAPP3_0
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public async ValueTask OnReadCompletedAsync()
|
public async ValueTask OnReadCompletedAsync()
|
||||||
{
|
{
|
||||||
await Writer.FlushAsync();
|
await Writer.FlushAsync();
|
||||||
|
|
@ -175,6 +181,11 @@ namespace PlatformBenchmarks
|
||||||
|
|
||||||
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||||
=> RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
=> RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
|
||||||
|
|
||||||
|
#if NETCOREAPP3_0
|
||||||
|
public void OnHeadersComplete()
|
||||||
|
=> RequestHandler.OnHeadersComplete();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,114 +11,11 @@ namespace CodeGenerator
|
||||||
{
|
{
|
||||||
public class KnownHeaders
|
public class KnownHeaders
|
||||||
{
|
{
|
||||||
static string Each<T>(IEnumerable<T> values, Func<T, string> formatter)
|
public readonly static KnownHeader[] RequestHeaders;
|
||||||
{
|
public readonly static KnownHeader[] ResponseHeaders;
|
||||||
return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : "";
|
public readonly static KnownHeader[] ResponseTrailers;
|
||||||
}
|
|
||||||
|
|
||||||
static string AppendSwitch(IEnumerable<IGrouping<int, KnownHeader>> values, string className) =>
|
static KnownHeaders()
|
||||||
$@"var pUL = (ulong*)pUB;
|
|
||||||
var pUI = (uint*)pUB;
|
|
||||||
var pUS = (ushort*)pUB;
|
|
||||||
var stringValue = new StringValues(value);
|
|
||||||
switch (keyLength)
|
|
||||||
{{{Each(values, byLength => $@"
|
|
||||||
case {byLength.Key}:
|
|
||||||
{{{Each(byLength, header => $@"
|
|
||||||
if ({header.EqualIgnoreCaseBytes()})
|
|
||||||
{{{(header.Identifier == "ContentLength" ? $@"
|
|
||||||
if (_contentLength.HasValue)
|
|
||||||
{{
|
|
||||||
BadHttpRequestException.Throw(RequestRejectionReason.MultipleContentLengths);
|
|
||||||
}}
|
|
||||||
else
|
|
||||||
{{
|
|
||||||
_contentLength = ParseContentLength(value);
|
|
||||||
}}
|
|
||||||
return;" : $@"
|
|
||||||
if ({header.TestBit()})
|
|
||||||
{{
|
|
||||||
_headers._{header.Identifier} = AppendValue(_headers._{header.Identifier}, value);
|
|
||||||
}}
|
|
||||||
else
|
|
||||||
{{
|
|
||||||
{header.SetBit()};
|
|
||||||
_headers._{header.Identifier} = stringValue;{(header.EnhancedSetter == false ? "" : $@"
|
|
||||||
_headers._raw{header.Identifier} = null;")}
|
|
||||||
}}
|
|
||||||
return;")}
|
|
||||||
}}
|
|
||||||
")}}}
|
|
||||||
break;
|
|
||||||
")}}}";
|
|
||||||
|
|
||||||
class KnownHeader
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public int Index { get; set; }
|
|
||||||
public string Identifier => Name.Replace("-", "");
|
|
||||||
|
|
||||||
public byte[] Bytes => Encoding.ASCII.GetBytes($"\r\n{Name}: ");
|
|
||||||
public int BytesOffset { get; set; }
|
|
||||||
public int BytesCount { get; set; }
|
|
||||||
public bool ExistenceCheck { get; set; }
|
|
||||||
public bool FastCount { get; set; }
|
|
||||||
public bool EnhancedSetter { get; set; }
|
|
||||||
public bool PrimaryHeader { get; set; }
|
|
||||||
public string TestBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) != 0";
|
|
||||||
public string TestTempBit() => $"(tempBits & {"0x" + (1L << Index).ToString("x")}L) != 0";
|
|
||||||
public string TestNotTempBit() => $"(tempBits & ~{"0x" + (1L << Index).ToString("x")}L) == 0";
|
|
||||||
public string TestNotBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) == 0";
|
|
||||||
public string SetBit() => $"_bits |= {"0x" + (1L << Index).ToString("x")}L";
|
|
||||||
public string ClearBit() => $"_bits &= ~{"0x" + (1L << Index).ToString("x")}L";
|
|
||||||
|
|
||||||
public string EqualIgnoreCaseBytes()
|
|
||||||
{
|
|
||||||
var result = "";
|
|
||||||
var delim = "";
|
|
||||||
var index = 0;
|
|
||||||
while (index != Name.Length)
|
|
||||||
{
|
|
||||||
if (Name.Length - index >= 8)
|
|
||||||
{
|
|
||||||
result += delim + Term(Name, index, 8, "pUL", "uL");
|
|
||||||
index += 8;
|
|
||||||
}
|
|
||||||
else if (Name.Length - index >= 4)
|
|
||||||
{
|
|
||||||
result += delim + Term(Name, index, 4, "pUI", "u");
|
|
||||||
index += 4;
|
|
||||||
}
|
|
||||||
else if (Name.Length - index >= 2)
|
|
||||||
{
|
|
||||||
result += delim + Term(Name, index, 2, "pUS", "u");
|
|
||||||
index += 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result += delim + Term(Name, index, 1, "pUB", "u");
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
delim = " && ";
|
|
||||||
}
|
|
||||||
return $"({result})";
|
|
||||||
}
|
|
||||||
protected string Term(string name, int offset, int count, string array, string suffix)
|
|
||||||
{
|
|
||||||
ulong mask = 0;
|
|
||||||
ulong comp = 0;
|
|
||||||
for (var scan = 0; scan < count; scan++)
|
|
||||||
{
|
|
||||||
var ch = (byte)name[offset + count - scan - 1];
|
|
||||||
var isAlpha = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
|
||||||
comp = (comp << 8) + (ch & (isAlpha ? 0xdfu : 0xffu));
|
|
||||||
mask = (mask << 8) + (isAlpha ? 0xdfu : 0xffu);
|
|
||||||
}
|
|
||||||
return $"(({array}[{offset / count}] & {mask}{suffix}) == {comp}{suffix})";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GeneratedFile()
|
|
||||||
{
|
{
|
||||||
var requestPrimaryHeaders = new[]
|
var requestPrimaryHeaders = new[]
|
||||||
{
|
{
|
||||||
|
|
@ -173,7 +70,7 @@ namespace CodeGenerator
|
||||||
{
|
{
|
||||||
"Host"
|
"Host"
|
||||||
};
|
};
|
||||||
var requestHeaders = commonHeaders.Concat(new[]
|
RequestHeaders = commonHeaders.Concat(new[]
|
||||||
{
|
{
|
||||||
"Accept",
|
"Accept",
|
||||||
"Accept-Charset",
|
"Accept-Charset",
|
||||||
|
|
@ -196,6 +93,8 @@ namespace CodeGenerator
|
||||||
"TE",
|
"TE",
|
||||||
"Translate",
|
"Translate",
|
||||||
"User-Agent",
|
"User-Agent",
|
||||||
|
"DNT",
|
||||||
|
"Upgrade-Insecure-Requests"
|
||||||
})
|
})
|
||||||
.Concat(corsRequestHeaders)
|
.Concat(corsRequestHeaders)
|
||||||
.Select((header, index) => new KnownHeader
|
.Select((header, index) => new KnownHeader
|
||||||
|
|
@ -213,8 +112,6 @@ namespace CodeGenerator
|
||||||
PrimaryHeader = requestPrimaryHeaders.Contains("Content-Length")
|
PrimaryHeader = requestPrimaryHeaders.Contains("Content-Length")
|
||||||
}})
|
}})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
Debug.Assert(requestHeaders.Length <= 64);
|
|
||||||
Debug.Assert(requestHeaders.Max(x => x.Index) <= 62);
|
|
||||||
|
|
||||||
var responseHeadersExistence = new[]
|
var responseHeadersExistence = new[]
|
||||||
{
|
{
|
||||||
|
|
@ -240,7 +137,7 @@ namespace CodeGenerator
|
||||||
"Access-Control-Expose-Headers",
|
"Access-Control-Expose-Headers",
|
||||||
"Access-Control-Max-Age",
|
"Access-Control-Max-Age",
|
||||||
};
|
};
|
||||||
var responseHeaders = commonHeaders.Concat(new[]
|
ResponseHeaders = commonHeaders.Concat(new[]
|
||||||
{
|
{
|
||||||
"Accept-Ranges",
|
"Accept-Ranges",
|
||||||
"Age",
|
"Age",
|
||||||
|
|
@ -271,7 +168,7 @@ namespace CodeGenerator
|
||||||
}})
|
}})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
var responseTrailers = new[]
|
ResponseTrailers = new[]
|
||||||
{
|
{
|
||||||
"ETag",
|
"ETag",
|
||||||
}
|
}
|
||||||
|
|
@ -284,11 +181,359 @@ namespace CodeGenerator
|
||||||
PrimaryHeader = responsePrimaryHeaders.Contains(header)
|
PrimaryHeader = responsePrimaryHeaders.Contains(header)
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
static string Each<T>(IEnumerable<T> values, Func<T, string> formatter)
|
||||||
|
{
|
||||||
|
return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static string Each<T>(IEnumerable<T> values, Func<T, int, string> formatter)
|
||||||
|
{
|
||||||
|
return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static string AppendSwitch(IEnumerable<IGrouping<int, KnownHeader>> values) =>
|
||||||
|
$@"switch (name.Length)
|
||||||
|
{{{Each(values, byLength => $@"
|
||||||
|
case {byLength.Key}:{AppendSwitchSection(byLength.Key, byLength.OrderBy(h => (h.PrimaryHeader ? "_" : "") + h.Name))}
|
||||||
|
break;")}
|
||||||
|
}}";
|
||||||
|
|
||||||
|
static string AppendSwitchSection(int length, IOrderedEnumerable<KnownHeader> values)
|
||||||
|
{
|
||||||
|
var useVarForFirstTerm = values.Count() > 1 && values.Select(h => h.FirstNameIgnoreCaseSegment()).Distinct().Count() == 1;
|
||||||
|
var firstTermVarExpression = values.Select(h => h.FirstNameIgnoreCaseSegment()).FirstOrDefault();
|
||||||
|
var firstTermVar = $"firstTerm{length}";
|
||||||
|
|
||||||
|
var start = "";
|
||||||
|
if (useVarForFirstTerm)
|
||||||
|
{
|
||||||
|
start = $@"
|
||||||
|
var {firstTermVar} = {firstTermVarExpression};";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
firstTermVar = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
var groups = values.GroupBy(header => header.EqualIgnoreCaseBytesFirstTerm());
|
||||||
|
return start + $@"{Each(groups, (byFirstTerm, i) => $@"{(byFirstTerm.Count() == 1 ? $@"{Each(byFirstTerm, header => $@"
|
||||||
|
{(i > 0 ? "else " : "")}if ({header.EqualIgnoreCaseBytes(firstTermVar)})
|
||||||
|
{{{(header.Identifier == "ContentLength" ? $@"
|
||||||
|
AppendContentLength(value);
|
||||||
|
return;" : $@"
|
||||||
|
flag = {header.FlagBit()};
|
||||||
|
values = ref _headers._{header.Identifier};")}
|
||||||
|
}}")}" : $@"
|
||||||
|
if ({byFirstTerm.Key.Replace(firstTermVarExpression, firstTermVar)})
|
||||||
|
{{{Each(byFirstTerm, (header, i) => $@"
|
||||||
|
{(i > 0 ? "else " : "")}if ({header.EqualIgnoreCaseBytesSecondTermOnwards()})
|
||||||
|
{{{(header.Identifier == "ContentLength" ? $@"
|
||||||
|
AppendContentLength(value);
|
||||||
|
return;" : $@"
|
||||||
|
flag = {header.FlagBit()};
|
||||||
|
values = ref _headers._{header.Identifier};")}
|
||||||
|
}}")}
|
||||||
|
}}")}")}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class KnownHeader
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Index { get; set; }
|
||||||
|
public string Identifier => Name.Replace("-", "");
|
||||||
|
|
||||||
|
public byte[] Bytes => Encoding.ASCII.GetBytes($"\r\n{Name}: ");
|
||||||
|
public int BytesOffset { get; set; }
|
||||||
|
public int BytesCount { get; set; }
|
||||||
|
public bool ExistenceCheck { get; set; }
|
||||||
|
public bool FastCount { get; set; }
|
||||||
|
public bool EnhancedSetter { get; set; }
|
||||||
|
public bool PrimaryHeader { get; set; }
|
||||||
|
public string FlagBit() => $"{"0x" + (1L << Index).ToString("x")}L";
|
||||||
|
public string TestBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) != 0";
|
||||||
|
public string TestTempBit() => $"(tempBits & {"0x" + (1L << Index).ToString("x")}L) != 0";
|
||||||
|
public string TestNotTempBit() => $"(tempBits & ~{"0x" + (1L << Index).ToString("x")}L) == 0";
|
||||||
|
public string TestNotBit() => $"(_bits & {"0x" + (1L << Index).ToString("x")}L) == 0";
|
||||||
|
public string SetBit() => $"_bits |= {"0x" + (1L << Index).ToString("x")}L";
|
||||||
|
public string ClearBit() => $"_bits &= ~{"0x" + (1L << Index).ToString("x")}L";
|
||||||
|
|
||||||
|
private void GetMaskAndComp(string name, int offset, int count, out ulong mask, out ulong comp)
|
||||||
|
{
|
||||||
|
mask = 0;
|
||||||
|
comp = 0;
|
||||||
|
for (var scan = 0; scan < count; scan++)
|
||||||
|
{
|
||||||
|
var ch = (byte)name[offset + count - scan - 1];
|
||||||
|
var isAlpha = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||||
|
comp = (comp << 8) + (ch & (isAlpha ? 0xdfu : 0xffu));
|
||||||
|
mask = (mask << 8) + (isAlpha ? 0xdfu : 0xffu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string NameTerm(string name, int offset, int count, string type, string suffix)
|
||||||
|
{
|
||||||
|
GetMaskAndComp(name, offset, count, out var mask, out var comp);
|
||||||
|
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
if (type == "byte")
|
||||||
|
{
|
||||||
|
return $"(nameStart & 0x{mask:x}{suffix})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $"(Unsafe.ReadUnaligned<{type}>(ref nameStart) & 0x{mask:x}{suffix})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type == "byte")
|
||||||
|
{
|
||||||
|
return $"(Unsafe.AddByteOffset(ref nameStart, (IntPtr){offset / count}) & 0x{mask:x}{suffix})";
|
||||||
|
}
|
||||||
|
else if ((offset / count) == 1)
|
||||||
|
{
|
||||||
|
return $"(Unsafe.ReadUnaligned<{type}>(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)sizeof({type}))) & 0x{mask:x}{suffix})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $"(Unsafe.ReadUnaligned<{type}>(ref Unsafe.AddByteOffset(ref nameStart, (IntPtr)({offset / count} * sizeof({type})))) & 0x{mask:x}{suffix})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private string EqualityTerm(string name, int offset, int count, string type, string suffix)
|
||||||
|
{
|
||||||
|
GetMaskAndComp(name, offset, count, out var mask, out var comp);
|
||||||
|
|
||||||
|
return $"0x{comp:x}{suffix}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string Term(string name, int offset, int count, string type, string suffix)
|
||||||
|
{
|
||||||
|
GetMaskAndComp(name, offset, count, out var mask, out var comp);
|
||||||
|
|
||||||
|
return $"({NameTerm(name, offset, count, type, suffix)} == {EqualityTerm(name, offset, count, type, suffix)})";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FirstNameIgnoreCaseSegment()
|
||||||
|
{
|
||||||
|
var result = "";
|
||||||
|
if (Name.Length >= 8)
|
||||||
|
{
|
||||||
|
result = NameTerm(Name, 0, 8, "ulong", "uL");
|
||||||
|
}
|
||||||
|
else if (Name.Length >= 4)
|
||||||
|
{
|
||||||
|
result = NameTerm(Name, 0, 4, "uint", "u");
|
||||||
|
}
|
||||||
|
else if (Name.Length >= 2)
|
||||||
|
{
|
||||||
|
result = NameTerm(Name, 0, 2, "ushort", "u");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = NameTerm(Name, 0, 1, "byte", "u");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EqualIgnoreCaseBytes(string firstTermVar = "")
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(firstTermVar))
|
||||||
|
{
|
||||||
|
return EqualIgnoreCaseBytesWithVar(firstTermVar);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = "";
|
||||||
|
var delim = "";
|
||||||
|
var index = 0;
|
||||||
|
while (index != Name.Length)
|
||||||
|
{
|
||||||
|
if (Name.Length - index >= 8)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 8, "ulong", "uL");
|
||||||
|
index += 8;
|
||||||
|
}
|
||||||
|
else if (Name.Length - index >= 4)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 4, "uint", "u");
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
else if (Name.Length - index >= 2)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 2, "ushort", "u");
|
||||||
|
index += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 1, "byte", "u");
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
delim = " && ";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
string EqualIgnoreCaseBytesWithVar(string firstTermVar)
|
||||||
|
{
|
||||||
|
var result = "";
|
||||||
|
var delim = " && ";
|
||||||
|
var index = 0;
|
||||||
|
var isFirst = true;
|
||||||
|
while (index != Name.Length)
|
||||||
|
{
|
||||||
|
if (Name.Length - index >= 8)
|
||||||
|
{
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
result = $"({firstTermVar} == {EqualityTerm(Name, index, 8, "ulong", "uL")})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 8, "ulong", "uL");
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 8;
|
||||||
|
}
|
||||||
|
else if (Name.Length - index >= 4)
|
||||||
|
{
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
result = $"({firstTermVar} == {EqualityTerm(Name, index, 4, "uint", "u")})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 4, "uint", "u");
|
||||||
|
}
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
else if (Name.Length - index >= 2)
|
||||||
|
{
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
result = $"({firstTermVar} == {EqualityTerm(Name, index, 2, "ushort", "u")})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 2, "ushort", "u");
|
||||||
|
}
|
||||||
|
index += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
result = $"({firstTermVar} == {EqualityTerm(Name, index, 1, "byte", "u")})";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 1, "byte", "u");
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
isFirst = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EqualIgnoreCaseBytesFirstTerm()
|
||||||
|
{
|
||||||
|
var result = "";
|
||||||
|
if (Name.Length >= 8)
|
||||||
|
{
|
||||||
|
result = Term(Name, 0, 8, "ulong", "uL");
|
||||||
|
}
|
||||||
|
else if (Name.Length >= 4)
|
||||||
|
{
|
||||||
|
result = Term(Name, 0, 4, "uint", "u");
|
||||||
|
}
|
||||||
|
else if (Name.Length >= 2)
|
||||||
|
{
|
||||||
|
result = Term(Name, 0, 2, "ushort", "u");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = Term(Name, 0, 1, "byte", "u");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string EqualIgnoreCaseBytesSecondTermOnwards()
|
||||||
|
{
|
||||||
|
var result = "";
|
||||||
|
var delim = "";
|
||||||
|
var index = 0;
|
||||||
|
var isFirst = true;
|
||||||
|
while (index != Name.Length)
|
||||||
|
{
|
||||||
|
if (Name.Length - index >= 8)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 8, "ulong", "uL");
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 8;
|
||||||
|
}
|
||||||
|
else if (Name.Length - index >= 4)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 4, "uint", "u");
|
||||||
|
}
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
else if (Name.Length - index >= 2)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 2, "ushort", "u");
|
||||||
|
}
|
||||||
|
index += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
result += delim + Term(Name, index, 1, "byte", "u");
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
isFirst = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delim = " && ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GeneratedFile()
|
||||||
|
{
|
||||||
|
|
||||||
|
var requestHeaders = RequestHeaders;
|
||||||
|
Debug.Assert(requestHeaders.Length <= 64);
|
||||||
|
Debug.Assert(requestHeaders.Max(x => x.Index) <= 62);
|
||||||
|
|
||||||
// 63 for responseHeaders as it steals one bit for Content-Length in CopyTo(ref MemoryPoolIterator output)
|
// 63 for responseHeaders as it steals one bit for Content-Length in CopyTo(ref MemoryPoolIterator output)
|
||||||
|
var responseHeaders = ResponseHeaders;
|
||||||
Debug.Assert(responseHeaders.Length <= 63);
|
Debug.Assert(responseHeaders.Length <= 63);
|
||||||
Debug.Assert(responseHeaders.Count(x => x.Index == 63) == 1);
|
Debug.Assert(responseHeaders.Count(x => x.Index == 63) == 1);
|
||||||
|
|
||||||
|
var responseTrailers = ResponseTrailers;
|
||||||
|
|
||||||
var loops = new[]
|
var loops = new[]
|
||||||
{
|
{
|
||||||
new
|
new
|
||||||
|
|
@ -331,8 +576,10 @@ using System.Collections.Generic;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.IO.Pipelines;
|
using System.IO.Pipelines;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{{
|
{{
|
||||||
|
|
@ -345,8 +592,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
{Each(loop.Bytes, b => $"{b},")}
|
{Each(loop.Bytes, b => $"{b},")}
|
||||||
}};"
|
}};"
|
||||||
: "")}
|
: "")}
|
||||||
|
|
||||||
private long _bits = 0;
|
|
||||||
private HeaderReferences _headers;
|
private HeaderReferences _headers;
|
||||||
{Each(loop.Headers.Where(header => header.ExistenceCheck), header => $@"
|
{Each(loop.Headers.Where(header => header.ExistenceCheck), header => $@"
|
||||||
public bool Has{header.Identifier} => {header.TestBit()};")}
|
public bool Has{header.Identifier} => {header.TestBit()};")}
|
||||||
|
|
@ -510,8 +755,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
|
|
||||||
return MaybeUnknown?.Remove(key) ?? false;
|
return MaybeUnknown?.Remove(key) ?? false;
|
||||||
}}
|
}}
|
||||||
|
{(loop.ClassName != "HttpRequestHeaders" ?
|
||||||
protected override void ClearFast()
|
$@" protected override void ClearFast()
|
||||||
{{
|
{{
|
||||||
MaybeUnknown?.Clear();
|
MaybeUnknown?.Clear();
|
||||||
_contentLength = null;
|
_contentLength = null;
|
||||||
|
|
@ -534,7 +779,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}}
|
}}
|
||||||
")}
|
")}
|
||||||
}}
|
}}
|
||||||
|
" :
|
||||||
|
$@" private void Clear(long bitsToClear)
|
||||||
|
{{
|
||||||
|
var tempBits = bitsToClear;
|
||||||
|
{Each(loop.Headers.Where(header => header.Identifier != "ContentLength").OrderBy(h => !h.PrimaryHeader), header => $@"
|
||||||
|
if ({header.TestTempBit()})
|
||||||
|
{{
|
||||||
|
_headers._{header.Identifier} = default(StringValues);
|
||||||
|
if({header.TestNotTempBit()})
|
||||||
|
{{
|
||||||
|
return;
|
||||||
|
}}
|
||||||
|
tempBits &= ~{"0x" + (1L << header.Index).ToString("x")}L;
|
||||||
|
}}
|
||||||
|
")}
|
||||||
|
}}
|
||||||
|
")}
|
||||||
protected override bool CopyToFast(KeyValuePair<string, StringValues>[] array, int arrayIndex)
|
protected override bool CopyToFast(KeyValuePair<string, StringValues>[] array, int arrayIndex)
|
||||||
{{
|
{{
|
||||||
if (arrayIndex < 0)
|
if (arrayIndex < 0)
|
||||||
|
|
@ -625,22 +886,63 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
}} while (tempBits != 0);
|
}} while (tempBits != 0);
|
||||||
}}" : "")}
|
}}" : "")}{(loop.ClassName == "HttpRequestHeaders" ? $@"
|
||||||
{(loop.ClassName == "HttpRequestHeaders" ? $@"
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
public unsafe void Append(byte* pKeyBytes, int keyLength, string value)
|
public unsafe void Append(Span<byte> name, Span<byte> value)
|
||||||
{{
|
{{
|
||||||
var pUB = pKeyBytes;
|
ref byte nameStart = ref MemoryMarshal.GetReference(name);
|
||||||
{AppendSwitch(loop.Headers.Where(h => h.PrimaryHeader).GroupBy(x => x.Name.Length), loop.ClassName)}
|
ref StringValues values = ref Unsafe.AsRef<StringValues>(null);
|
||||||
|
var flag = 0L;
|
||||||
|
|
||||||
AppendNonPrimaryHeaders(pKeyBytes, keyLength, value);
|
// Does the name matched any ""known"" headers
|
||||||
}}
|
{AppendSwitch(loop.Headers.GroupBy(x => x.Name.Length).OrderBy(x => x.Key))}
|
||||||
|
|
||||||
private unsafe void AppendNonPrimaryHeaders(byte* pKeyBytes, int keyLength, string value)
|
if (flag != 0)
|
||||||
{{
|
{{
|
||||||
var pUB = pKeyBytes;
|
// Matched a known header
|
||||||
{AppendSwitch(loop.Headers.Where(h => !h.PrimaryHeader).GroupBy(x => x.Name.Length), loop.ClassName)}
|
if ((_previousBits & flag) != 0)
|
||||||
|
{{
|
||||||
|
// Had a previous string for this header, mark it as used so we don't clear it OnHeadersComplete or consider it if we get a second header
|
||||||
|
_previousBits ^= flag;
|
||||||
|
|
||||||
AppendUnknownHeaders(pKeyBytes, keyLength, value);
|
// We will only reuse this header if there was only one previous header
|
||||||
|
if (values.Count == 1)
|
||||||
|
{{
|
||||||
|
var previousValue = values.ToString();
|
||||||
|
// Check lengths are the same, then if the bytes were converted to an ascii string if they would be the same.
|
||||||
|
// We do not consider Utf8 headers for reuse.
|
||||||
|
if (previousValue.Length == value.Length &&
|
||||||
|
StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, value))
|
||||||
|
{{
|
||||||
|
// The previous string matches what the bytes would convert to, so we will just use that one.
|
||||||
|
_bits |= flag;
|
||||||
|
return;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
// We didn't have a previous matching header value, or have already added a header, so get the string for this value.
|
||||||
|
var valueStr = value.GetAsciiOrUTF8StringNonNullCharacters();
|
||||||
|
if ((_bits & flag) == 0)
|
||||||
|
{{
|
||||||
|
// We didn't already have a header set, so add a new one.
|
||||||
|
_bits |= flag;
|
||||||
|
values = new StringValues(valueStr);
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
{{
|
||||||
|
// We already had a header set, so concatenate the new one.
|
||||||
|
values = AppendValue(values, valueStr);
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
{{
|
||||||
|
// The header was not one of the ""known"" headers.
|
||||||
|
// Convert value to string first, because passing two spans causes 8 bytes stack zeroing in
|
||||||
|
// this method with rep stosd, which is slower than necessary.
|
||||||
|
var valueStr = value.GetAsciiOrUTF8StringNonNullCharacters();
|
||||||
|
AppendUnknownHeaders(name, valueStr);
|
||||||
|
}}
|
||||||
}}" : "")}
|
}}" : "")}
|
||||||
|
|
||||||
private struct HeaderReferences
|
private struct HeaderReferences
|
||||||
|
|
@ -154,6 +154,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalTheory]
|
[ConditionalTheory]
|
||||||
|
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2179", FlakyOn.Helix.All)]
|
||||||
[MemberData(nameof(AddressRegistrationDataIPv6ScopeId))]
|
[MemberData(nameof(AddressRegistrationDataIPv6ScopeId))]
|
||||||
[IPv6SupportedCondition]
|
[IPv6SupportedCondition]
|
||||||
[IPv6ScopeIdPresentCondition]
|
[IPv6ScopeIdPresentCondition]
|
||||||
|
|
@ -589,6 +590,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2178", FlakyOn.All)]
|
||||||
public async Task DoesNotOverrideDirectConfigurationWithIServerAddressesFeature_IfPreferHostingUrlsFalse()
|
public async Task DoesNotOverrideDirectConfigurationWithIServerAddressesFeature_IfPreferHostingUrlsFalse()
|
||||||
{
|
{
|
||||||
var useUrlsAddress = $"http://127.0.0.1:0";
|
var useUrlsAddress = $"http://127.0.0.1:0";
|
||||||
|
|
|
||||||
|
|
@ -108,16 +108,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LargeUploadRetryPredicate(Exception e)
|
|
||||||
=> e is IOException && e.Message.Contains("Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request");
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[Flaky("https://github.com/aspnet/AspNetCore/issues/8054", FlakyOn.AzP.Windows)]
|
[Flaky("https://github.com/aspnet/AspNetCore/issues/8054", FlakyOn.AzP.Windows)]
|
||||||
[RetryTest(nameof(LargeUploadRetryPredicate),
|
|
||||||
"Active investigation into potential corefx sockets bug: https://github.com/dotnet/corefx/issues/30691",
|
|
||||||
OperatingSystems.Windows,
|
|
||||||
5)]
|
|
||||||
[MemberData(nameof(LargeUploadData))]
|
[MemberData(nameof(LargeUploadData))]
|
||||||
public async Task LargeUpload(long? maxRequestBufferSize, bool connectionAdapter, bool expectPause)
|
public async Task LargeUpload(long? maxRequestBufferSize, bool connectionAdapter, bool expectPause)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -542,6 +542,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2181", FlakyOn.Helix.All)]
|
||||||
[MemberData(nameof(ConnectionAdapterData))]
|
[MemberData(nameof(ConnectionAdapterData))]
|
||||||
public async Task ConnectionClosedTokenFiresOnServerFIN(ListenOptions listenOptions)
|
public async Task ConnectionClosedTokenFiresOnServerFIN(ListenOptions listenOptions)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -810,10 +810,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
|
||||||
=> e is IOException && e.Message.Contains("Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request");
|
=> e is IOException && e.Message.Contains("Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request");
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[RetryTest(nameof(ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseHeadersRetryPredicate),
|
[Flaky("https://github.com/dotnet/corefx/issues/30691", FlakyOn.AzP.Windows)]
|
||||||
"Active investigation into potential corefx sockets bug: https://github.com/dotnet/corefx/issues/30691",
|
|
||||||
OperatingSystems.Windows,
|
|
||||||
5)]
|
|
||||||
public async Task ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseHeaders()
|
public async Task ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseHeaders()
|
||||||
{
|
{
|
||||||
var headerSize = 1024 * 1024; // 1 MB for each header value
|
var headerSize = 1024 * 1024; // 1 MB for each header value
|
||||||
|
|
|
||||||
|
|
@ -406,6 +406,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
_decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiOrUTF8StringNonNullCharacters();
|
_decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiOrUTF8StringNonNullCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IHttpHeadersHandler.OnHeadersComplete() { }
|
||||||
|
|
||||||
protected void CreateConnection()
|
protected void CreateConnection()
|
||||||
{
|
{
|
||||||
var limits = _serviceContext.ServerOptions.Limits;
|
var limits = _serviceContext.ServerOptions.Limits;
|
||||||
|
|
|
||||||
|
|
@ -492,7 +492,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
_mockConnectionContext.VerifyNoOtherCalls();
|
_mockConnectionContext.VerifyNoOtherCalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact(Skip = "https://github.com/aspnet/AspNetCore-Internal/issues/2197")]
|
||||||
public async Task DATA_Sent_TooSlowlyDueToOutputFlowControlOnMultipleStreams_AbortsConnectionAfterAdditiveRateTimeout()
|
public async Task DATA_Sent_TooSlowlyDueToOutputFlowControlOnMultipleStreams_AbortsConnectionAfterAdditiveRateTimeout()
|
||||||
{
|
{
|
||||||
var mockSystemClock = _serviceContext.MockSystemClock;
|
var mockSystemClock = _serviceContext.MockSystemClock;
|
||||||
|
|
|
||||||
|
|
@ -484,7 +484,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[ConditionalTheory]
|
||||||
[SkipOnHelix]
|
[SkipOnHelix]
|
||||||
[InlineData(ClientCertificateMode.AllowCertificate)]
|
[InlineData(ClientCertificateMode.AllowCertificate)]
|
||||||
[InlineData(ClientCertificateMode.RequireCertificate)]
|
[InlineData(ClientCertificateMode.RequireCertificate)]
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
|
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -14,6 +15,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
||||||
public class LoggingConnectionAdapterTests : LoggedTest
|
public class LoggingConnectionAdapterTests : LoggedTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1753", FlakyOn.Helix.All)]
|
||||||
public async Task LoggingConnectionAdapterCanBeAddedBeforeAndAfterHttpsAdapter()
|
public async Task LoggingConnectionAdapterCanBeAddedBeforeAndAfterHttpsAdapter()
|
||||||
{
|
{
|
||||||
await using (var server = new TestServer(context =>
|
await using (var server = new TestServer(context =>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
|
using Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTransport;
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -781,6 +782,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
[Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2176", FlakyOn.All)]
|
||||||
public async Task ContentLengthReadAsyncSingleBytesAtATime()
|
public async Task ContentLengthReadAsyncSingleBytesAtATime()
|
||||||
{
|
{
|
||||||
var testContext = new TestServiceContext(LoggerFactory);
|
var testContext = new TestServiceContext(LoggerFactory);
|
||||||
|
|
@ -811,10 +813,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests
|
||||||
"Content-Length: 5",
|
"Content-Length: 5",
|
||||||
"",
|
"",
|
||||||
"fun");
|
"fun");
|
||||||
await tcs.Task;
|
await tcs.Task.DefaultTimeout();
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"n");
|
"n");
|
||||||
await tcs2.Task;
|
await tcs2.Task.DefaultTimeout();
|
||||||
await connection.Send(
|
await connection.Send(
|
||||||
"y");
|
"y");
|
||||||
await connection.ReceiveEnd(
|
await connection.ReceiveEnd(
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
<IsTestAssetProject>true</IsTestAssetProject>
|
<IsTestAssetProject>true</IsTestAssetProject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="$(KestrelSharedSourceRoot)KnownHeaders.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
<Reference Include="Microsoft.AspNetCore.Hosting" />
|
||||||
<Reference Include="Microsoft.AspNetCore.Http.Features" />
|
<Reference Include="Microsoft.AspNetCore.Http.Features" />
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
"appDomain": "denied",
|
"appDomain": "denied",
|
||||||
"methodDisplay": "method",
|
"methodDisplay": "method",
|
||||||
"longRunningTestSeconds": 60,
|
"longRunningTestSeconds": 60,
|
||||||
"maxParallelThreads": -1
|
"maxParallelThreads": -1,
|
||||||
|
"diagnosticMessages": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,20 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using OpenQA.Selenium;
|
using OpenQA.Selenium;
|
||||||
using OpenQA.Selenium.Chrome;
|
using OpenQA.Selenium.Chrome;
|
||||||
using OpenQA.Selenium.Remote;
|
using OpenQA.Selenium.Remote;
|
||||||
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.E2ETesting
|
namespace Microsoft.AspNetCore.E2ETesting
|
||||||
{
|
{
|
||||||
public class BrowserFixture : IDisposable
|
public class BrowserFixture : IAsyncLifetime
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<string, Task<(IWebDriver browser, ILogs log)>> _browsers = new ConcurrentDictionary<string, Task<(IWebDriver, ILogs)>>();
|
private ConcurrentDictionary<string, Task<(IWebDriver browser, ILogs log)>> _browsers = new ConcurrentDictionary<string, Task<(IWebDriver, ILogs)>>();
|
||||||
private List<IWebDriver> _browsersToDispose = new List<IWebDriver>();
|
|
||||||
|
|
||||||
public BrowserFixture(IMessageSink diagnosticsMessageSink)
|
public BrowserFixture(IMessageSink diagnosticsMessageSink)
|
||||||
{
|
{
|
||||||
|
|
@ -52,9 +51,10 @@ namespace Microsoft.AspNetCore.E2ETesting
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
foreach (var browser in _browsersToDispose)
|
var browsers = await Task.WhenAll(_browsers.Values);
|
||||||
|
foreach (var (browser, log) in browsers)
|
||||||
{
|
{
|
||||||
browser.Dispose();
|
browser.Dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -71,6 +71,8 @@ namespace Microsoft.AspNetCore.E2ETesting
|
||||||
return _browsers.GetOrAdd(isolationContext, CreateBrowserAsync, output);
|
return _browsers.GetOrAdd(isolationContext, CreateBrowserAsync, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task InitializeAsync() => Task.CompletedTask;
|
||||||
|
|
||||||
private async Task<(IWebDriver browser, ILogs log)> CreateBrowserAsync(string context, ITestOutputHelper output)
|
private async Task<(IWebDriver browser, ILogs log)> CreateBrowserAsync(string context, ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
var opts = new ChromeOptions();
|
var opts = new ChromeOptions();
|
||||||
|
|
@ -115,7 +117,6 @@ namespace Microsoft.AspNetCore.E2ETesting
|
||||||
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);
|
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);
|
||||||
var logs = new RemoteLogs(driver);
|
var logs = new RemoteLogs(driver);
|
||||||
|
|
||||||
_browsersToDispose.Add(driver);
|
|
||||||
return (driver, logs);
|
return (driver, logs);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "clients/cpp/test/gtest/googletest"]
|
|
||||||
path = clients/cpp/test/gtest/googletest
|
|
||||||
url = https://github.com/google/googletest
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
packages/
|
|
||||||
Debug/
|
|
||||||
Release/
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildThisFileDirectory)Version.props" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or '$(SolutionDir)' == '*Undefined*'">$(MSBuildThisFileDirectory)..\</SolutionDir>
|
|
||||||
<Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
|
|
||||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
|
||||||
<PlatformToolset Condition=" '$(PlatformToolset)' == '' And '$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
|
|
||||||
<PlatformToolset Condition=" '$(PlatformToolset)' == '' And '$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
|
|
||||||
<PlatformToolset Condition=" '$(PlatformToolset)' == ''">v140</PlatformToolset>
|
|
||||||
<SubSystem Condition="'$(SubSystem)' != 'UWP'">Desktop</SubSystem>
|
|
||||||
<OutDir Condition="'$(OutDir)' == ''">$(SolutionDir)bin\$(SubSystem)\$(Platform)\$(Configuration)\</OutDir>
|
|
||||||
<SignalrClientTargetName>signalrclient</SignalrClientTargetName>
|
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<UsingTask TaskName="ExecAsync" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
|
|
||||||
<ParameterGroup>
|
|
||||||
<Executable ParameterType="System.String" Required="true" />
|
|
||||||
<Arguments ParameterType="System.String" Required="false" />
|
|
||||||
</ParameterGroup>
|
|
||||||
<Task>
|
|
||||||
<Using Namespace="System.IO" />
|
|
||||||
<Using Namespace="System.Diagnostics" />
|
|
||||||
<Code Type="Fragment" Language="cs">
|
|
||||||
<![CDATA[
|
|
||||||
Log.LogMessage("Executable {0}...", Executable);
|
|
||||||
var name = System.IO.Path.GetFileNameWithoutExtension(Executable);
|
|
||||||
Log.LogMessage("Starting {0}...", name);
|
|
||||||
var processStartInfo = new ProcessStartInfo(Executable, Arguments) { UseShellExecute = true };
|
|
||||||
Process.Start(processStartInfo);
|
|
||||||
Log.LogMessage("Finished starting process {0}.", name);
|
|
||||||
]]>
|
|
||||||
</Code>
|
|
||||||
</Task>
|
|
||||||
</UsingTask>
|
|
||||||
|
|
||||||
<UsingTask TaskName="Sleep" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
|
|
||||||
<ParameterGroup>
|
|
||||||
<TimeoutMs ParameterType="System.Int32" Required="true" />
|
|
||||||
</ParameterGroup>
|
|
||||||
<Task>
|
|
||||||
<Code Type="Fragment" Language="cs">
|
|
||||||
<![CDATA[System.Threading.Thread.Sleep(TimeoutMs);]]>
|
|
||||||
</Code>
|
|
||||||
</Task>
|
|
||||||
</UsingTask>
|
|
||||||
|
|
||||||
<UsingTask TaskName="ZipDir" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
|
|
||||||
<ParameterGroup>
|
|
||||||
<InputDir ParameterType="System.String" Required="true" />
|
|
||||||
<OutputFileName ParameterType="System.String" Required="true" />
|
|
||||||
<IncludeBaseDir ParameterType="System.Boolean" Required="false" />
|
|
||||||
</ParameterGroup>
|
|
||||||
<Task>
|
|
||||||
<Reference Include="System.IO.Compression.FileSystem" />
|
|
||||||
<Using Namespace="System.IO.Compression" />
|
|
||||||
<Code Type="Fragment" Language="cs">
|
|
||||||
<![CDATA[ ZipFile.CreateFromDirectory(InputDir, OutputFileName, CompressionLevel.Optimal, IncludeBaseDir); ]]>
|
|
||||||
</Code>
|
|
||||||
</Task>
|
|
||||||
</UsingTask>
|
|
||||||
|
|
||||||
<UsingTask TaskName="RegexReplaceInFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
|
|
||||||
<ParameterGroup>
|
|
||||||
<InputFilename ParameterType="System.String" Required="true" />
|
|
||||||
<OutputFilename ParameterType="System.String" Required="true" />
|
|
||||||
<Pattern ParameterType="System.String" Required="true" />
|
|
||||||
<Replacement ParameterType="System.String" Required="true" />
|
|
||||||
</ParameterGroup>
|
|
||||||
<Task>
|
|
||||||
<Using Namespace="System.IO" />
|
|
||||||
<Using Namespace="System.Linq" />
|
|
||||||
<Using Namespace="System.Text.RegularExpressions" />
|
|
||||||
<Code Type="Fragment" Language="cs">
|
|
||||||
<![CDATA[
|
|
||||||
string contents;
|
|
||||||
using (var input = new StreamReader(InputFilename))
|
|
||||||
{
|
|
||||||
contents = input.ReadToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
contents = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.Multiline)
|
|
||||||
.Replace(contents, Replacement);
|
|
||||||
|
|
||||||
using (var output = new StreamWriter(OutputFilename))
|
|
||||||
{
|
|
||||||
output.Write(contents);
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</Code>
|
|
||||||
</Task>
|
|
||||||
</UsingTask>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|x64">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>x64</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildThisFileDirectory)\Common.Build.Settings" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
|
|
||||||
<RestorePackages>true</RestorePackages>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(SubSystem)' == 'UWP'">
|
|
||||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
|
||||||
<AppContainerApplication>true</AppContainerApplication>
|
|
||||||
<ApplicationType>Windows Store</ApplicationType>
|
|
||||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
|
||||||
<WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
|
|
||||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
|
||||||
<GenerateProjectSpecificOutputFolder>False</GenerateProjectSpecificOutputFolder>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level4</WarningLevel>
|
|
||||||
<TreatWarningAsError Condition="'$(TreatWarningsAsErrors)' != ''">true</TreatWarningAsError>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<StringPooling>true</StringPooling>
|
|
||||||
<CompileAsWinRT Condition="'$(SubSystem)' == 'UWP'">true</CompileAsWinRT>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem Condition="'$(SubSystem)' != 'UWP'">Windows</SubSystem>
|
|
||||||
<SubSystem Condition="'$(SubSystem)' == 'UWP'">Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).pub.pdb</StripPrivateSymbols>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<Profile>true</Profile>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
|
||||||
<ClCompile>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
|
||||||
<ClCompile>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>_WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>_WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<!-- When changing version remember to update version in $src\signalrclient\constants.h -->
|
|
||||||
<SignalRClientCppVersionMajor>1</SignalRClientCppVersionMajor>
|
|
||||||
<SignalRClientCppVersionMinor>0</SignalRClientCppVersionMinor>
|
|
||||||
<SignalRClientCppVersionPatch>0</SignalRClientCppVersionPatch>
|
|
||||||
<SignalRClientCppVersionSuffix>-alpha0</SignalRClientCppVersionSuffix>
|
|
||||||
<!-- $(build_number) generated by Team City -->
|
|
||||||
<SignalRClientCppVersionSuffix Condition="'$(build_number)' != '' And '$(build_branch)' != 'release'">$(SignalRClientCppVersionSuffix)-$(build_number)</SignalRClientCppVersionSuffix>
|
|
||||||
<SignalRClientCppVersionString>$(SignalRClientCppVersionMajor).$(SignalRClientCppVersionMinor).$(SignalRClientCppVersionPatch)$(SignalRClientCppVersionSuffix)</SignalRClientCppVersionString>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="$(MSBuildThisFileDirectory)\Common.tasks" />
|
|
||||||
<Import Project="$(MSBuildThisFileDirectory)\Common.Build.Settings" />
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Projects Include="$(SolutionDir)src\signalrclientdll\Build\VS\signalrclientdll.vcxproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<TestProjects Include="$(SolutionDir)src\signalrclient\Build\VS\signalrclient.vcxproj" />
|
|
||||||
<TestProjects Include="$(SolutionDir)test\signalrclienttests\Build\VS\signalrclienttests.vcxproj" />
|
|
||||||
<TestProjects Include="$(SolutionDir)test\signalrclient-e2e-tests\Build\VS\signalrclient-e2e-tests.vcxproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- TestHost is an ASP.NET app, will replace with a ASP.NET Core app -->
|
|
||||||
<!-- <ManagedProjects Include="$(SolutionDir)test\signalrclient-testhost\signalrclient-testhost.csproj" /> -->
|
|
||||||
<!--
|
|
||||||
<ManagedProjects Include="$(SolutionDir)\samples\SignalRServer\SignalRServer.csproj" />
|
|
||||||
-->
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<!--
|
|
||||||
<SampleProjects Include="$(SolutionDir)\samples\PersistentConnectionSample\PersistentConnectionSample.vcxproj" />
|
|
||||||
<SampleProjects Include="$(SolutionDir)\samples\HubConnectionSample\HubConnectionSample.vcxproj" />
|
|
||||||
-->
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
|
||||||
|
|
||||||
<Target Name="Build">
|
|
||||||
<MSBuild Targets="RestorePackages" Projects="@(Projects)" />
|
|
||||||
<MSBuild Targets="RestorePackages" Projects="@(SampleProjects)" />
|
|
||||||
<MSBuild Targets="RestorePackages" Projects="@(ManagedProjects)" />
|
|
||||||
|
|
||||||
<MSBuild Targets="$(BuildTargets)"
|
|
||||||
Projects="@(Projects)"
|
|
||||||
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)" />
|
|
||||||
|
|
||||||
<MSBuild Targets="$(BuildTargets)"
|
|
||||||
Projects="@(TestProjects)"
|
|
||||||
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'"/>
|
|
||||||
|
|
||||||
<MSBuild Targets="$(BuildTargets)"
|
|
||||||
Projects="@(SampleProjects)"
|
|
||||||
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'"/>
|
|
||||||
|
|
||||||
<MSBuild Targets="$(BuildTargets)"
|
|
||||||
Projects="@(ManagedProjects)"
|
|
||||||
Properties="Configuration=$(Configuration)" Condition="'$(SubSystem)' == 'Desktop'"/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="Clean">
|
|
||||||
<MSBuild Targets="Clean"
|
|
||||||
Projects="@(Projects)" />
|
|
||||||
<MSBuild Targets="Clean"
|
|
||||||
Projects="@(TestProjects)" />
|
|
||||||
<MSBuild Targets="Clean"
|
|
||||||
Projects="@(SampleProjects)" />
|
|
||||||
<MSBuild Targets="Clean"
|
|
||||||
Projects="@(ManagedProjects)" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="Rebuild">
|
|
||||||
<MSBuild Targets="Clean;Build"
|
|
||||||
Projects="$(MSBuildProjectFile)"
|
|
||||||
Properties="BuildTargets=Rebuild;Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)"/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="Test" DependsOnTargets="Build" Condition="'$(SubSystem)' == 'Desktop'">
|
|
||||||
<Exec Command="$(OutDir)\signalrclienttests.exe --gtest_output=xml:$(OutDir)test_results.xml" />
|
|
||||||
<ExecAsync Executable="$(SolutionDir)test\signalrclient-testhost\bin\$(Configuration)\signalrclient-testhost.exe" Arguments="60000" />
|
|
||||||
<!-- give the host some time to open the port otherwise the first tests may fail on slow machines-->
|
|
||||||
<Sleep TimeoutMs="3000" />
|
|
||||||
<Exec Command="$(OutDir)\signalrclient-e2e-tests.exe --gtest_output=xml:$(OutDir)e2e_test_results.xml" />
|
|
||||||
<Exec Command="taskkill /IM signalrclient-testhost.exe /F" ContinueOnError="true" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Import Project="Config.Definitions.Props" />
|
|
||||||
|
|
||||||
<Target Name="CreatePackage">
|
|
||||||
<PropertyGroup>
|
|
||||||
<PlatformToolset Condition="'$(PlatformToolset)' == ''">v140</PlatformToolset>
|
|
||||||
<SubSystem Condition="'$(SubSystem)' != 'UWP'">Desktop</SubSystem>
|
|
||||||
<PackageSource>$(SolutionDir)bin\Package\$(SubSystem)\$(PlatformToolset)\</PackageSource>
|
|
||||||
<PackageSourceNative>$(PackageSource)build\native\</PackageSourceNative>
|
|
||||||
<NuGetArtifactsPath>$(MSBuildThisFileDirectory)..\NuGet\</NuGetArtifactsPath>
|
|
||||||
<NuSpecTemplatePath>$(NuGetArtifactsPath)signalrclientcpp.nuspec.template</NuSpecTemplatePath>
|
|
||||||
<PackageOutputDir>$(SolutionDir)artifacts\build</PackageOutputDir>
|
|
||||||
<PrivateSymbols>$(SolutionDir)bin\Symbols\$(SubSystem)\$(PlatformToolset)\</PrivateSymbols>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Error Text="UWP not supported with v120 toolset" Condition="'$(SubSystem)' == 'UWP' And '$(PlatformToolset)' != 'v140'" />
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Include Include="$(SolutionDir)include\**\*.*" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Copy SourceFiles="@(Include)" DestinationFolder="$(PackageSourceNative)include\%(RecursiveDir)" />
|
|
||||||
<MakeDir Directories="$(PackageSource)" />
|
|
||||||
|
|
||||||
<RegexReplaceInFile InputFileName="$(NuSpecTemplatePath)" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#Toolset#" Replacement="$(PlatformToolset)" />
|
|
||||||
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#casablanca-subsystem#" Replacement="windesktop" Condition="'$(SubSystem)' == 'Desktop'" />
|
|
||||||
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#SubSystem#" Replacement="WinDesktop" Condition="'$(SubSystem)' == 'Desktop'" />
|
|
||||||
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#casablanca-subsystem#" Replacement="winapp" Condition="'$(SubSystem)' == 'UWP'" />
|
|
||||||
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#SubSystem#" Replacement="UWP" Condition="'$(SubSystem)' == 'UWP'" />
|
|
||||||
|
|
||||||
<RegexReplaceInFile InputFileName="$(NuGetArtifactsPath)\Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template"
|
|
||||||
OutputFileName="$(PackageSourceNative)Microsoft.AspNet.SignalR.Client.Cpp.$(PlatformToolset).WinDesktop.targets" Pattern="#Toolset#" Replacement="$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'" />
|
|
||||||
<RegexReplaceInFile InputFileName="$(NuGetArtifactsPath)\Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template"
|
|
||||||
OutputFileName="$(PackageSourceNative)Microsoft.AspNet.SignalR.Client.Cpp.$(PlatformToolset).UWP.targets" Pattern="#Toolset#" Replacement="$(PlatformToolset)" Condition="'$(SubSystem)' == 'UWP'" />
|
|
||||||
|
|
||||||
<MSBuild Targets="RestorePackages" Projects="@(Projects)" />
|
|
||||||
|
|
||||||
<MSBuild Targets="BuildForNuget"
|
|
||||||
Projects="$(MSBuildThisFile)" Properties="PackageSourceNative=$(PackageSourceNative);PrivateSymbols=$(PrivateSymbols);Configuration=%(ProjectConfiguration.Configuration);Platform=%(ProjectConfiguration.Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem);SignalrClientTargetName=$(SignalrClientTargetName)" />
|
|
||||||
|
|
||||||
<MakeDir Directories="$(PackageOutputDir)" />
|
|
||||||
<Exec Command="$(NuGetCommand) pack $(PackageSource)signalrclientcpp.nuspec -BasePath $(PackageSource) -OutputDirectory $(PackageOutputDir) -Version $(SignalRClientCppVersionString)" LogStandardErrorAsError="true" />
|
|
||||||
|
|
||||||
<ZipDir InputDir="$(PrivateSymbols)" OutputFileName="$(PackageOutputDir)\Symbols_$(PlatformToolset)_$(SubSystem).zip" IncludeBaseDir="false"/>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="BuildForNuget">
|
|
||||||
<MSBuild Targets="$(BuildTargets)"
|
|
||||||
Projects="@(Projects)"
|
|
||||||
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)" />
|
|
||||||
|
|
||||||
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).lib" DestinationFolder="$(PackageSourceNative)lib\$(Platform)\$(PlatformToolset)\$(Configuration)" />
|
|
||||||
|
|
||||||
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).dll" DestinationFolder="$(PackageSourceNative)dll\$(Platform)\$(PlatformToolset)\$(Configuration)" />
|
|
||||||
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).pub.pdb" DestinationFiles="$(PackageSourceNative)dll\$(Platform)\$(PlatformToolset)\$(Configuration)\$(SignalrClientTargetName).pdb" />
|
|
||||||
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).pdb" DestinationFiles="$(PrivateSymbols)$(Platform)\$(PlatformToolset)\$(Configuration)\$(SignalrClientTargetName).pdb" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="NuGetPush">
|
|
||||||
<PropertyGroup>
|
|
||||||
<NuGetExePath Condition="'$(NuGetExePath)' == ''">$(PUSH_NUGET_EXE)</NuGetExePath>
|
|
||||||
<NuGetExePath Condition="'$(NuGetExePath)' == ''">$(MSBuildThisFileDirectory)..\.nuget\NuGet.exe</NuGetExePath>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Package Include="$(SolutionDir)artifacts\build\*.nupkg" />
|
|
||||||
<Package Include="$(SolutionDir)artifacts\build\*.symbols.nupkg" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Exec Command="$(NuGetExePath) push -nosymbols %(Package.Identity) -Source $(NUGET_PUBLISH_FEED) -ApiKey $(APIKEY)" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
cmake_minimum_required (VERSION 2.8.11)
|
|
||||||
project (signalrclient)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -L -lcpprest")
|
|
||||||
|
|
||||||
set(CPPREST_INCLUDE_DIR "" CACHE FILEPATH "Path to casablanca include dir")
|
|
||||||
|
|
||||||
include_directories (
|
|
||||||
include
|
|
||||||
"${CPPREST_INCLUDE_DIR}")
|
|
||||||
|
|
||||||
find_library(CPPREST_SO NAMES "cpprest" PATHS ${CPPREST_LIB_DIR} REQUIRED)
|
|
||||||
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
|
||||||
|
|
||||||
add_subdirectory(src/signalrclient)
|
|
||||||
add_subdirectory(test)
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
Contributing
|
|
||||||
======
|
|
||||||
|
|
||||||
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<packageSources>
|
|
||||||
<clear />
|
|
||||||
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
|
|
||||||
</packageSources>
|
|
||||||
</configuration>
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="signalrclient_uwp_inittarget">
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(PlatformToolset)' != 'v140' Or '$(ApplicationType)' != 'Windows Store'">
|
|
||||||
<DisableUwp>True</DisableUwp>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(DisableUwp)' == ''">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Label="x64 and #Toolset# and Release" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Label="x64 and #Toolset# and Debug" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Label="Win32 and #Toolset# and Release" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Label="Win32 and #Toolset# and Debug" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<Target Name="signalrclient_uwp_AfterBuild" AfterTargets="AfterBuild" Condition="'$(DisableUwp)' == ''">
|
|
||||||
<PropertyGroup>
|
|
||||||
<UseHardlinksIfPossible Condition="'$(UseHardlinksIfPossible)' == ''">true</UseHardlinksIfPossible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Copy DestinationFolder="$(TargetDir)" SourceFiles="@(CopyToOutput)" SkipUnchangedFiles="true" UseHardlinksIfPossible="$(UseHardlinksIfPossible)">
|
|
||||||
<Output TaskParameter="DestinationFiles" PropertyName="DestinationFiles" />
|
|
||||||
<Output TaskParameter="DestinationFiles" ItemName="DestinationFiles" />
|
|
||||||
<Output TaskParameter="CopiedFiles" PropertyName="CopiedFiles" />
|
|
||||||
<Output TaskParameter="CopiedFiles" ItemName="CopiedFiles" />
|
|
||||||
</Copy>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="signalrclient_uwp_inittarget" Condition="'$(DisableUwp)' == ''">
|
|
||||||
<ItemGroup Label="x64 and #Toolset# and Debug" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll" />
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.pdb" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="x64 and #Toolset# and Release" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll" />
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.pdb" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="Win32 and #Toolset# and Debug" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll" />
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.pdb" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="Win32 and #Toolset# and Release" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll" />
|
|
||||||
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.pdb" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="signalrclient_inittarget">
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(ApplicationType)' != ''">
|
|
||||||
<DisableDesktop>True</DisableDesktop>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Condition="'$(DisableDesktop)' == ''">
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<ResourceCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<ItemDefinitionGroup Label="x64 and #Toolset# and Release" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Label="x64 and #Toolset# and Debug" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Label="Win32 and #Toolset# and Release" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Label="Win32 and #Toolset# and Debug" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<Link>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
|
|
||||||
<Target Name="signalrclient_AfterBuild" AfterTargets="AfterBuild" Condition="'$(DisableDesktop)' == ''">
|
|
||||||
<PropertyGroup>
|
|
||||||
<UseHardlinksIfPossible Condition="'$(UseHardlinksIfPossible)' == ''">true</UseHardlinksIfPossible>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Copy DestinationFolder="$(TargetDir)" SourceFiles="@(CopyToOutput)" SkipUnchangedFiles="true" UseHardlinksIfPossible="$(UseHardlinksIfPossible)">
|
|
||||||
<Output TaskParameter="DestinationFiles" PropertyName="DestinationFiles" />
|
|
||||||
<Output TaskParameter="DestinationFiles" ItemName="DestinationFiles" />
|
|
||||||
<Output TaskParameter="CopiedFiles" PropertyName="CopiedFiles" />
|
|
||||||
<Output TaskParameter="CopiedFiles" ItemName="CopiedFiles" />
|
|
||||||
</Copy>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<Target Name="signalrclient_inittarget" Condition="'$(DisableDesktop)' == ''">
|
|
||||||
<ItemGroup Label="x64 and #Toolset# and Debug" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll" />
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.pdb" />
|
|
||||||
<None Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll">
|
|
||||||
<DeploymentContent>true</DeploymentContent>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="x64 and #Toolset# and Release" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll" />
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.pdb" />
|
|
||||||
<None Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll">
|
|
||||||
<DeploymentContent>true</DeploymentContent>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="Win32 and #Toolset# and Debug" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1">
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll" />
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.pdb" />
|
|
||||||
<None Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll">
|
|
||||||
<DeploymentContent>true</DeploymentContent>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup Label="Win32 and #Toolset# and Release" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll" />
|
|
||||||
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.pdb" />
|
|
||||||
<None Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll">
|
|
||||||
<DeploymentContent>true</DeploymentContent>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<package>
|
|
||||||
<metadata>
|
|
||||||
<id>Microsoft.AspNet.SignalR.Client.Cpp.#Toolset#.#SubSystem#</id>
|
|
||||||
<title>Microsoft ASP.NET SignalR C++ Client</title>
|
|
||||||
<version>0.0.0</version>
|
|
||||||
<authors>Microsoft</authors>
|
|
||||||
<owners>Microsoft</owners>
|
|
||||||
<licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
|
|
||||||
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
|
|
||||||
<projectUrl>http://www.asp.net/signalr</projectUrl>
|
|
||||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
|
||||||
<description>C++ client for ASP.NET SignalR.</description>
|
|
||||||
<language>en-US</language>
|
|
||||||
<tags>Microsoft AspNet SignalR AspNetSignalR Client C++ native</tags>
|
|
||||||
<releaseNotes>https://github.com/aspnet/SignalR-Client-Cpp/releases</releaseNotes>
|
|
||||||
<dependencies>
|
|
||||||
<dependency id="cpprestsdk.#Toolset#.#casablanca-subsystem#.msvcstl.dyn.rt-dyn" version="2.9.1" />
|
|
||||||
</dependencies>
|
|
||||||
</metadata>
|
|
||||||
</package>
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
ASP.NET Core SignalR C++ Client
|
|
||||||
========
|
|
||||||
|
|
||||||
This folder contains a C++ client for ASP.NET Core SignalR.
|
|
||||||
|
|
||||||
**There are no plans to ship this client at this time.**
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
msbuild "%~dp0\Build\build.msbuild" /v:minimal /maxcpucount /nodeReuse:false %*
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef NO_SIGNALRCLIENT_EXPORTS
|
|
||||||
#define SIGNALRCLIENT_API
|
|
||||||
#else
|
|
||||||
#ifdef SIGNALRCLIENT_EXPORTS
|
|
||||||
#define SIGNALRCLIENT_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define SIGNALRCLIENT_API __declspec(dllimport)
|
|
||||||
#endif // SIGNALRCLIENT_EXPORTS
|
|
||||||
#endif // NO_SIGNALRCLIENT_EXPORTS
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "_exports.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
|
||||||
#include "connection_state.h"
|
|
||||||
#include "trace_level.h"
|
|
||||||
#include "log_writer.h"
|
|
||||||
#include "signalr_client_config.h"
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class connection_impl;
|
|
||||||
|
|
||||||
class connection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::function<void __cdecl(const std::string&)> message_received_handler;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API explicit connection(const std::string& url, trace_level trace_level = trace_level::all, std::shared_ptr<log_writer> log_writer = nullptr);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API ~connection();
|
|
||||||
|
|
||||||
connection(const connection&) = delete;
|
|
||||||
|
|
||||||
connection& operator=(const connection&) = delete;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_message_received(const message_received_handler& message_received_callback);
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_client_config(const signalr_client_config& config);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API connection_state __cdecl get_connection_state() const noexcept;
|
|
||||||
SIGNALRCLIENT_API std::string __cdecl get_connection_id() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The recommended smart pointer to use when doing pImpl is the `std::unique_ptr`. However
|
|
||||||
// we are capturing the m_pImpl instance in the lambdas used by tasks which can outlive
|
|
||||||
// the connection instance. Using `std::shared_ptr` guarantees that we won't be using
|
|
||||||
// a deleted object if the task is run after the `connection` instance goes away.
|
|
||||||
std::shared_ptr<connection_impl> m_pImpl;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
enum class connection_state
|
|
||||||
{
|
|
||||||
connecting,
|
|
||||||
connected,
|
|
||||||
disconnecting,
|
|
||||||
disconnected
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
enum class http_method
|
|
||||||
{
|
|
||||||
GET,
|
|
||||||
POST
|
|
||||||
};
|
|
||||||
|
|
||||||
class http_request
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
http_method method;
|
|
||||||
std::map<std::string, std::string> headers;
|
|
||||||
std::string content;
|
|
||||||
std::chrono::seconds timeout;
|
|
||||||
};
|
|
||||||
|
|
||||||
class http_response
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
http_response() {}
|
|
||||||
http_response(http_response&& rhs) noexcept : status_code(rhs.status_code), content(std::move(rhs.content)) {}
|
|
||||||
http_response(int code, const std::string& content) : status_code(code), content(content) {}
|
|
||||||
|
|
||||||
http_response& operator=(http_response&& rhs)
|
|
||||||
{
|
|
||||||
status_code = rhs.status_code;
|
|
||||||
content = std::move(rhs.content);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int status_code = 0;
|
|
||||||
std::string content;
|
|
||||||
};
|
|
||||||
|
|
||||||
class http_client
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) = 0;
|
|
||||||
|
|
||||||
virtual ~http_client() {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "_exports.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
|
||||||
#include "cpprest/json.h"
|
|
||||||
#include "connection_state.h"
|
|
||||||
#include "trace_level.h"
|
|
||||||
#include "log_writer.h"
|
|
||||||
#include "signalr_client_config.h"
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class hub_connection_impl;
|
|
||||||
|
|
||||||
class hub_connection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::function<void __cdecl (const web::json::value&)> method_invoked_handler;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API explicit hub_connection(const std::string& url, trace_level trace_level = trace_level::all,
|
|
||||||
std::shared_ptr<log_writer> log_writer = nullptr);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API ~hub_connection();
|
|
||||||
|
|
||||||
hub_connection(const hub_connection&) = delete;
|
|
||||||
|
|
||||||
hub_connection& operator=(const hub_connection&) = delete;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept;
|
|
||||||
SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API connection_state __cdecl get_connection_state() const;
|
|
||||||
SIGNALRCLIENT_API std::string __cdecl get_connection_id() const;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_client_config(const signalr_client_config& config);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void __cdecl on(const std::string& event_name, const method_invoked_handler& handler);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void invoke(const std::string& method_name, const web::json::value& arguments = web::json::value::array(), std::function<void(const web::json::value&, std::exception_ptr)> callback = [](const web::json::value&, std::exception_ptr) {}) noexcept;
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API void send(const std::string& method_name, const web::json::value& arguments = web::json::value::array(), std::function<void(std::exception_ptr)> callback = [](std::exception_ptr) {}) noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<hub_connection_impl> m_pImpl;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "signalr_exception.h"
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class hub_exception : public signalr_exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
hub_exception(const std::string &what)
|
|
||||||
: signalr_exception(what)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class log_writer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// NOTE: the caller does not enforce thread safety of this call
|
|
||||||
virtual void __cdecl write(const std::string &entry) = 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cpprest/http_client.h"
|
|
||||||
#include "cpprest/ws_client.h"
|
|
||||||
#include "_exports.h"
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class signalr_client_config
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_proxy(const web::web_proxy &proxy);
|
|
||||||
// Please note that setting credentials does not work in all cases.
|
|
||||||
// For example, Basic Authentication fails under Win32.
|
|
||||||
// As a workaround, you can set the required authorization headers directly
|
|
||||||
// using signalr_client_config::set_http_headers
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_credentials(const web::credentials &credentials);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API web::http::client::http_client_config __cdecl get_http_client_config() const;
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_http_client_config(const web::http::client::http_client_config& http_client_config);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API web::websockets::client::websocket_client_config __cdecl get_websocket_client_config() const noexcept;
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_websocket_client_config(const web::websockets::client::websocket_client_config& websocket_client_config);
|
|
||||||
|
|
||||||
SIGNALRCLIENT_API web::http::http_headers __cdecl get_http_headers() const noexcept;
|
|
||||||
SIGNALRCLIENT_API void __cdecl set_http_headers(const web::http::http_headers& http_headers);
|
|
||||||
|
|
||||||
private:
|
|
||||||
web::http::client::http_client_config m_http_client_config;
|
|
||||||
web::websockets::client::websocket_client_config m_websocket_client_config;
|
|
||||||
web::http::http_headers m_http_headers;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class signalr_exception : public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit signalr_exception(const std::string &what)
|
|
||||||
: runtime_error(what)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
enum class trace_level : int
|
|
||||||
{
|
|
||||||
none = 0,
|
|
||||||
messages = 1,
|
|
||||||
events = 2,
|
|
||||||
state_changes = 4,
|
|
||||||
errors = 8,
|
|
||||||
info = 16,
|
|
||||||
all = messages | events | state_changes | errors | info
|
|
||||||
};
|
|
||||||
|
|
||||||
inline trace_level operator|(trace_level lhs, trace_level rhs) noexcept
|
|
||||||
{
|
|
||||||
return static_cast<trace_level>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline trace_level operator&(trace_level lhs, trace_level rhs) noexcept
|
|
||||||
{
|
|
||||||
return static_cast<trace_level>(static_cast<int>(lhs) & static_cast<int>(rhs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
enum class transfer_format
|
|
||||||
{
|
|
||||||
text,
|
|
||||||
binary
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
enum class transport_type
|
|
||||||
{
|
|
||||||
long_polling,
|
|
||||||
websockets
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class web_exception : public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
web_exception(const std::string &what, unsigned short status_code)
|
|
||||||
: runtime_error(what), m_status_code(status_code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
unsigned short status_code() const noexcept
|
|
||||||
{
|
|
||||||
return m_status_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned short m_status_code;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "transfer_format.h"
|
|
||||||
|
|
||||||
namespace signalr
|
|
||||||
{
|
|
||||||
class websocket_client
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~websocket_client() {};
|
|
||||||
|
|
||||||
virtual void start(std::string url, transfer_format format, std::function<void(std::exception_ptr)> callback) = 0;
|
|
||||||
|
|
||||||
virtual void stop(std::function<void(std::exception_ptr)> callback) = 0;
|
|
||||||
|
|
||||||
virtual void send(std::string payload, std::function<void(std::exception_ptr)> callback) = 0;
|
|
||||||
|
|
||||||
virtual void receive(std::function<void(std::string, std::exception_ptr)> callback) = 0;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 2013
|
|
||||||
VisualStudioVersion = 16.0.0.0
|
|
||||||
MinimumVisualStudioVersion = 16.0.0.0
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PersistentConnectionSample", "samples\PersistentConnectionSample\PersistentConnectionSample.vcxproj", "{BD075706-11E9-403B-A2E3-A5E1397E53EF}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HubConnectionSample", "samples\HubConnectionSample\HubConnectionSample.vcxproj", "{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignalRServer", "samples\SignalRServer\SignalRServer.csproj", "{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{4AA7C02A-A2E9-4E22-A026-B43D623C272F}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
.nuget\NuGet.Config = .nuget\NuGet.Config
|
|
||||||
.nuget\NuGet.exe = .nuget\NuGet.exe
|
|
||||||
.nuget\NuGet.targets = .nuget\NuGet.targets
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
|
||||||
Debug|Win32 = Debug|Win32
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
Release|Mixed Platforms = Release|Mixed Platforms
|
|
||||||
Release|Win32 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Mixed Platforms.Build.0 = Release|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.Build.0 = Debug|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.ActiveCfg = Debug|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.Build.0 = Debug|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.ActiveCfg = Release|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.Build.0 = Release|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.ActiveCfg = Release|Win32
|
|
||||||
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
|
||||||
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Win32.ActiveCfg = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include "hub_connection.h"
|
|
||||||
#include "log_writer.h"
|
|
||||||
#include <future>
|
|
||||||
|
|
||||||
class logger : public signalr::log_writer
|
|
||||||
{
|
|
||||||
// Inherited via log_writer
|
|
||||||
virtual void __cdecl write(const std::string & entry) override
|
|
||||||
{
|
|
||||||
//std::cout << utility::conversions::to_utf8string(entry) << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void send_message(signalr::hub_connection& connection, const std::string& message)
|
|
||||||
{
|
|
||||||
web::json::value args{};
|
|
||||||
args[0] = web::json::value(utility::conversions::to_string_t(message));
|
|
||||||
|
|
||||||
// if you get an internal compiler error uncomment the lambda below or install VS Update 4
|
|
||||||
connection.invoke("Send", args, [](const web::json::value& value, std::exception_ptr exception)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (exception)
|
|
||||||
{
|
|
||||||
std::rethrow_exception(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
ucout << U("Received: ") << value.serialize() << std::endl;
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
ucout << U("Error while sending data: ") << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void chat()
|
|
||||||
{
|
|
||||||
signalr::hub_connection connection("http://localhost:5000/default", signalr::trace_level::all, std::make_shared<logger>());
|
|
||||||
connection.on("Send", [](const web::json::value & m)
|
|
||||||
{
|
|
||||||
ucout << std::endl << m.at(0).as_string() << /*U(" wrote:") << m.at(1).as_string() <<*/ std::endl << U("Enter your message: ");
|
|
||||||
});
|
|
||||||
|
|
||||||
std::promise<void> task;
|
|
||||||
connection.start([&connection, &task](std::exception_ptr exception)
|
|
||||||
{
|
|
||||||
if (exception)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::rethrow_exception(exception);
|
|
||||||
}
|
|
||||||
catch (const std::exception & ex)
|
|
||||||
{
|
|
||||||
ucout << U("exception when starting connection: ") << ex.what() << std::endl;
|
|
||||||
}
|
|
||||||
task.set_value();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ucout << U("Enter your message:");
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
std::string message;
|
|
||||||
std::getline(std::cin, message);
|
|
||||||
|
|
||||||
if (message == ":q")
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_message(connection, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
connection.stop([&task](std::exception_ptr exception)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (exception)
|
|
||||||
{
|
|
||||||
std::rethrow_exception(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
ucout << U("connection stopped successfully") << std::endl;
|
|
||||||
}
|
|
||||||
catch (const std::exception & e)
|
|
||||||
{
|
|
||||||
ucout << U("exception when stopping connection: ") << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
task.set_value();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
task.get_future().get();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
chat();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="..\..\Build\SignalRClient.Build.Settings" />
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>HubConnectionSample</RootNamespace>
|
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
|
||||||
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
|
|
||||||
<RestorePackages>true</RestorePackages>
|
|
||||||
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
<Import Project="..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<AdditionalIncludeDirectories>..\..\include\signalrclient;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<AdditionalLibraryDirectories>
|
|
||||||
</AdditionalLibraryDirectories>
|
|
||||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\lib\native\v140\windesktop\msvcstl\dyn\rt-dyn\x86\Debug\cpprest140d_2_9.lib;$(MSBuildThisFileDirectory)..\..\bin\Desktop\Win32\Debug\dll\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
<AdditionalIncludeDirectories>..\..\include\signalrclient;$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="stdafx.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="HubConnectionSample.cpp" />
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\signalrclient\Build\VS\signalrclient.vcxproj">
|
|
||||||
<Project>{87ed3ad4-d820-48cd-8382-a12564213a12}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
<Exec Command="copy /y "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).dll" "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).dll"" />
|
|
||||||
<Exec Command="copy /y "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).pdb" "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).pdb"" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="stdafx.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="HubConnectionSample.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.9.1" targetFramework="native" />
|
|
||||||
</packages>
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "signalrclient\connection.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void send_message(signalr::connection &connection, const utility::string_t& message)
|
|
||||||
{
|
|
||||||
connection.send(message)
|
|
||||||
.then([](pplx::task<void> send_task) // fire and forget but we need to observe exceptions
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
send_task.get();
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
ucout << U("Error while sending data: ") << e.what();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
signalr::connection connection{ U("http://localhost:34281/echo") };
|
|
||||||
connection.set_message_received([](const utility::string_t& m)
|
|
||||||
{
|
|
||||||
ucout << U("Message received:") << m << std::endl << U("Enter message: ");
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.start()
|
|
||||||
.then([&connection]() // fine to capture by reference - we are blocking so it is guaranteed to be valid
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
utility::string_t message;
|
|
||||||
std::getline(ucin, message);
|
|
||||||
|
|
||||||
if (message == U(":q"))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_message(connection, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return connection.stop();
|
|
||||||
})
|
|
||||||
.then([](pplx::task<void> stop_task)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
stop_task.get();
|
|
||||||
ucout << U("connection stopped successfully") << std::endl;
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
ucout << U("exception when starting or closing connection: ") << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
}).get();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{BD075706-11E9-403B-A2E3-A5E1397E53EF}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>PersistentConnectionSample</RootNamespace>
|
|
||||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
|
||||||
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
|
|
||||||
<RestorePackages>true</RestorePackages>
|
|
||||||
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="stdafx.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="PersistentConnectionSample.cpp" />
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
|
||||||
<Import Project="..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
|
|
||||||
<Import Project="..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets" Condition="Exists('..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets')" />
|
|
||||||
</ImportGroup>
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
|
||||||
<Error Condition="!Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
|
|
||||||
<Error Condition="!Exists('..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets'))" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="stdafx.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="stdafx.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="PersistentConnectionSample.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.7.0" targetFramework="native" />
|
|
||||||
<package id="Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop" version="1.0.0-beta1" targetFramework="native" />
|
|
||||||
</packages>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue